新手入门
- 积分
- 16
- 金钱
- 16
- 注册时间
- 2016-6-15
- 在线时间
- 2 小时
|
5金钱
本帖最后由 Jeremy_Su 于 2016-6-15 17:51 编辑
DMA配置源码如下:
#define USART_COMMUNICATE_IDX UART2
#if USART_COMMUNICATE_IDX==UART1
#define USART_COMMUNICATE USART1
#define DMA_CHANNEL_RXD DMA1_Channel3
#define DMA_FLAG_RXD DMA1_FLAG_GL3
#else
#define USART_COMMUNICATE USART2
#define DMA_CHANNEL_RXD DMA1_Channel5
#define DMA_FLAG_RXD DMA1_FLAG_GL5
#endif
#define DMA_USART USART_COMMUNICATE
#define DMA_USART_IDX USART_COMMUNICATE_IDX
void LumMod_Uart_DMA_Rx_Data(void);
/* USART1的RxIRQ入口 */
void USART1_IRQHandler(void)
{
uint8_t int_flg=0;
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) // 空闲中断
{
LumMod_Uart_DMA_Rx_Data();
USART_ClearITPendingBit(USART1, USART_IT_IDLE);
int_flg |= 1;
}
if(!int_flg) {
if ((USART1->ISR & (~0x00000008)) != RESET) {
USART1->ICR |= 0x00000008;
}
}
}
/* USART2的RxIRQ入口 */
void USART2_IRQHandler(void)
{
uint8_t int_flg=0;
if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET) // 空闲中断
{
LumMod_Uart_DMA_Rx_Data();
USART_ClearITPendingBit(USART2, USART_IT_IDLE);
int_flg |= 1;
}
if(!int_flg) {
if ((USART2->ISR & (~0x00000008)) != RESET) {
USART2->ICR |= 0x00000008;
}
}
}
void LumMod_Uart_DMA_Rx_Data(void)
{
uint16_t i;
DMA_Cmd(DMA_CHANNEL_RXD, DISABLE); // 关闭DMA ,防止干扰
DMA_ClearFlag( DMA_FLAG_RXD ); // 清DMA标志位
s_nRxdLen = LUMMOD_RX_BSIZE - DMA_GetCurrDataCounter(DMA_CHANNEL_RXD); //获得接收到的字节数
if (FALSE==WriteBlockRoundBuf(&s_uart_round[DMA_USART_IDX], s_szBuf, s_nRxdLen)) {
for (i=0; i<s_nRxdLen; i++){
WriteRoundBuf(&s_uart_round[DMA_USART_IDX], s_szBuf);
}
}
DMA_CHANNEL_RXD->CMAR = (uint32_t)s_szBuf;
DMA_CHANNEL_RXD->CNDTR = LUMMOD_RX_BSIZE; // 重新赋值计数值,必须大于等于最大可能接收到的数据帧数目
DMA_Cmd(DMA_CHANNEL_RXD, ENABLE);
}
void DMA_Uart_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* DMA clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 开启DMA1时钟
//=DMA_Configuration==============================================================================//
/*--- DMA1_Channel3 DMA (RXD) Config ---*/
DMA_Cmd(DMA_CHANNEL_RXD, DISABLE); // 关DMA通道
DMA_DeInit(DMA_CHANNEL_RXD); // 恢复缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&DMA_USART->RDR); // 设置串口接收数据寄存器
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&s_szBuf[0]); // 设置接收缓冲区首地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 设置外设为数据源,外设寄存器 -> 内存缓冲区
DMA_InitStructure.DMA_BufferSize = LUMMOD_RX_BSIZE; // 需要最大可能接收到的字节数
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不做增加调整,调整不调整是DMA自动实现的
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存缓冲区地址增加调整
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设数据宽度8位,1个字节
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存数据宽度8位,1个字节
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 单次传输模式
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; // 优先级设置
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 关闭内存到内存的DMA模式
DMA_Init(DMA_CHANNEL_RXD, &DMA_InitStructure); // 写入配置
DMA_ClearFlag(DMA_FLAG_RXD); // 清除DMA所有标志
DMA_Cmd(DMA_CHANNEL_RXD, ENABLE); // 开启接收DMA通道,等待接收数据
USART_DMACmd(DMA_USART, USART_DMAReq_Rx, ENABLE); // 开启串口DMA接收
}
STM32F030配置USART2 接收为DMA模式后,DMA没有执行搬运数据的动作,但是IDLE中断是正常的。
当串口改为USART1 #define USART_COMMUNICATE_IDX UART1 DMA工作却是正常的, 我反复检查了所有相关串口DMA的配置 实在找不到配置上的差异 , 求大神解惑!!!
|
最佳答案
查看完整内容[请看2#楼]
问题已解决! 虽然只有原子哥一个人帮顶,不过还是要说下问题, 原因是我代码里的UART1和UART2是枚举类型的, 原来枚举是不能参与宏表达式的,由于我之前不知道, 所以编译器一直都是编译 #if USART_COMMUNICATE_IDX==UART1分支的代码!
|