STM32 USART DMA
来源:互联网 发布:baidu软件 编辑:程序博客网 时间:2024/05/02 22:14
今天终于实现了,串口1接收上位机的指令,串口2转发指令给模块,再接收模块数据通过串口2发送出去。整个串口的收发由DMA完成,运用串口总线空闲中断,这个真的是STM32的内部很好的一个东东,不消耗CPU资源。
憋了我两天了,日思夜想,主要因为我对整个的逻辑开始没认真分析。
程序参考部分http://www.amobbs.com/forum.php?mod=viewthread&tid=5486343&highlight=STM32%E5%AE%9E%E7%8E%B0USART%2BDMA%E6%8E%A5%E6%94%B6%E6%9C%AA%E7%9F%A5%E9%95%BF%E5%BA%A6%E7%9A%84%E6%95%B0%E6%8D%AE%E5%92%8C%E5%8F%91%E9%80%81
下面贴上部分我修改的程序,配置都是参考以上的,上面的写得非常详细,非常推荐看一下。
在定义这一块修改了一下:
#define SENDBUFF_SIZE 10240
vu8 USART1_SEND_DATA[SENDBUFF_SIZE]; //512
vu8 USART2_SEND_DATA[SENDBUFF_SIZE]; //512
vu8 USART1_RECEIVE_DATA[SENDBUFF_SIZE]; //512
vu8 USART2_RECEIVE_DATA[SENDBUFF_SIZE]; //512
vu8 USART1_TX_Finish=1;// USART1发送完成标志量
vu8 USART2_TX_Finish=1; // USART2发送完成标志量
在DMA的配置里面
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//512
中断里面:
串口1中断
void USART1_IRQHandler(void)
{
u16 DATA_LEN;
u16 i;
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)//如果为空闲总线中断
{
DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
//USART_RX_STA = USART1->SR;//先读SR,然后读DR才能清除
//USART_RX_STA = USART1->DR;
DATA_LEN=SENDBUFF_SIZE-DMA_GetCurrDataCounter(DMA1_Channel5);
if(DATA_LEN > 0)
{
while(USART2_TX_Finish==0)//等待数据传输完成才下一次
{
;
}
//将数据送DMA存储地址
for(i=0;i<DATA_LEN;i++)
{
USART2_SEND_DATA[i]=USART1_RECEIVE_DATA[i];
}
//USART用DMA传输替代查询方式发送,克服被高优先级中断而产生丢帧现象。
DMA_Cmd(DMA1_Channel7, DISABLE); //改变datasize前先要禁止通道工作
DMA1_Channel7->CNDTR=DATA_LEN; //DMA1,传输数据量
USART2_TX_Finish=0;
DMA_Cmd(DMA1_Channel7, ENABLE);
}
//DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
DMA_ClearFlag(DMA1_FLAG_GL5 | DMA1_FLAG_TC5 | DMA1_FLAG_TE5 | DMA1_FLAG_HT5);//清标志
DMA1_Channel5->CNDTR = SENDBUFF_SIZE;//重装填 512
DMA_Cmd(DMA1_Channel5, ENABLE);//处理完,重开DMA
//读SR后读DR清除Idle
i = USART1->SR;
i = USART1->DR;
}
if(USART_GetITStatus(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出错
{
USART_ClearITPendingBit(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE);
}
USART_ClearITPendingBit(USART1, USART_IT_TC);
USART_ClearITPendingBit(USART1, USART_IT_IDLE);
}
串口2中断
void USART2_IRQHandler(void)
{
u16 DATA_LEN;
u16 i;
if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET) //如果为空闲总线中断
{
DMA_Cmd(DMA1_Channel6, DISABLE);//关闭DMA,防止处理其间有数据
//USART_RX_STA = USART1->SR;//先读SR,然后读DR才能清除
//USART_RX_STA = USART1->DR;
DATA_LEN=SENDBUFF_SIZE-DMA_GetCurrDataCounter(DMA1_Channel6);
if(DATA_LEN > 0)
{
while(USART1_TX_Finish==0)//等待数据完成才下一次
{
;
}
//将数据送DMA存储地址
for(i=0;i<DATA_LEN;i++)
{
USART1_SEND_DATA[i]=USART2_RECEIVE_DATA[i];
}
//USART用DMA传输替代查询方式发送,克服被高优先级中断而产生丢帧现象。
DMA_Cmd(DMA1_Channel4, DISABLE); //改变datasize前先要禁止通道工作
DMA1_Channel4->CNDTR=DATA_LEN; //DMA1,传输数据量
USART1_TX_Finish=0;
DMA_Cmd(DMA1_Channel4, ENABLE);
}
//DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
DMA_ClearFlag(DMA1_FLAG_GL6 | DMA1_FLAG_TC6 | DMA1_FLAG_TE6 | DMA1_FLAG_HT6);//清标志
DMA1_Channel6->CNDTR = SENDBUFF_SIZE;//重装填 512
DMA_Cmd(DMA1_Channel6, ENABLE);//处理完,重开DMA
//读SR后读DR清除Idle
i = USART2->SR;
i = USART2->DR;
}
if(USART_GetITStatus(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出错
{
USART_ClearITPendingBit(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE);
}
USART_ClearITPendingBit(USART2, USART_IT_TC);
USART_ClearITPendingBit(USART2, USART_IT_IDLE);
}
- STM32 DMA USART ADC
- STM32 USART DMA
- STM32笔记---DMA(USART)的演示
- 实现STM32中USART的DMA
- 实现STM32中USART的DMA
- 实现STM32中USART的DMA
- STM32:DMA实例之串口(USART)通信
- STM32 USART DMA发送 中断接收
- STM32笔记(三)ADC、DMA、USART的综合练习
- STM32中USART的DMA 实现(转)
- 实现STM32中USART的DMA(转)
- STM32笔记(四)DMA、USART的演示
- Stm32使用Usart代码例子(轮询、中断、DMA)
- STM32 USART 串口 DMA 接收和发送的源码详解!
- STM32----------ADC和DMA(附:完整USART输出程序)
- STM32 USART串口DMA接收和发送模式
- stm32 usart在DMA模式下只能发送一次
- STM32 USART 串口 DMA 接收和发送的源码详解!
- ORACLE-SQL性能优化
- python PEP8格式
- chromium之content_shell源代码分析(二)
- Fiddler 教程
- Android高效加载大图、多图解决方案,有效避免程序OOM
- STM32 USART DMA
- TopCoder 300 points 27-SRM 157 DIV 1 90/300 30%
- ssh 通过 443 访问 github - github access from behind a firewall
- burpsuite绕过本地javascripte上传文件
- Boa服务器移植
- Notepad++ 快捷键
- Learn UML with Jude
- ocp-047-87 where 条件限制的自连接
- 程序员如何成功的假装在很努力的工作