Moin, ich stehe vor folgendem Problem. Ich habe mir 2 ATMega88 auf eine Lochrasterplatine gesetzt und möchte das diese per SPI untereinander kommunizieren und mir dann ein Messergebnis über die serielle Schnittstelle vom Master ausgeben. Konkret geht es darum die interne Temperaturmessung etwas genauer zu betrachten. Momentan habe ich beide Controller über einen MAX232 mit 2 Schnittstellen verbunden. Dies soll aber momentan nur zum testen der SPI Schnittstelle dienen. Problem ist aber das die Zeichen die ich mit dem Master sende nicht korrekt übertragen werden. Ab und dann kommt nach 5-6 Versuchen mal etwas korrektes an. Beide Prozessoren laufen mit internen RC Oszilator. Quelltext Master:
1 | #include <stdint.h> |
2 | #include <stdlib.h> |
3 | #include <avr/io.h> |
4 | #include <avr/interrupt.h> |
5 | #include "adhandle.h" |
6 | |
7 | #ifndef F_CPU
|
8 | #define F_CPU 1000000UL
|
9 | #endif
|
10 | #include <util/delay.h> |
11 | #define sendByte(ch) (UDR0=ch)
|
12 | #define getByte() (UDR0)
|
13 | |
14 | #define DDR_SPI DDRB
|
15 | #define DD_MOSI DDB3
|
16 | #define DD_SCK DDB5
|
17 | #define DD_SS DDB2
|
18 | #define SS PB2
|
19 | |
20 | char getTemp = 0x00; |
21 | int16_t temperature; |
22 | uint16_t adTemp; |
23 | uint8_t i; |
24 | char ReceivedByte; |
25 | char sendZero = 0x00; |
26 | |
27 | ISR(USART_RX_vect){ |
28 | if(getByte() == 0x54) |
29 | getTemp = 0x01; |
30 | else{ |
31 | sendZero = 0x01; |
32 | ReceivedByte = getByte(); |
33 | }
|
34 | }
|
35 | void initUART( void ){ |
36 | UCSR0B |= ( 1<<RXEN0 ) | ( 1<<TXEN0 ); |
37 | UCSR0B |= ( 1<<RXCIE0 ); |
38 | UCSR0C |= ( 1<<UCSZ00 ) | ( 1<<UCSZ01 ); |
39 | UCSR0A |= ( 1<<U2X0 ); |
40 | UBRR0 = 12; |
41 | |
42 | }
|
43 | |
44 | void UART_putc(unsigned char c){ |
45 | while((UCSR0A & (1 << UDRE0)) == 0){}; |
46 | sendByte(c); |
47 | }
|
48 | |
49 | |
50 | void init_spiMaster( void ){ |
51 | /* Set MOSI and SCK output, all others input */
|
52 | DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS); |
53 | /* Enable SPI, Master, set clock rate fck/16 */
|
54 | SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); |
55 | }
|
56 | |
57 | void spiMasterTransmit(char cData) |
58 | {
|
59 | /* Start transmission */
|
60 | SPDR = cData; |
61 | /* Wait for transmission complete */
|
62 | while(!(SPSR & (1<<SPIF))) |
63 | ;
|
64 | }
|
65 | int main( void ){ |
66 | |
67 | //
|
68 | // Initialisierung des A/D-Wandlers
|
69 | //
|
70 | // ADC aktivieren und Prescaler auf 8 setzen
|
71 | ADCSRA |= ( 1<<ADEN ) | ( 1<<ADPS1 ) | ( 1<<ADPS0 ); |
72 | // Free Running Mode aktivieren, Reservierte Bits mit 0 beschreiben
|
73 | ADCSRB = 0x00; |
74 | initUART(); |
75 | init_spiMaster(); |
76 | sei(); |
77 | |
78 | for(;;){ |
79 | if( getTemp == 0x01){ |
80 | adTemp = readADC(0xC8); |
81 | _delay_ms(20); |
82 | adTemp = readADC(0xC8); |
83 | temperature = ((adTemp-335)*88)/100; |
84 | getTemp = 0x00; |
85 | char one = (adTemp & 0xFF00) >> 8; |
86 | char two = (adTemp & 0x00FF); |
87 | char three = (temperature & 0xFF00) >> 8; |
88 | char four = (temperature & 0x00FF); |
89 | UART_putc(one); |
90 | UART_putc(two); |
91 | UART_putc(three); |
92 | UART_putc(four); |
93 | PORTB &= ~( 1<<SS); |
94 | _delay_ms(1); |
95 | spiMasterTransmit(0x00); |
96 | _delay_ms(1); |
97 | PORTB |= ( 1<<SS); |
98 | }else if(sendZero == 0x01){ |
99 | UART_putc(ReceivedByte); |
100 | sendZero = 0x00; |
101 | PORTB &= ~( 1<<SS); |
102 | _delay_ms(1); |
103 | spiMasterTransmit(ReceivedByte); |
104 | _delay_ms(1); |
105 | PORTB |= ( 1<<SS); |
106 | }else{ |
107 | i++; |
108 | if ( i >= 200 ) |
109 | i = 0; |
110 | }
|
111 | }
|
112 | }
|
Quelltext Slave:
1 | #include <stdint.h> |
2 | #include <stdlib.h> |
3 | #include <avr/io.h> |
4 | #include <avr/interrupt.h> |
5 | #include "adhandle.h" |
6 | |
7 | |
8 | |
9 | #ifndef F_CPU
|
10 | #define F_CPU 1000000UL
|
11 | #endif
|
12 | #include <util/delay.h> |
13 | #define sendByte(ch) (UDR0=ch)
|
14 | #define getByte() (UDR0)
|
15 | |
16 | #define DDR_SPI DDRB
|
17 | #define DD_MISO DDB4
|
18 | |
19 | |
20 | char getTemp = 0x00; |
21 | int16_t temperature; |
22 | uint16_t adTemp; |
23 | uint8_t i; |
24 | char ReceivedByte; |
25 | char sendZero = 0x00; |
26 | char spiChar; |
27 | |
28 | ISR(USART_RX_vect){ |
29 | char ReceivedByte; |
30 | if(getByte() == 0x54) |
31 | getTemp = 0x01; |
32 | else
|
33 | sendZero = 0x01; |
34 | }
|
35 | ISR(SPI_STC_vect){ |
36 | //PORTC |= (1<<PC0);
|
37 | spiChar = SPDR; |
38 | }
|
39 | |
40 | void initUART( void ){ |
41 | |
42 | UCSR0B |= ( 1<<RXEN0 ) | ( 1<<TXEN0 ); |
43 | UCSR0B |= ( 1<<RXCIE0 ); |
44 | |
45 | UCSR0C |= ( 1<<UCSZ00 ) | ( 1<<UCSZ01 ); |
46 | |
47 | UCSR0A |= ( 1<<U2X0 ); |
48 | |
49 | UBRR0 = 12; |
50 | |
51 | }
|
52 | void SPI_SlaveInit(void) |
53 | {
|
54 | /* Set MISO output, all others input */
|
55 | DDR_SPI = (1<<DD_MISO); |
56 | /* Enable SPI */
|
57 | SPCR = (1<<SPIE)|(1<<SPE); |
58 | }
|
59 | |
60 | |
61 | void UART_putc(unsigned char c){ |
62 | while((UCSR0A & (1 << UDRE0)) == 0){}; |
63 | sendByte(c); |
64 | }
|
65 | |
66 | int main( void ){ |
67 | |
68 | //
|
69 | // Initialisierung des A/D-Wandlers
|
70 | //
|
71 | // ADC aktivieren und Prescaler auf 8 setzen
|
72 | ADCSRA |= ( 1<<ADEN ) | ( 1<<ADPS1 ) | ( 1<<ADPS0 ); |
73 | // Free Running Mode aktivieren, Reservierte Bits mit 0 beschreiben
|
74 | ADCSRB = 0x00; |
75 | initUART(); |
76 | SPI_SlaveInit(); |
77 | sei(); |
78 | |
79 | for(;;){ |
80 | if( getTemp == 0x01){ |
81 | adTemp = readADC(0xC8); |
82 | _delay_ms(20); |
83 | adTemp = readADC(0xC8); |
84 | temperature = ((adTemp-335)*88)/100; |
85 | getTemp = 0x00; |
86 | char one = (adTemp & 0xFF00) >> 8; |
87 | char two = (adTemp & 0x00FF); |
88 | char three = (temperature & 0xFF00) >> 8; |
89 | char four = (temperature & 0x00FF); |
90 | UART_putc(one); |
91 | UART_putc(two); |
92 | UART_putc(three); |
93 | UART_putc(four); |
94 | }else if(sendZero == 0x01){ |
95 | UART_putc(spiChar); |
96 | sendZero = 0x00; |
97 | }else{ |
98 | i++; |
99 | if ( i >= 200 ) |
100 | i = 0; |
101 | }
|
102 | }
|
103 | }
|