Forum: Mikrocontroller und Digitale Elektronik XMega USART in SPI-Mode, CS-Problem


von Christoph K. (easyrider)


Angehängte Dateien:

Lesenswert?

Moin,

Hab hier nen ziemliches Problem mit nem XMega.
Ich will den USARTC1 in SPI-Mode betreiben. Dabei möchte ich 32 bits 
übertragen.

Mein Ansatz: USARTC1 initialisieren, CS -> low, 4x das Datenregister 
beschreiben (vorm schreiben Prüfen ob frei) und danach wieder CS -> 
High.

Mein Problem: siehe Foto.
oben dargestellt die SCK-Leitung, unten die CS-Leitung. Irgendwie wird 
die zu früh wieder H gesetzt, hab aber keine Peilung woher das kommt.

Hier der Code:
1
void UART_5004_write(const uint8_t adr, const uint32_t data){
2
  PORTC.OUTCLR = (1<<CS_5004_PIN);
3
  while (!(USARTC1.STATUS & USART_DREIF_bm));
4
  USARTC1.DATA  = adr;
5
  while(!(USARTC1.STATUS & USART_TXCIF_bm));
6
7
  USARTC1.DATA = (data>>16);
8
  /while(!(USARTC1.STATUS & USART_TXCIF_bm));
9
10
  USARTC1.DATA = (data>>8);
11
  while(!(USARTC1.STATUS & USART_TXCIF_bm));
12
13
  USARTC1.DATA = (data);
14
  while(!(USARTC1.STATUS & USART_TXCIF_bm));
15
16
  PORTC.OUTSET = (1<<CS_5004_PIN);
17
  _delay_us(10);
18
} 
19
20
void PE5004_init_UART(void){
21
  PORTC.DIRSET = (1<<SCK_5004_PIN)|(1<<MOSI_5004_PIN)|(1<<CS_5004_PIN);
22
  PORTC.OUTSET = (1<<CS_5004_PIN);
23
  PORTC.DIRCLR = (1<<MISO_5004_PIN);
24
  PORTD.DIRCLR = (1<<INT_5004_PIN);
25
  USARTC1.CTRLA = 0;
26
  USARTC1.CTRLB = 0x1C;  // TX Enabled, Rx enabled, Double speed
27
  USARTC1.CTRLC = 0xC0;  // UART in SPI-Mode, MSB First, 
28
  USARTC1.BAUDCTRLA = 0x05;  // 32 MHz/(2*(5+1)) = 32 MHz / 12 = 2,666 MHz // Evtl auch 0x04 möglich -> 3,2 MHz  
29
  
30
  UART_5004_write(0x05, 0x02);    // Select SPI
31
  UART_5004_write(0x02, (WAITCOL<<12)|WAITROW);
32
  UART_5004_write(0x03, (SinePush<<23)|(SINF<<18)|(SINA<<12)|(PWRI<<11)|(GCO<<4)|DACREF);
33
  UART_5004_write(0x04, PCO);
34
}

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

das TXCIF-Flag wird ohne aktivierten TXC-Interrupt nicht automatisch 
gelöscht! Du musst es voher mit einer 1 beschreiben um es 
zurückzusetzen. Die Ausgabe kannst du besser mit dem UDRE-Flag steuern, 
denn so kannst du den Puffer des UART ordentlich verwenden - allerdings 
macht das die Auswertung wann die Bytes versendet sind nicht einfacher. 
Mann könnte aber z.B. über die RX-ISR die Anzahl der empfangenen Bytes 
zählen, und wenn 4 Byte empfangen sind, wurden auch 4 Byte gesendet.

Sascha

von Christoph K. (easyrider)


Lesenswert?

Danke für den Tip!

setze jetzt hinter jeder while-schleife das flag mit
1
USARTC1.STATUS |= USART_TXCIF_bm
zurück, damit funktionierts!

Das UDRE-Flag habe ich bewusst nicht verwendet, denn das zeigt ja nur an 
wann ich das datenregister verwenden kann (eben wenns leer ist). Das 
TXIC Flag hingen wird erst gesetzt wenn das ganze byte durch das 
register durchgeschoben wurde.

Auf Interrupts wollte ich an der stelle noch verzichten, ich bin an 
dieser stelle erst noch in der initialisierungsphase, da muss ich 
lediglich die 4x32 bits durchschieben. Da kann ich auch mal warten. 
Später zum auslesen muss ich dann aber eventgesteurt den DMA Controller 
verwenden.

Nochmals Danke!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.