使用SPI从Slave读取

时间:2017-06-26 09:48:42

标签: c++ avr atmega atmelstudio

我正在使用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;
}

1 个答案:

答案 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值,以便寄存器溢出。

此外,您必须将正确的命令发送到您的内存芯片。您必须选择方向READWRITE,并通过发送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位宽。像我提供的功能一样,它应该工作。