Hallo Leute,
habe folgendes Problem, will mein Display EA DOGM and die USART0 in SPI
Mode anschließen. Ich verwende einen ATmega 1280 TQFP100
Das Display war bisher direkt an der SPI Schnittstelle dran, da ich aber
diese nun für eine SDCard Ansteuerung brauche, muss ich nun die USART0
in SPI Mode verwenden.
Wie gesagt das Display funktionierte bisher tatellos an SPI, das einzige
was nun geändert wurde, ist MOSI und SCK vom Display an USART
angeschlossen
die restlichen PINs blieben unberührt.
DISPLAY MOSI -> TXD
DISPLAY SCK -> XCK0
Init Funktion
Aber mit diesen Änderungen Funktioniert mein Display nicht mehr!
Display funktioniert noch, habe noch eine zwei Platine mit der SPI
Ansteuerung!
Habe ich irgendetwas übersehen? Es muss an der Initialisierung oder am
Senden liegen!!
Danke für eure Hilfe
Gruß
Jochen
Hi
>while (!(UCSR0A & (1 << UDRE0))); //USART in SPIMODE
Im Gegensatz zum SPI ist das Datenregister der UART gepuffert. UDRE gibt
nur an, das ein Byte an UDR übergeben werden kann, nicht , das das
Byte fertig gesendet wurde. Bevor du den Status der Steuerleitungen
(CS,A0..) änderst, must du mit TXC prüfen, ob das letzte Byte komplett
gesendet wurde.
MfG Spess
Salut ...
ich benutze den USART0 auf einen Atmega2561, ich denke mal von den
Register sollte das das selbe sein in etwa. Hier mein Code zum Init und
senden/empfangen.
1
voidSPI_init(void)
2
{
3
UBRR0=0;
4
/* Setting the XCKn port pin as output, enables master mode. */
5
SPI_DDR|=(1<<XCK1);
6
/* Set MSPI mode of operation and SPI data mode 0. */
7
UCSR0C=(1<<UMSEL01)|(1<<UMSEL00);
8
/* Enable receiver and transmitter. */
9
UCSR0B=(1<<RXEN0)|(1<<TXEN0);
10
/* Set baud rate. */
11
/* IMPORTANT: The Baud Rate must be set after the transmitter is enabled */
12
UBRR0=0;
13
}
14
15
charSPI_ReadWrite(charData)
16
{
17
/* Wait for empty transmit buffer */
18
while(!(UCSR0A&(1<<UDRE0)));
19
/* Put data into buffer, sends the data */
20
UDR0=Data;
21
/* Wait for data to be received */
22
while(!(UCSR0A&(1<<RXC0)));
23
/* Get and return received data from buffer */
24
returnUDR0;
25
}
Bei tut dieser Code mit einem ENC28j60. Evtl. musst du noch den Mode und
Speed ändern auf deine Bedürfnisse.
CA Dirk
Hallo Dirk,
SPI_DDR ist DDRE???
und
XCK1 ist PE2???
Sonst habe ich alles identisch, nur SPIMODE 3 das ich mit
(1 << UCSZ00)| (0 << UCSZ01) | (1 << UCPOL0)
eingestellt habe.
Ich denke die Speed, bzw Baudrate dürfte keine Rolle spielen!
Oder doch?
Gruß
Jochen
Salut ...
so weit ich das noch in Erinnerung habe war die Baudrate bei den
Displays nicht so dolle.
SPI_DDR = DDRE
und XCK0 liegt auf PE2, da ist ein kleiner Fehler in meinem Listing,
dort steht XCK1 :-). Aber interessant dürfte für dich eigentlich nur das
abholen der Daten sein.
N8 Dirk
Hallo,
versuche mal ein NOP oder ein kleine Pause nach dem Senden, also
1
voidsend_byte(uint8_tdata)
2
{
3
clr_cs();
4
5
//SPI SENDBYTE
6
//SPDR = data;
7
//while (!(SPSR & (1<<SPIF)));
8
9
while(!(UCSR0A&(1<<UDRE0)));
10
UDR0=data;
11
12
_delay_ms(0.001);// ODER NOP;
13
14
while(!(UCSR0A&(1<<TXC0)));
15
set_cs();
16
}
Die Displays brauchen eine kurze Pause bis Sie wieder den nächsten
Befehl annehmen können. Wenn es zu schnell geht, dann reagiert das
Display nicht mehr.
Gruß
Marcus Parentis
Hallo,
wo ist der /CS des SPI-Displays angeschlossen? Er sollte einen eigenen
Pin bekommen; der /SS von der SPI-Schnittstelle wird ja wohl für die
SDCard verwendet ...
> Ich denke die Speed, bzw Baudrate dürfte keine Rolle spielen! Oder doch?
Darüber sollte das Datenblatt des Displays Auskunft geben (max. SPI
clock); zu schneller Takt kann Probleme geben.
Da das Display an der (richtigen) SPI-Schnittstelle gelaufen hat, kannst
du diese Takteinstellungen doch für den SPI-USART übernehmen.
Hallo,
also Marcus hatte recht, es lag an den Timings.
Sobald ich eine Pause einbaue, dann gehts!
Danke für Eure Hilfe und ein schönes Wochenende..
Gruß
Jochen
Hallo Jochen,
im Datenblatt vom ATmega128x/644x/256x steht, nur die mega
1281/6441/2561
haben den UART0 di/do Modus. Bei den anderen gehen die PINs nach
MISO/MOSI
• PDO/TXD0 – Port E, Bit 1
PDO, SPI Serial Programming Data Output. During Serial Program
Downloading, this pin is
used as data output line for the ATmega1281/2561. For
ATmega640/1280/2560 this function is
placed on MISO.
TXD0, USART0 Transmit pin.
• PDI/RXD0/PCINT8 – Port E, Bit 0
PDI, SPI Serial Programming Data Input. During Serial Program
Downloading, this pin is used
as data input line for the ATmega1281/2561. For ATmega640/1280/2560 this
function is placed
on MOSI.
RXD0, USART0 Receive Pin. Receive Data (Data input pin for the USART0).
When the
USART0 receiver is enabled this pin is configured as an input regardless
of the value of DDRE0.
When the USART0 forces this pin to be an input, a logical one in PORTE0
will turn on the internal
pull-up
Gruß Karl-Heinz
Danke für die Info,
Ich baue mir gerade ein Bord mit 2560 , externes Ram, Ethernet
Controller, usart to usb chip, serial eeprom ,Micro-SD, jtag , ISP . Die
freien Ports werde ich auf Wannenstecker ausführen. Für den Ethernet
Chip werde ich exklusive ein SPI port z.b. PortE verwenden.
Der TCP/IP Stack wird eine Mischung von U.Radig Stack und dem openMPC
Stack.
Beide Stacks laufen auf meine Demo Boards mega644p und mega2560.
Mal sehen wie weit ich mit meinem Projekt komme.
Im Endausbau werde ich auch einen Ethernet Bootloader dazu packen.
Gruß KH
Was mir noch aufgefallen ist, im AVR-Studio Simulator kann man den
USART0 welcher auf PORTE zeigt , nur auf USART synchron stellen und
nicht wie bei allen anderen auf SPI Master ?
Gruß KH
ich habe mein Problem gelöst, im Datenblatt steht man muss nach dem
Senden das UDRx lesen. deshalb sieht man bei vielen Implementierungen
SPI_ReadWrite an einem Stück.
Wenn man mit SPI_Put oder SPI_Get arbeitet, muss im SPI_Put ein warten
und lesen vom UDRx erfolgen. Diese Daten gebe ich mit einem Flag und
einer Variable an die SPI_Get Prozedur weiter.
mit dieser kleinen Änderung läuft der Stack von U.Radig auch auf USART
im SPI Mode, könnte für manche Leute hilfreich sein.
Gilt für USART0:
static inline void spi_put( unsigned char value )
{
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) );
/* Put data into buffer, sends the data */
UDR0 = value;
while ( !(UCSR0A & (1<<RXC0)) );
SendReceive=UDR0; //read data and flag read done to
spi_get
SendReceiveFlag=true;
}
static inline unsigned char spi_get(void)
{
if (SendReceiveFlag==true)
{
SendReceiveFlag=false;
return SendReceive;
}
while ( !(UCSR0A & (1<<RXC0)) );
return UDR0;
}
ich habe mein Problem gelöst, im Datenblatt steht man muss nach dem
Senden das UDRx lesen. deshalb sieht man bei vielen Implementierungen
SPI_ReadWrite an einem Stück.
Wenn man mit SPI_Put oder SPI_Get arbeitet, muss im SPI_Put ein warten
und lesen vom UDRx erfolgen. Diese Daten gebe ich mit einem Flag und
einer Variable an die SPI_Get Prozedur weiter.
mit dieser kleinen Änderung läuft der Stack von U.Radig auch auf USART
SPI Mode, könnte für manche Leute hilfreich sein.
static inline void spi_put( unsigned char value )
{
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) );
/* Put data into buffer, sends the data */
UDR0 = value;
while ( !(UCSR0A & (1<<RXC0)) );
SendReceive=UDR0; //read data and flag read done to
spi_get
SendReceiveFlag=true;
}
static inline unsigned char spi_get(void)
{
if (SendReceiveFlag==true)
{
SendReceiveFlag=false;
return SendReceive;
}
while ( !(UCSR0A & (1<<RXC0)) );
return UDR0;
}
Hallo Leute,
ich möchte eine atmega1281 durch USART1 als SPI_Master verwenden. Das
ist die C Code aus Datasheet:
// Initialisierung SPI_Master (ATMEGA1281)
void USART_Init( unsigned int baud )
{
UBRR1L = 0;
/* Setting the XCKn port pin as output, enables master mode. */
XCK1_DDR |= (1<<XCK1);
/* Set MSPI mode of operation and SPI data mode 0. */
UCSR1C = (1<<UMSEL11)|(1<<UMSEL10)|(0<<UCPHA1)|(0<<UCPOL1);
/* Enable receiver and transmitter. */
UCSR1B = (1<<RXEN1)|(1<<TXEN1);
/* Set baud rate. */
/* IMPORTANT: The Baud Rate must be set after the transmitter is
enabled*/
UBRR1L = baud;
}
// Senden der Daten von Master
unsigned char USART_Receive(void)
{
unsigned char data;
/* Wait for empty transmit buffer */
while ( !( UCSR1A & (1<<UDRE1)) );
/* Put data into buffer, sends the data */
UDR1 = data;
/* Wait for data to be received */
while ( !(UCSR1A & (1<<RXC1)) );
/* Get and return received data from buffer */
return UDR1;
}
aber bei der Übersetzung meldet die folgenden Bits als undeclared:
UBRR1L
XCK1_DDR
XCK1
UCSR1C
UMSEL11
UMSEL10
UCPHA1
UCPOL1
UCSR1B
RXEN1
TXEN1
UCSR1A
UDRE1
UDR1
RXC1
Habt ihr sie extra definiert oder gibt eine Header(Include) File, welche
diese Bits erkennen kann?
Grüße
David