我正在使用Atmega328p,我正在编写一个可以从微控制器和内存芯片读写的程序,
我试着写标签并且写得正确,但是当我想从内存芯片中读取标签时,我收到255号,我无法专门化这个错误!
有人能帮助我吗?
uint16_t read_SPI (uint16_t address){
Slave_select;
SPDR= address;
while(!(SPSR & (1<<SPIF)));
Slave_deselect;
return (SPDR);
}
void write_SPI (uint16_t address, uint16_t byte){
Slave_select;
SPDR=byte;
while(!(SPSR & (1<<SPIF)));
//address=SPDR;
/*SPI_tradeByte(0x02);
chip_send16BitAdress(address);
SPI_tradeByte(byte);*/
Slave_deselect;
}
答案 0 :(得分:3)
实际上,您通过SPI发送每字节字节(unsigned char
),因为SPI数据寄存器SPDR
只有8位宽,see datasheet第224页。
此外,您通常使用一个功能进行发送和接收,以下是接收和发送的典型实现。该函数来自here,其中SPI得到了很好的解释。
//Function to send and receive data for both master and slave
unsigned char spi_tranceiver (unsigned char data)
{
// Load data into the buffer
SPDR = data;
//Wait until transmission complete
while(!(SPSR & (1<<SPIF) ));
// Return received data
return(SPDR);
}
您的代码的一个重大区别是,您将SPDR
设置为uint16_t
值,以便寄存器溢出。
此外,您必须将正确的命令发送到您的内存芯片。您必须选择方向READ
或WRITE
,并通过发送ADDR
来寻址内存单元格。如果地址空间大于一个字节,则必须发送单独的字节。
您必须在内存控制器的数据表中查找。 Here也是一个很好的例子,可以提供帮助。
编辑#1:
关于datasheet of your memory controller,你必须考虑以下几点:
<强> 1。 阅读(数据表第19页):
要从您必须发送的芯片中读取:
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
<强> 2。 WRITE(数据表第19页):
要写入您必须发送的芯片:
0x02 = 0b00000010: 8 bit WRITE command
0x0000 - 0x07FF = 0bXXXXXAAA AAAAAAAA: 16 bit ADDRESS (5 upper bits don't
0x0000 - 0xFFFF = 0bDDDDDDDD DDDDDDDD: 16 bit DATA
第3。 内存布局(数据表第8页):
用户存储区从0x0000变为0xA6F。
<强> 4。 使用SPI信息寄存器(数据表第20页):
在串行通信模式下,如果LSI加密 执行READ / WRITE命令时出错, 错误代码将存储在th中 e 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
数据表非常详细地介绍了通信,还有时序和通信图表。按照我的说法发送命令但是每字节字节,因为SPDR
寄存器只有8位宽。像我提供的功能一样,它应该工作。