Hallo Zusammen,
hoffe mir kann jemand helfen.
Ich habe zwei ATmegas (32 und 128) mittels SPI verbunden. Beide Laufen
mit 16MHz.
Der ATMEGA32 ist als Master konfiguriert und der 128 als Slave.
Ich bin mitlerweile so weit gekommen, dass der Master ein Byte (in
meinem Fall zum Testen ein 'A') sendet und der Slave schaut ob ein 'A'
angekommen ist und dann einfach eine LED schaltet.
Dies Funktioniert soweit ziemlich gut :-)
Nun zu meinem Problem.
Ich würde gerne ein String senden, z.B. "Time\n" und wenn der Slave das
richtige bekommt, dann soll diesr erstmals auch einfach eine LED
einschalten. (Arbeite mich langsam Schritt für Schritt vor)
Quellcode beim Master sieht wie folgt aus :
1 | char spi_send_string(char string[], int cs)
|
2 | {
|
3 | uint8_t length;
|
4 | uint8_t i;
|
5 |
|
6 | length = strlen(string);
|
7 |
|
8 | for(i=0; i < length; i++)
|
9 | {
|
10 | spi_send(string[i], cs);
|
11 | }
|
12 | }
|
13 |
|
14 | char spi_send (unsigned char data, int cs)
|
15 | {
|
16 | PORT_SPI &= ~(1<<cs); // SS am Slave Low --> Beginn der Übertragung
|
17 | SPDR = data; // Daten ins Buffer-Register laden und senden mittels Interrupt
|
18 | _delay_us(10);
|
19 | while (!(SPSR & (1<<SPIF)));
|
20 | //_delay_ms(1);
|
21 | _delay_us(10);
|
22 | PORT_SPI |= (1<<cs); // SS High --> Ende der Übertragung
|
23 | return (SPDR); // Return received data
|
24 | }
|
zum senden benutze ich einfach
1 | spi_send("TIME\n", PIN_SPI_CS3);
|
beim Slave habe ich nun folgendes gemacht. Ich habe im Interrupt
folgenden Quellcode:
1 | volatile unsigned char data;
|
2 | // SPI Transmission/reception complete ISR
|
3 | ISR(SPI_STC_vect)
|
4 | {
|
5 | SWITCH_LED3;
|
6 | data = SPDR;
|
7 | // add to buffer if room
|
8 | if (spi_data_pos < sizeof(spi_data_buf) )
|
9 | {
|
10 | spi_data_buf[spi_data_pos++] = data;
|
11 | if (data == '\n')
|
12 | {
|
13 | spi_data_pos = 0;
|
14 | }
|
15 | }
|
16 | }
|
17 |
|
18 | spi_master_slave.h
|
19 |
|
20 | #ifndef SPI_MASTER_SLAVE_H_
|
21 | #define SPI_MASTER_SLAVE_H_
|
22 |
|
23 | #include <avr/io.h>
|
24 | #include <stdlib.h>
|
25 | #include <util/delay.h>
|
26 | #include <avr/interrupt.h>
|
27 |
|
28 | #include "../global.h"
|
29 | extern volatile char spi_data_buf[50];
|
30 | extern volatile int spi_data_pos;
|
31 |
|
32 | void spi_init_slave (void);
|
33 | void spi_init_master (void);
|
34 | char spi_send (char data, unsigned char cs);
|
35 |
|
36 | #endif /* SPI_MASTER_SLAVE_H_ */
|
global.h
1 | #define F_CPU 16000000UL
|
2 |
|
3 |
|
4 | // SPI DatenVariable
|
5 | volatile char spi_data_buf[50];
|
6 | volatile int spi_data_pos;
|
7 |
|
8 | .....
|
und in der Main eine whileschleife
1 | cli(); // Disable all interrupts
|
2 | initPort(); // Inizalisierung der Ports
|
3 | // spi_init_master(); // SPI Inizalisierung
|
4 | spi_init_slave (); // SPI Inizalisierung als Slave
|
5 | sei(); // enable all interrupts
|
6 | while(1)
|
7 | {
|
8 | SWITCH_LED1;
|
9 | _delay_ms(500);
|
10 | if (spi_data_buf == "TIME\n")
|
11 | SWITCH_LED2;
|
12 | }
|
Kann mir vielleicht jemand verraten warum die Überprufung im
spi_data_buf nicht Funkioniert bzw. nicht das richtige drin steht? Habe
ich da einen Denkfehler in meinem Programm?
Oder etwas mit den Variablen (Buffern für den String) falsch gemacht?
Falls ich zu wenig Informationen gegeben habe einfach bescheid sagen was
fehlt und ich poste es sofort nach!
Dankeschön im Vorfeld für eure Hilfe.