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