STM32通过中断方式实现USART1通信
2017-08-30 22:35
288 查看
1.前言
这个例程花了我好几天的时间,涉及到的内容比较多,走了很多弯路,一定要总结一下!
首先说明,我的开发板不是比较流行的正点原子家的,而是普中的STM32F1,原子家的开发板太贵了。到目前为止,我还没有发现我的开发板出现硬件上的问题,就是客服很不给力,关于仿真器配置的一个小问题就解决不了。好在网上资料比较丰富,慢慢也能解决自己遇到的一些问题。
思路和程序网上大家列举的都一样。在上网查资料的过程中发现,ARM开发板就是厉害,我想找什么问题,不管大家用什么型号的开发板,程序几乎一点都没有变化,问题讨论起来方便多了!
2.程序摘要
分为4部分:GPIO配置、USART参数配置、NVIC总中断配置、中断函数;
在主函数中初始化以上配置,直接进入while(1)就行了。
首先配置管脚GPIOA:GPIO_Init
注意:这里使用了管脚复用功能,但是并不需要下面这句话:
“RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);”
原因:STM32F103:什么时候需要复用IO(AFIO)?
串口通信USART1参数配置:USART_Init
使用USART_Init函数,配置包括波特率、停止位、数据位、校验位等常见的串口通信的参数;
这里要弄清楚,可以操作USART1中断标志位(也就是输入参数是USART的中断类型)的库函数有三个:
USART_ITConfig:使能/失能中断
USART_ GetITStatus:读取中断状态
USART_ClearITPendingBit:清除中断标志位
其中,清除中断标志位用: USART_ClearITPendingBit;
总中断设置:NVIC_Init
中断函数
这里要实现的功能是:
PC向单片机发送字节数据,单片机接收到数据后+2,并返回到PC端;
第一个问题:
进入中断之后,判断中断发生的类型时,可以使用USART_GetFlagStatus吗?
b08e
回答:
可以。把:if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)
替换成: if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)),
结果证明可以。
事实上,USART_IT_RXNE 只是中断类型名,要接ENABLE/DISABLE的,不是中断标志位,我猜测 USART_GetITStatus 函数其实判断的也是发送完成的flag:USART_FLAG_TXE。
但是,明明已经进入了中断,查询中断状态来判断不是更加顺其自然吗!
第二个问题:
执行发送语句、等待发送完成的时候,可以用 USART_GetITStatus 函数判断是否发送完成吗?
回答:
不可以。因为发送中断根本没打开,中断状态也是无效的。
3.遇到的问题
软件问题
写好程序之后,通过仿真器调试发现,总是不能进入接收字节的串口中断;
当时有一种病急乱投医的感觉,在网上查了很多资料,有说“不该打开发送中断”的,有说“在中断函数中没有清楚中断标志位”的,也有说“管脚复用没有打开”的……
再说明一下:本次管脚复用不需要用那句话打开的,上面链接讲的很详细了。
等我调试好,把上面的说法进行逐个验证,最后不需要的都没加上,最终得到了上面所示的最简洁的,并且实现预期效果的通信程序。
硬件问题
其实,最开始导致程序不能进入中断的原因,是硬件的原因。
232串口通信,根据我的经验,找了一根USB转9针串口,连接上发现不进入中断……
后来各种调试没结果,实在没办法了,看视频才知道,这个开发板的232有两种模式,USART1使用的是:
PC→USB转microUSB数据线→CH340芯片→USART1接口→MCU
而常见的却是这种模式:
PC→USB转9针串口数据线→max232芯片→USART1串口→MCU
我误以为USART1是后者,调了很久没结果……
4.总结
这个例程已经花了好几天时间了……
今天上午实验室的师兄师姐们进行招聘网上答题,给出一个问题,在很短的时间内提出解决方法并编出程序。感觉这种考验真的能体现出水平,不妨偶尔把平时遇到的问题当做考试来解决,换一换思路和环境,毕竟也不是做研究,没必要按部就班像上课一样学习。
遇到一个问题就像面临一张空白的试卷,我按照流程不慌不忙的花个几天解决问题,就像把试卷当做练习题来做;
但是总做练习题,水平提高的并不是很快,不如偶尔认真起来,把这一张试卷当做考试,不是为了应试,而是为了在考试中发现自己的薄弱部分,毕竟考试完毕也可以好好总结。
从下一个例程开始!
这个例程花了我好几天的时间,涉及到的内容比较多,走了很多弯路,一定要总结一下!
首先说明,我的开发板不是比较流行的正点原子家的,而是普中的STM32F1,原子家的开发板太贵了。到目前为止,我还没有发现我的开发板出现硬件上的问题,就是客服很不给力,关于仿真器配置的一个小问题就解决不了。好在网上资料比较丰富,慢慢也能解决自己遇到的一些问题。
思路和程序网上大家列举的都一样。在上网查资料的过程中发现,ARM开发板就是厉害,我想找什么问题,不管大家用什么型号的开发板,程序几乎一点都没有变化,问题讨论起来方便多了!
2.程序摘要
分为4部分:GPIO配置、USART参数配置、NVIC总中断配置、中断函数;
在主函数中初始化以上配置,直接进入while(1)就行了。
首先配置管脚GPIOA:GPIO_Init
//使用USART1的PA9和PA10,打开GPIOA: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //打开USART1时钟; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //通过结构体配置GPIOA的USART1接口PA9,输出为“复用推挽输出”: GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //P10接口,输入为“模拟浮空输入”: GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; ……
注意:这里使用了管脚复用功能,但是并不需要下面这句话:
“RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);”
原因:STM32F103:什么时候需要复用IO(AFIO)?
串口通信USART1参数配置:USART_Init
使用USART_Init函数,配置包括波特率、停止位、数据位、校验位等常见的串口通信的参数;
//记得同时打开“发送模式”和“接收模式”: USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //打开串口USART1使能: USART_Cmd(USART1, ENABLE); //打开USART1的串口接收中断: USART_ITConfig(USART1, USART_IT_RXNE ,ENABLE); //清除中断标志位 USART_ClearITPendingBit(USART1, USART_IT_RXNE);
这里要弄清楚,可以操作USART1中断标志位(也就是输入参数是USART的中断类型)的库函数有三个:
USART_ITConfig:使能/失能中断
USART_ GetITStatus:读取中断状态
USART_ClearITPendingBit:清除中断标志位
其中,清除中断标志位用: USART_ClearITPendingBit;
总中断设置:NVIC_Init
//记得配置中断参数之前,要进行中断分组; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //选择USART1中断 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
中断函数
这里要实现的功能是:
PC向单片机发送字节数据,单片机接收到数据后+2,并返回到PC端;
void USART1_IRQHandler () { u8 k; //判断现在发生的中断的类型,可以用USART_GetFlagStatus吗? if(USART_GetITStatus(USART1,USART_IT_RXNE)== SET) { //读接收寄存器,系统自动清除接收中断标志位 k=USART_ReceiveData(USART1); k=k+2; //发送数据 USART_SendData(USART1,k); //等发送完成;可以用USART_GetITStatus吗? while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); } }
第一个问题:
进入中断之后,判断中断发生的类型时,可以使用USART_GetFlagStatus吗?
b08e
回答:
可以。把:if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)
替换成: if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)),
结果证明可以。
事实上,USART_IT_RXNE 只是中断类型名,要接ENABLE/DISABLE的,不是中断标志位,我猜测 USART_GetITStatus 函数其实判断的也是发送完成的flag:USART_FLAG_TXE。
但是,明明已经进入了中断,查询中断状态来判断不是更加顺其自然吗!
第二个问题:
执行发送语句、等待发送完成的时候,可以用 USART_GetITStatus 函数判断是否发送完成吗?
回答:
不可以。因为发送中断根本没打开,中断状态也是无效的。
3.遇到的问题
软件问题
写好程序之后,通过仿真器调试发现,总是不能进入接收字节的串口中断;
当时有一种病急乱投医的感觉,在网上查了很多资料,有说“不该打开发送中断”的,有说“在中断函数中没有清楚中断标志位”的,也有说“管脚复用没有打开”的……
再说明一下:本次管脚复用不需要用那句话打开的,上面链接讲的很详细了。
等我调试好,把上面的说法进行逐个验证,最后不需要的都没加上,最终得到了上面所示的最简洁的,并且实现预期效果的通信程序。
硬件问题
其实,最开始导致程序不能进入中断的原因,是硬件的原因。
232串口通信,根据我的经验,找了一根USB转9针串口,连接上发现不进入中断……
后来各种调试没结果,实在没办法了,看视频才知道,这个开发板的232有两种模式,USART1使用的是:
PC→USB转microUSB数据线→CH340芯片→USART1接口→MCU
而常见的却是这种模式:
PC→USB转9针串口数据线→max232芯片→USART1串口→MCU
我误以为USART1是后者,调了很久没结果……
4.总结
这个例程已经花了好几天时间了……
今天上午实验室的师兄师姐们进行招聘网上答题,给出一个问题,在很短的时间内提出解决方法并编出程序。感觉这种考验真的能体现出水平,不妨偶尔把平时遇到的问题当做考试来解决,换一换思路和环境,毕竟也不是做研究,没必要按部就班像上课一样学习。
遇到一个问题就像面临一张空白的试卷,我按照流程不慌不忙的花个几天解决问题,就像把试卷当做练习题来做;
但是总做练习题,水平提高的并不是很快,不如偶尔认真起来,把这一张试卷当做考试,不是为了应试,而是为了在考试中发现自己的薄弱部分,毕竟考试完毕也可以好好总结。
从下一个例程开始!
相关文章推荐
- QTE下通过Http协议以同步方式与Web服务器通信的实现
- STM32 -USART中断方式
- STM32 -USART中断方式
- 通过跳线方式实现STM32 的IAP模式
- stm32的usb与上位机通过中断传输进行通信控制led--LibUsbDotNet
- HTTP 通信, 三种方式XML 解析,并通过 Hander 实现异步消息处理
- 通过关中断的方式来实现原语的分析
- STM32学习之:USART中断方式
- 用中断方式在嵌入式操作系统μC/OS-Ⅱ上实现多任务通信
- STM32 I2C 硬件中断方式实现方法,带流程图
- STM32 学习八 USART通信3 库函数方式编程
- STM32 学习九 通过USART实现printf重定向
- 俩个PC机通过串行口互联,实现件的无差错传输。程序必须用中断方式来完成任务
- STM32 学习七 USART通信2 寄存器方式编程
- jBPM与业务系统集成-通过定制Task Instance等方式实现
- iOS通过OTA方式分发应用的实现
- 两台计算机实现通信的几种方式(转)
- 如何通过js跨域调用ASP.NET Web API (请问如何实现在javascript中通过http get的方式跨域调用ASP.NET Web API?)
- 串口中断方式通信(非类库)
- PHP如何通过AJAX方式实现登录功能