Hallo zusammen,
ich versuche derzeit einen ATmega8 mit einen ATtiny85 über SPI zu
verbinden (später soll der ATtiny85 die Werte an seinem ADC an den
ATmega8 weitergeben).
Hierzu läuft auf dem ATmega8 ein SPI Master. Gesteuert wird der ATmega8
über UART mit dem Computer. Wenn vom Computer aus das Signal 'send\n'
geschickt wird dann übertragt der ATmega8 ein Byte (hier 97 == 'a') über
den SPI Bus. Anschließend soll der ATtiny85 das gesendete Byte um 1
erhöhen und zurück an den ATmega8 übertragen. Leider scheint mir der
ATtiny immer nur 255 zurück zusenden anstatt 98 == 'b'.
Die beiden Controller sind wie folgt miteinander verbunden:
ATmega8 -- ATtiny85
GND -- GND
PB2 (SS) -- PB4 (soll später als Slave Select verwendet werden)
PB3 (MOSI) -- PB1 (MISO)
PB4 (MISO) -- PB0 (MOSI)
PB5 (SCK) -- PB2 (SCK)
Hier ist der Code für den ATmega8 (Master)
(In uart.h befindet sich der Code für die Kommunikation mit dem
Computer)
1 | #define F_CPU 8000000UL
|
2 |
|
3 | #include <avr/io.h>
|
4 | #include <avr/interrupt.h>
|
5 | #include <avr/wdt.h>
|
6 | #include <util/delay.h>
|
7 | #include <stdlib.h>
|
8 |
|
9 | #include "uart.h"
|
10 |
|
11 | uint8_t spi_tranceiver (uint8_t data);
|
12 |
|
13 | void process_command(uint8_t * command) {
|
14 |
|
15 | uint8_t success = 0;
|
16 |
|
17 |
|
18 | if(strcmp(command, "send") == 0) {
|
19 | uint8_t send_byte = 97;
|
20 |
|
21 |
|
22 | int i;
|
23 |
|
24 | uart_puts("send: ",6);
|
25 |
|
26 | for(i = 7; i >= 0; i--) {
|
27 | if((send_byte & (1 << i)) == (1 << i)) {
|
28 | uart_putc('1');
|
29 | } else {
|
30 | uart_putc('0');
|
31 | }
|
32 | }
|
33 |
|
34 | uart_putc('\n');
|
35 | uart_putc('\r');
|
36 |
|
37 |
|
38 | uint8_t received_byte = spi_tranceiver(send_byte);
|
39 |
|
40 | uart_puts("recv: ",6);
|
41 |
|
42 | for(i = 7; i >= 0; i--) {
|
43 | if((received_byte & (1 << i)) == (1 << i)) {
|
44 | uart_putc('1');
|
45 | } else {
|
46 | uart_putc('0');
|
47 | }
|
48 | }
|
49 |
|
50 | uart_putc('\n');
|
51 | uart_putc('\r');
|
52 | }
|
53 |
|
54 | if(success == 1) {
|
55 | uart_puts("ack\n",4);
|
56 | }
|
57 | }
|
58 |
|
59 | void spi_init_master (void) {
|
60 | DDRB = (1<<5)|(1<<3); //Set MOSI, SCK as Output
|
61 | SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); //Enable SPI, Set as Master
|
62 | //Prescaler: Fosc/16, Enable Interrupts
|
63 | }
|
64 |
|
65 | //Function to send and receive data
|
66 | uint8_t spi_tranceiver (uint8_t data) {
|
67 | SPDR = data; //Load data into the buffer
|
68 | while(!(SPSR & (1<<SPIF) )); //Wait until transmission complete
|
69 | return(SPDR); //Return received data
|
70 | }
|
71 |
|
72 | uint8_t main (void) {
|
73 |
|
74 | // enable interrupts
|
75 | sei();
|
76 |
|
77 | // enable uart
|
78 | uart_init();
|
79 | spi_init_master();
|
80 |
|
81 | sei();
|
82 |
|
83 | // send ready
|
84 | uart_puts("ready\n\r", 7);
|
85 |
|
86 | uint8_t * command;
|
87 | uint8_t command_in_queue;
|
88 |
|
89 | while(1) {
|
90 | command_in_queue = command_queue_pop(&command);
|
91 |
|
92 | if(command_in_queue == 0) {
|
93 | process_command(command);
|
94 | free(command);
|
95 | }
|
96 | }
|
97 |
|
98 | return 0;
|
99 | }
|
Auf dem ATtiny85 läuft der folgende Code
1 | #define F_CPU 8000000UL
|
2 |
|
3 | #include <avr/io.h>
|
4 |
|
5 |
|
6 | // Set USI to slave mode - do this at startup
|
7 | void spi_init_slave() {
|
8 | USICR = (1<<USIWM0)|(1<<USICS1);
|
9 | }
|
10 |
|
11 | // Receive a byte from the master
|
12 | uint8_t spi_tranceiver() {
|
13 |
|
14 | // Clear counter overflow flag
|
15 | USISR = (1<<USIOIF);
|
16 |
|
17 | // Wait for complete byte to arrive
|
18 | while ((USISR & (1<<USIOIF))==0) {}
|
19 |
|
20 | // Return received byte
|
21 | uint8_t byte = USIDR;
|
22 | USIDR = byte+1;
|
23 | }
|
24 |
|
25 |
|
26 | uint8_t main(void) {
|
27 |
|
28 | spi_init_slave();
|
29 |
|
30 | while(1) {
|
31 | spi_tranceiver();
|
32 | }
|
33 |
|
34 | return 0;
|
35 |
|
36 | }
|
Im angehängten Bild ist die Kommunikation zwischen dem Computer und dem
ATmega8 aufgezeichnet. Hier Protokolliert der ATmega8 die SPI
Kommunikation mit dem ATtiny85. Könnt ihr mir einen Tipp geben?
Vielen Dank und viele Grüße
Konze