Hallo,
habe eine SPI-Master-Slave Schnittstelle zwischen zwei AVR aufgebaut.
Die Daten für den Master (ATMega8) kommen von der RS232 und sollen an
den Slave (ATMega32) versendet werden. Damit der Master weiß, wann die
Ausführung am Slave abgeschlossen ist und ein datenbyte zurückgelesen
werden kann, habe ich eine zusätzliche /ACK-Leitung eingebaut. Diese ist
für 50us LOW und wechselt dann wieder auf HIGH. Anschließend schreibt
der Master eine 0x00 an den Slave um die Antwortdaten über MISO zu
empfangen.
Nun mein Problem: Der Master erkennt nicht wann er die 8Bit übertragen
hat und nimmt dann zu früh das /SS zurück.
1 | #define F_CPU 16000000L //CPU-Frequenz
|
2 | #define BAUD 9600L //Baudrate
|
3 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) //Runden für Prescaler
|
4 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) //reale Baudrate
|
5 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) //Fehler in Promille
|
6 | //Compilerausgabe bei Fehler
|
7 | #if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
|
8 | #error Systematischer Fehler der Baudrate ist größer 1% und damit zu hoch!
|
9 | #endif
|
10 |
|
11 |
|
12 |
|
13 | #include<avr/io.h>
|
14 | #include<avr/interrupt.h>
|
15 |
|
16 | unsigned char temp=0;
|
17 |
|
18 |
|
19 | int main(void)
|
20 | {PORTB = (1<<PORTB2)|(1<<PORTB0); //PB0,PB2 ist 1
|
21 | DDRB = 0x2C; //SCK,MOSI,/SS = Ausgang
|
22 | //UART Initialisierung
|
23 | UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); //8 Bit + 2 Stoppbit
|
24 | UBRRL = UBRR_VAL; //Baudrate setzen
|
25 | UBRRH = (UBRR_VAL>>8);
|
26 | //SPI-Initialisierung
|
27 | SPSR = (0<<SPI2X);
|
28 | SPCR = (1<<SPE)|(1<<MSTR)|(2<<SPR0); //SPI-Mode 0; 250kHz
|
29 |
|
30 |
|
31 | //Hauptprogramm
|
32 | UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN); //RX-IRQ enable;TX & RX enable
|
33 | sei();
|
34 | while(1);
|
35 | {};
|
36 |
|
37 | };
|
38 |
|
39 |
|
40 | ISR(USART_RXC_vect)
|
41 | {cli();
|
42 | PORTB &= ~(1<<PORTB2); //slave select = low
|
43 | SPDR=UDR; //daten von RS232 an SPI schreiben
|
44 |
|
45 | while(PINB&(1<<PINB0)) //warte auf ACK = low
|
46 | {};
|
47 | while(!(PINB&(1<<PINB0))) //warte auf ACK = high
|
48 | {};
|
49 | SPDR=0x00;
|
50 | while(!(SPSR & (1 << SPIF))); //Warte bis daten gesendet
|
51 |
|
52 | PORTB |=(1<<PORTB2);
|
53 | UDR = SPDR; //daten von SPI an RS232 schreiben
|
54 | while(!(UCSRA&(1<<UDRE))) //TxD complete
|
55 | {};
|
56 | sei();
|
57 | }
|
Anbei noch eine Messung...siehe data2 da sollte /SS noch low sein.