Ich habe das letztes mal vor 2-3 Jahre, SPI mit fertige Arduino
Libraries programmiert.
Heute habe ich mit ATMEGA328p als Master und X25020P(EEPROM) als Slave
konfiguriert. Ich würde sagen 'auf gut Deutsch'- das ist das billigste
von billigste SPI Programm. :)
Also, das Ziel war ein Byte (0x01) schreiben auf Adresse 0x20 und die
geschriebene Byte wieder lesen. Wenn lesen erfolgreich war, leuchtet ein
LED.
Ich wusste was wo angeschlossen werden muss, also nicht zu viel HW
Aufwand.
Datenblatt von x25020p chip:
http://pdf.datasheetcatalog.com/datasheet_pdf/xicor/X25020P_to_X25020SI-2,7.pdf
C code:
1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 | #include <avr/interrupt.h>
|
4 | #include <string.h>
|
5 |
|
6 |
|
7 |
|
8 | void spi_master_init()
|
9 | {
|
10 | DDRB = ( (1<<PB2) | (1<<PB3) | (1<<PB5) ); // /SS as output, MOSI and SCK as output
|
11 | SPCR = ( (1<<SPE) | (1<<SPR1) | (1<<MSTR)); //SPI Enable, fosc/64, Master mode
|
12 | }
|
13 |
|
14 |
|
15 | void spi_slave_init()
|
16 | {
|
17 | DDRB = 0<<PB4; //MOSI as input
|
18 | SPCR = 1<<SPE ;
|
19 | }
|
20 |
|
21 |
|
22 | void SPI_Tx(char data)
|
23 | {
|
24 | SPDR=data;
|
25 | while( !(SPSR & (1<<SPIF)) ); //wait until SPIF flag is set, to indicate transmission is complete
|
26 | }
|
27 |
|
28 | char SPI_Rx()
|
29 | {
|
30 | char Rx_char;
|
31 | SPI_Tx(0);
|
32 | while( !(SPSR & (1<<SPIF)) );
|
33 | Rx_char= SPDR;
|
34 |
|
35 | return Rx_char;
|
36 | }
|
37 |
|
38 | void write_to_slave()
|
39 | {
|
40 | PORTB|=1<<PB2; //take /CS on slave LOW
|
41 | SPI_Tx(0x06); //WREN write enable command
|
42 | PORTB&=~(1<<PB2); //take /CS on slave HIGH
|
43 |
|
44 | PORTB|=1<<PB2; //take /CS on slave LOW
|
45 | SPI_Tx(0x02); //WRITE instruction
|
46 | SPI_Tx(0x20); //Address to write data to
|
47 | SPI_Tx(0x01); //Data to be written
|
48 | PORTB&=~(1<<PB2); //take /CS on slave HIGH
|
49 | }
|
50 |
|
51 | char read_from_slave()
|
52 | {
|
53 | char recvd_char;
|
54 | PORTB|=1<<PB2; //take /CS on slave LOW
|
55 | SPI_Tx(0x03); //READ instruction
|
56 | SPI_Tx(0x20); //Address to be read from
|
57 |
|
58 | recvd_char = SPI_Rx();
|
59 | return recvd_char;
|
60 | }
|
61 |
|
62 | int main (void)
|
63 | {
|
64 | DDRC=0xff; //PORTC as output
|
65 |
|
66 |
|
67 | char recvdchar=0;
|
68 |
|
69 | spi_master_init();
|
70 | spi_slave_init();
|
71 |
|
72 | write_to_slave();
|
73 |
|
74 | recvdchar=read_from_slave();
|
75 |
|
76 | if(recvdchar==0x01)
|
77 | PORTC=1<<PC0;
|
78 |
|
79 |
|
80 |
|
81 |
|
82 | }
|
Das Problem ist nun, LED leuchtet nicht wie erwartet. Was habe ich
falsch gemacht!?