Я новичок в программировании Avr, у меня есть ведомое устройство с 16-битным регистром (микросхема памяти), и я хочу читать и записывать в память через Atmega328 (8-битный регистр), я знаю, что мне нужно отправить 8 на 8 бит, Я уже пытался запрограммировать это, но я не мог читать с моего ведомого устройства с помощью отладчика Atmel Studio, может ли кто-нибудь посоветовать мне, пожалуйста?
Протокол связи с моим чипом - SPI.
Последовательная связь описана в техническом описании микросхемы как:
- ЧИТАТЬ :
Для чтения из чипа необходимо отправить:
0x03 = 0b00000011: 8 bit READ command
0x0000 - 0x07FF = 0bXXXXXAAA AAAAAAAA: 16 bit ADDRESS (5 upper bits don't care)
Тогда я получу:
0x0000 - 0xFFFF = 0bDDDDDDDD DDDDDDDD: 16 bit DATA
- ЗАПИСЫВАТЬ :
Для записи на чип мне нужно отправить:
0x02 = 0b00000010: 8 bit WRITE command
0x0000 - 0x07FF = 0bXXXXXAAA AAAAAAAA: 16 bit ADDRESS (5 upper bits don't care)
0x0000 - 0xFFFF = 0bDDDDDDDD DDDDDDDD: 16 bit DATA
- Схема памяти:
Область пользовательской памяти изменяется от 0x0000 до 0xA6F.
- Используйте регистр информации SPI:
В режиме последовательной связи, если LSI регистрирует ошибку при выполнении команды READ / WRITE, коды ошибок будут сохранены в регистре информации об ошибках SPI.
Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Function 0 0 0 0 0 0 0 0 0 0 0 0 | ERROR* |
* : ERROR
b1000 : Low voltage detection
b0100 : Write NG
b0010 : Read NG
b0001 : NG because RF occurred
b0000 : Finished successfully
Моя инициализация SPI:
void spi_init()
// Initialize pins for spi communication
{
// set MOSI , select chip SS and SCK Output, all others are outputs
DDR_SPI |= ((1<<DD_MOSI)|(1<<DD_SCK) );/*|(1<<DD_SS))*/
// set MISO us input
//Enable SPI, Master, set clock rate
SPCR = (1<<SPE|(1<<MSTR)| (1<<SPR0)| // SPI Enable
(0<<SPIE)| // SPI Interrupt Enable
(0<<DORD)| // Data Order (0:MSB first / 1:LSB first)
(1<<MSTR)| // Master/Slave select
(0<<SPR1)|(1<<SPR0)| // SPI Clock Rate
(1<<CPOL)| // Clock Polarity (0:SCK low / 1:SCK hi when idle)
(1<<CPHA)); // Clock Phase (0:leading / 1:trailing edge sampling)
SPSR = (1<<SPI2X); // Double Clock Rate
}
void SPI_MasterTransmit(uint16_t cdata){
SPDR = cdata; //start transmission
while(!(SPSR & (1<<SPIF))); // wait for transmission complete
}
uint16_t SPI_SlaveReceive(void){
while(!(SPSR & (1<<SPIF))); //wait for reception complete
return (SPDR); //return Data Register
}
Прочитано:
uint16_t read_SPI( uint16_t address){
uint16_t datar;
Slave_select;
// charger les données inf au buffer
SPDR = uint16_t( address & 0xFF);
//attente lors de la premiere transmission
while(!(SPSR & (1<<SPIF) ));
// premier octet est reçu
datar = SPDR;
// charger les données sup au buffer
SPDR = uint16_t ((address >> 8) & 0xFF);
//attente de la seconde tr
while(!(SPSR & (1<<SPIF) ));
// seceond octet est reçu
datar = datar | ((uint16_t) (SPDR) << 8);
Slave_deselect;
return datar;
}
Написать
void write_SPI (uint16_t address, uint16_t data){
Slave_select;
SPDR= data;
while(!(SPSR & (1<<SPIF)));
/*data = SPDR;*/ // erase SPDR register
Slave_deselect;
}