打印
[开发工具]

SPI 通信,既有单字节数据传输,又有多字节数据传输,该如正确使用 DMA?

[复制链接]
47|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
laocuo1142|  楼主 | 2024-11-8 09:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用 ENC28J60 + UIP 实现 UDP 数据的收发,其中ENC28J60 通过 SPI 接口和单片机连接;在收发数据的时候,要先对 ENC28J60 的寄存器进行读写,然后才写入或者读取要收发的数据。
    读写寄存器的时候,开启了 SPI 的片选,只需要读取 1 到 2 个字节的数据;在正式读写收发的数据的时候,开启 SPI 片选需要读写多个字节的数据。
    这样的情况下如何配置DMA,如果在开启片选信号的时候开启DMA,关闭片选信号的情况下关闭DMA;在进行寄存器读写的时候,岂不是会出现频繁开关DMA的情况,这样算不算降低了程序的执行效率,而且还增加了程序的不稳定性?
    我想在进行寄存器读写的时候,单独使用SPI,不使能DMA,在传输数据的时候,再开启DMA,请问这样配置合理吗?或者说还有无其他的实现方式?

读写寄存器部分代码:
/*********************************************
函数名:ENC28J60_ReadOp
功  能:从器件寄存器读取状态
形  参:op--操作码  address--控制寄存器地址
返回值:寄存器状态值
备  注:命令时序图--29页
**********************************************/
uint8_t ENC28J60_ReadOp(uint8_t op, uint8_t address)
{
    uint8_t dat = 0;

    CS_L;

    dat = op | (address & ADDR_MASK); //重构操作码和地址,参见手册第28页。
    SPI_ReadWrite(dat);

    dat = SPI_ReadWrite(0xFF);
    //如果需要,进行虚拟读取(对于MAC和MII,请参见手册第29页)
        /* 如果是MAC和MII寄存器,第一个读取的字节无效,该信息包含在地址的最高位 */
    if(address & 0x80)
    {
        dat = SPI_ReadWrite(0xFF);
    }

    CS_H;
    return dat;
}

/*********************************************
函数名:ENC28J60_WriteOp
功  能:向器件寄存器写入1byte
形  参:op--操作码  address--控制寄存器地址  data--数据字节
**********************************************/
void ENC28J60_WriteOp(uint8_t op, uint8_t address, uint8_t data)
{
    uint8_t dat = 0;

    CS_L;
    dat = op | (address & ADDR_MASK);//重构操作码和地址,参见手册第28页。
    SPI_ReadWrite(dat);

    SPI_ReadWrite(data);//写入数据
    CS_H;

}

读写数据部分代码:
/*********************************************
函数名:ENC28J60_ReadBuffer
功  能:读取缓冲存储器的数据
形  参:len--长度   data--存放数据的指针
**********************************************/
void ENC28J60_ReadBuffer(uint32_t len, uint8_t* data)
{
    CS_L;
    SPI_ReadWrite(ENC28J60_READ_BUF_MEM);
    while(len)
    {
        len--;
        *data = (uint8_t)SPI_ReadWrite(0);
        data++;
    }
    *data = '\0';
    CS_H;
}
/*********************************************
函数名:ENC28J60_WriteBuffer
功  能:向缓冲存储器写入数据
形  参:len--字节长度   data--数据内容的指针
**********************************************/
void ENC28J60_WriteBuffer(uint32_t len, uint8_t* data)
{
    CS_L;
    SPI_ReadWrite(ENC28J60_WRITE_BUF_MEM);
    while(len)
    {
        len--;
        SPI_ReadWrite(*data);
        data++;
    }
    CS_H;

}

使用特权

评论回复
沙发
两只袜子| | 2024-11-8 16:00 | 只看该作者
在SPI通信中正确使用DMA进行数据传输需要仔细配置和初始化SPI和DMA模块,并考虑数据格式、缓冲区管理、错误处理、性能优化以及低功耗等因素。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1172

主题

5129

帖子

12

粉丝