历史上的今天

今天是:2024年08月27日(星期二)

正在发生

2018年08月27日 | STM32通过中断方式实现USART1通信

发布者:SparklingRiver 来源: eefocus关键字:STM32  中断方式  USART1通信 手机看文章 扫描二维码
随时随地手机看文章

1.前言


这个例程花了我好几天的时间,涉及到的内容比较多,走了很多弯路,一定要总结一下!

首先说明,我的开发板不是比较流行的正点原子家的,而是普中的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吗? 

回答: 

可以。把: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.总结

这个例程已经花了好几天时间了……

今天上午实验室的师兄师姐们进行招聘网上答题,给出一个问题,在很短的时间内提出解决方法并编出程序。感觉这种考验真的能体现出水平,不妨偶尔把平时遇到的问题当做考试来解决,换一换思路和环境,毕竟也不是做研究,没必要按部就班像上课一样学习。

遇到一个问题就像面临一张空白的试卷,我按照流程不慌不忙的花个几天解决问题,就像把试卷当做练习题来做;

但是总做练习题,水平提高的并不是很快,不如偶尔认真起来,把这一张试卷当做考试,不是为了应试,而是为了在考试中发现自己的薄弱部分,毕竟考试完毕也可以好好总结。

从下一个例程开始!


关键字:STM32  中断方式  USART1通信 引用地址:STM32通过中断方式实现USART1通信

上一篇:STM32的AFIO时钟什么时候需要开启
下一篇:开启和关闭AFIO时钟

推荐阅读

这段时间半导体投资是比较热点的,这股热潮也是MLCC陶瓷电容缺货导致大家开始关注随着半导体行业的供需阶段性失衡,大玩家可以调控价格导致各方面的紧张。这个价格和拿货可不是那么简单的事情。  如下图所示,基础的如模拟、分立器件和MEMS这些有待增长。  半导体分立器件这些器件主要包括二极管(含稳压管、TVS)、信号三极管、功率三极管等等。  ...
开源作为科技产业发展的一大驱动力,在新兴领域尤为受推崇。RISC-V无疑是这两年开源界最受关注的新星之一。今年7月10日,RISC-V生态系统又迎来里程碑事件。RISC-V基金会宣布批准RISC-V基础指令集架构与特权架构规范。RISC-V发展迅猛,RISC-V阵营也在不断加强。8月22日,兆易创新首发RISC-V内核32位通用MCU,成为国内RISC-V芯又一重要事件。当然,本周还有...
PICC变量的类型与定义PICC变量及定义1、当变量为多字节数据时,PICC按低字节存放在低地址、高字节存放在高地址的原则存放变量,并以最低字节的地址作为该变量的地址。例如int型变量i的值为0X1234,低字节0x34存放在0X30,高字节0x12存放在0X31,并以0x30作为变量i的地址。2、单片机的带符号的整数均以补码方式存放。对于二进制数来说,先减一后取反和先取...
据外媒报道,由杜兰大学(Tulane University)科学与工程系Ken & Ruth Arnold早期职业教授(Ken & Ruth Arnold Early Career Professor in Science and Engineering)Michael Naguib领导的研究团队设计出新型纳米级材料,可实现高功率和能量密度,或可大大加快电动汽车和便携式设备(如手机和笔记本电脑)的充电速度。这种新材料有可能将充...

史海拾趣

问答坊 | AI 解惑

关于购买开发板的问题

    本人刚入行嵌入式开发,基础较薄弱,尤其是底层驱动硬件方面,现在主要做qt的开发,我对底层也敢兴趣,想买块开发板玩玩,是价格便宜的24xx呢,还是功能强大的6410啊。开发板纯粹用来学习用,请各位大牛指教~…

查看全部问答∨

驱动程序开发小问题

小弟正在学习Windows驱动开发,写了个HelloDDK,其中头文件中有一段代码如下: #ifdef __cplusplus extern "C" { #endif #include <wdm.h> #ifdef __cplusplus } #endif 但编译连接就有如下错误: fatal error C1083: Cannot op ...…

查看全部问答∨

[急!!!]内存溢出??

EVC书上的例子,但是程序有些错,如果输入数字超过2个,程序自动关闭。或是输入字母有时出现同样情况。内存分配的函数如下,这些数据还没写入串口缓冲区呀,占用的内存应该也不多呀。是什么问题啊??? 获取用户输入:BYTE * buf;     ...…

查看全部问答∨

无线技术经典方案与教程

无线技术分不同种类,通常以产生无线信号的方式来区分,目前主要的方式有调频无线技术、红外无线技术和蓝牙无线技术三种,其成本和特点也不尽相同。广泛应用于音响 键鼠等各项内容,有很好的发展前景。 无线技术定义:智能天线原名自适应天线阵列( ...…

查看全部问答∨

用STM32操作AD芯片,会出现毛刺,什么原因?

这是STM32f103操作AD芯片(AD7746)的写入波形图,会发现有毛刺 上面两张为细节图 下面给出的是为F2812对相同芯片操作波形图,就没有明显的毛刺 STM32F103为什么GPIO口会出现电平转换,毛刺产生的问题,这是外围电路搭接产生的问题还是芯片本 ...…

查看全部问答∨

求指点MSP430F149驱动超声波模块程序,不能正常工作

求指点MSP430F149驱动超声波模块程序,不能正常工作 #include <msp430f149.h> #define  RISE  1 #define  FALL  0 #define CPU_F ((double)8000000) #define delay_us(x) __delay_cycles((long)( ...…

查看全部问答∨

【朱兆祺带你学嵌入式】第二章第八节 U-Boot-2013.04启动分析(4)

1)        调用board_init_f函数    bl  board_init_f实际上,board_init_f()函数是U-Boot执行的第一个C语言函数:void board_init_f(ulong bootflag),这个函数位于arch/arm/lib目录下的board. ...…

查看全部问答∨

蓝牙4.0之旅第二步 CC2540 USB DONGLE 布局完成喽

淘宝上卖的太贵了,准备自己做一个。 可以通过ANDROID上的USB连接滴蓝牙模块,让普通PAD装备BLE功能 顺便放几个PCB参考设计的资料,TI官方的,网站上就能下到。 [ 本帖最后由 littleshrimp 于 2013-12-15 20:08 编辑 ]…

查看全部问答∨

UCD3138 交错PFC 调试问题

我在调试UCD3138交错PFC时出现如下问题:波形如下图所示,其中CH3是交流输入电流, CH4是其中一相驱动管DS波形,另外两个通道CH1和CH2没有用到。对外围电路进行了各种调试,DS波形和输入电流总会间歇性出现一段不稳定(或不正常的情况),请问这是 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved