“触发慢,自然就慢”这句没太明白。
(1)DMA功能平时是关闭的,只有在使用时才启用。
(2)在使用时传入实际的数据缓存、长度,开启DMA(此时就是马上触发了,不知道触发快慢是如
何控制的),等待操作完毕后,再关闭DMA功能。
我把相关代码贴出来,麻烦大家帮看看。可以正常使用,就是速度无任何改善。
宏定义:
[mw_shl_code=c,true]#ifdef SPI2_DMA
#define SPI_MASTER_DMA DMA1
#define SPI_MASTER_DMA_CLK RCC_AHBPeriph_DMA1
#define SPI_MASTER_Rx_DMA_Channel DMA1_Channel4
#define SPI_MASTER_Rx_DMA_FLAG DMA1_FLAG_TC4
#define SPI_MASTER_Tx_DMA_Channel DMA1_Channel5
#define SPI_MASTER_Tx_DMA_FLAG DMA1_FLAG_TC5
#endif //SPI2_DMA
[/mw_shl_code]
DMA基本配置:
[mw_shl_code=c,true]#ifdef SPI2_DMA
/* SPI_MASTER_Rx_DMA_Channel configuration ------------------------*/
DMA_DeInit(SPI_MASTER_Rx_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)uip_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI_MASTER_Rx_DMA_Channel, &DMA_InitStructure);
/* SPI_MASTER_Tx_DMA_Channel configuration -------------------------------*/
DMA_DeInit(SPI_MASTER_Tx_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)uip_buf;[/mw_shl_code]
[mw_shl_code=c,true]
[mw_shl_code=c,true] DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;[/mw_shl_code]
[/mw_shl_code]
[mw_shl_code=c,true] DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI_MASTER_Tx_DMA_Channel, &DMA_InitStructure);
#endif //SPI2_DMA[/mw_shl_code]
写缓存:
[mw_shl_code=c,true]void enc28j60WriteBuffer(unsigned int len, unsigned char* data)
{
CS28J60_Low();
// issue write command
SPI2_ReadWrite(ENC28J60_WRITE_BUF_MEM);
#ifndef SPI2_DMA
while(len)
{
len--;
SPI2_ReadWrite(*data);
data++;
}
CS28J60_High();
#else
((DMA_Channel_TypeDef *)SPI_MASTER_Tx_DMA_Channel)->CMAR = (uint32_t)data;
((DMA_Channel_TypeDef *)SPI_MASTER_Tx_DMA_Channel)->CNDTR = (uint32_t)len;
DMA_Cmd(SPI_MASTER_Tx_DMA_Channel, ENABLE);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);//TX DMA request, start move data
while(!DMA_GetFlagStatus(SPI_MASTER_Tx_DMA_FLAG));
DMA_ClearFlag(SPI_MASTER_Tx_DMA_FLAG);
CS28J60_High();
DMA_Cmd(SPI_MASTER_Tx_DMA_Channel, DISABLE);
#endif //SPI2_DMA
}
[/mw_shl_code]
读缓存:
[mw_shl_code=c,true]void enc28j60ReadBuffer(unsigned int len, unsigned char* data)
{
uint32_t mccr;
CS28J60_Low();
// issue read command
SPI2_ReadWrite(ENC28J60_READ_BUF_MEM);
#ifndef SPI2_DMA
while(len)
{
len--;
// read data
*data = (unsigned char)SPI2_ReadWrite(0);
data++;
}
*data='\0';
CS28J60_High();
#else
((DMA_Channel_TypeDef *)SPI_MASTER_Rx_DMA_Channel)->CMAR = (uint32_t)data;
((DMA_Channel_TypeDef *)SPI_MASTER_Rx_DMA_Channel)->CNDTR = (uint32_t)len;
DMA_Cmd(SPI_MASTER_Rx_DMA_Channel, ENABLE);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);//RX DMA request, start move data
/* Dummy TX to generate SPI clock for RX*/
mccr = ((DMA_Channel_TypeDef *)SPI_MASTER_Tx_DMA_Channel)->CCR; //Save DMA channel 3 configuration register
((DMA_Channel_TypeDef *)SPI_MASTER_Tx_DMA_Channel)->CCR = (mccr & 0xffffff31); // Peripheral & memory doesn't auto increment. Interrupt disable
((DMA_Channel_TypeDef *)SPI_MASTER_Tx_DMA_Channel)->CMAR = (uint32_t)data;
((DMA_Channel_TypeDef *)SPI_MASTER_Tx_DMA_Channel)->CNDTR = (uint32_t)len;
DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, DISABLE);//Diable Interrupt
DMA_Cmd(SPI_MASTER_Tx_DMA_Channel, ENABLE);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);//TX DMA request, start move data
while(!DMA_GetFlagStatus(SPI_MASTER_Rx_DMA_FLAG));
while(!DMA_GetFlagStatus(SPI_MASTER_Tx_DMA_FLAG));
DMA_ClearFlag(SPI_MASTER_Rx_DMA_FLAG);
DMA_ClearFlag(SPI_MASTER_Tx_DMA_FLAG);
// data++;
// *data='\0';
CS28J60_High();
DMA_Cmd(SPI_MASTER_Rx_DMA_Channel, DISABLE);
/* Restore Tx setting */
DMA_Cmd(SPI_MASTER_Tx_DMA_Channel, DISABLE);
((DMA_Channel_TypeDef *)SPI_MASTER_Tx_DMA_Channel)->CCR = mccr;
DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
#endif
}
[/mw_shl_code]
|