AVR 问题:在spi 中,spdr 寄存器是8 位,但我的数字是16 位

Avr Problem: in spi, spdr register is 8 bit but my number is 16 bit

我在 atmega16 工作,在主从两个方面。 我想将键盘输入的 100-999 之间的数字发送给从机。 数字是 16 位,但 spdr 寄存器是 8 位,所以我先发送 lsb,然后发送 msb 位。这很好用,我正确地发送了我的号码。

但我的问题出在从属端: 我在从属端启用了中断 spie,因此从主控端接收到的每个 spdr 都作为中断并进入 ISR 功能。但是因为我的数是16位的,所以想把每16位或者两个字节作为一个中断。我该怎么办?

您知道您的消息长度(16 位或 2 字节)。只需创建一个环形缓冲区来存储两个字节并填充环形缓冲区。也许您可以添加第三个字节作为开始或结束字节或其他内容,但这取决于您。如果您的传输结束,您还可以设置一个标志。

因此您的代码可以如下所示。请注意,此代码只是 ISR 和作为 SPI 从设备的 XMega,但它应该有助于理解该过程。

#define SPI_BUFFER_SIZE                     2
uint8_t SPI_RxSlaveBuffer[SPI_BUFFER_SIZE];

typedef struct 
{
    uint8_t* RxBuffer;
    uint8_t BytesProcessed;
    uint8_t Status;
} SPI_Buffer_t;

static SPI_Buffer_t SlaveBuffer;

int main()
{
   // Some code
   SlaveBuffer.RxBuffer = SPI_RxSlaveBuffer;
   // Some other code
}

ISR(SPIC_INT_vect)
{
    SlaveBuffer.RxBuffer[SlaveBuffer.BytesProcessed++] = SPIC.DATA;

    if(SlaveBuffer.BytesProcessed >= SPI_BUFFER_SIZE - 1)
    {
        SlaveBuffer.BytesProcessed = 0x00;
        SlaveBuffer.Status = 0x01;
    }
}

您还可以检查 SS 引脚的状态,如果主控器断言该引脚(如果主控器已中止传输或其他原因),则重置计数器 - 例如轮询SS 引脚或将 SS 引脚的信号连接到中断引脚以生成额外的 I/O 中断。