浅谈STM32串口USART1的使用

通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择,支持同步单向通信和半双工单线通信。1、STM32固件库使用外围设备的主要思路在STM32中,外围设备的配置思路比较固定。首先是使能相关的时钟,一方面是设备本身的时钟,另一方面如果设备通过IO口输出还需要使能IO口的时钟;最后如果对应的IO口是复用功能的IO口,则还必须使能AFIO的时钟。其次是配置GPIO,GPIO的各种属性由硬件手册的AFIO一章详细规定,较为简单。接着相关设备需要如果需要使用中断功能,必须先配置中断优先级。然后是配置外围设备的相关属性,视具体设备而定,如果设备需要使用中断方式,必须使能相应设备的中断,之后需要使能相关设备。最后如果设备使用了中断功能,则还需要填写相应的中断服务程序,在服务程序中进行相应操作。2、UART的配置步骤(查询方式)2.1、打开时钟由于UART的TX和RX和AFIO都挂在APB2桥上,因此采用固件库函数RCC_APB2PeriphClockCmd()进行初始化。UARTx需要分情况讨论,如果是UART1,则挂在APB2桥上,因此采用RCC_APB2PeriphClockCmd()进行初始化,其余的UART2~5均挂在APB1上。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);

2.2、GPIO初始化GPIO的属性包含在结构体GPIO_InitTypeDef,其中对于TX引脚,GPIO_Mode字段设置为GPIO_Mode_AF_PP(复用推挽输出),GPIO_Speed切换速率设置为GPIO_Speed_50MHz;对于RX引脚,GPIO_Mode字段设置为GPIO_Mode_IN_FLOATING(浮空输入),不需要设置切换速率。最后通过GPIO_Init()使能IO口。以下是GPIO设置的实例代码:

GPIO_InitTypeDef GPIO_InitStructure;//USART1 Tx(PA.09)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);//USART1 Rx(PA.10)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);

2.3、配置UART相关属性通过结构体USART_InitTypeDef来确定。UART模式下的字段如下USART_BaudRate:波特率,视具体设备而定USART_WordLength:字长USART_StopBits:停止位USART_Parity:校验方式USART_HardwareFlowControl:硬件流控制USART_Mode:单/双工最后设置。实例代码为:

//USART1配置USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE);

别忘了最后要使用USART_Cmd()来启动设备UART1。2.4、重定向print()函数。

int fputc(int ch,FILE *f){    USART1->SR;  //USART_GetFlagStatus(USART1, USART_FLAG_TC) 解决第一个字符发送失败的问题    //一个一个发送字符    USART_SendData(USART1, (unsigned char) ch);    //等待发送完成    while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);        return(ch);}

后通过主函数直接输出即可。

int main(void){    // USART1 config 9600 8-N-1    USART1_Config();        printf("hello world!");}

3、UART的配置步骤(中断方式)打开时钟、GPIO初始化、配置UART相关属性、重定向print()函数 与上面的相同。3.1、中断优先级的配置这是STM32比较奇怪的地方,在只有一个中断的情况下,仍然需要配置优先级,其作用是使能某条中断的触发通道。STM32的中断有至多两个层次,分别是先占优先级和从优先级,而整个优先级设置参数的长度为4位,因此需要首先划分先占优先级位数和从优先级位数,通过NVIC_PriorityGroupConfig()实现;特定设备的中断优先级NVIC的属性包含在结构体NVIC_InitTypeDef中,其中字段NVIC_IRQChannel包含了设备的中断向量,保存在启动代码中;字段NVIC_IRQChannelPreemptionPriority为主优先级,NVIC_IRQChannelSubPriority为从优先级,取值的范围应根据位数划分的情况而定;最后NVIC_IRQChannelCmd字段是是否使能,一般定位ENABLE。最后通过NVIC_Init()来使能这一中断向量。实例代码如下:

//配置UART1接收中断void NVIC_Configuration(void){    NVIC_InitTypeDef NVIC_InitStructure;    /* Configure the NVIC Preemption Priority Bits */    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);        /* Enable the USARTy Interrupt */    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    NVIC_Init(&NVIC_InitStructure);}

3.2、中断的服务程序的设计目前使用了UART的两个中断USART_IT_RXNE(接收缓存补空中断)和USART_IT_TXE(发送缓存空中断),前一个中断保证了一旦有数据接收到就进入中断以接收特定长度的数据,后一个中断表示一旦发完一个数据就进入中断函数,保证连续发送一段数据。一个设备的所有中断都包含在一个中断服务程序中,因此必须首先分清楚这次响应的是哪一个中断,使用USART_GetITStatus()函数确定;采用USART_ReceiveData()函数接收一个字节数据,采用USART_SendData()函数发送一个字节数据,当关闭中断时采用USART_ITConfig()失能响应的中断。实例程序:

void USART1_IRQHandler(void){    uint8_t ch;        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)    {        //ch = USART1->DR;            ch = USART_ReceiveData(USART1);     //接受数据          printf( "%c", ch );    //返回打印    }     }

3.3、接收数据函数:

//重定向scanf函数到USART1int fgetc(FILE *f){    /*等待串口1输入数据*/    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);    return (int)USART_ReceiveData(USART1);}

4、 STM32串口在首次发送字符的时候,首字符丢失解决办法网上关于发送字符的代码大多如下:

USART_SendData(USART1, (uint8_t)ch);while( USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);

其实咋一看是说的通的,但是在仔细看手册的时候发现 TC 和 TXE 标志位在复位的时候被置1,这样第一次while循环就是没有用的。这样导致了首次第一个字符还没有被输出,就被后面的字符覆盖掉,造成实际看到的丢失现象。解决办法就很简单:在前面加上一句:USART1->SR;

具体代码如下:

USART1->SR; //USART_GetFlagStatus(USART1, USART_FLAG_TC);USART_SendData(USART1, (uint8_t)ch);while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);

下面我来说说原因: 第一句读取SR寄存器,第二句写DR寄存器 刚好清除了TC标志位 。第一次while循环就起作用了。也可将USART1->SR;替换为USART_GetFlagStatus(USART1, USART_FLAG_TC)。5、补充一直有一个疑问是关于接收和发送数据的问题:对于“hello”这样的字符串是一个一个接收还是整体接收显示,下面的实验可以验证是一个一个进行的。

免责声明:本文来源于网络。版权归原作者所有,如涉及侵权,请联系删除。谢谢。

stm32中断优先级_浅谈STM32串口USART1的使用相关推荐

  1. 浅谈STM32的DMA模块的使用

    浅谈STM32的DMA模块的使用 转自:http://blog.ednchina.com/jack_chang/123085/message.aspx http://article.ednchina. ...

  2. 借WS2812 PWM DMA驱动调试浅谈STM32调试思路

    借WS2812 PWM DMA驱动调试浅谈STM32调试思路 ​ 接触STM32差不多有4年了,在学校参加比赛时也需要进行各种调试工作,团队的配合也需要个人具有领域内快速定位与解决BUG的能力,前些日 ...

  3. **浅谈STM32系列单片机的零基础学习方法**

    浅谈STM32系列单片机的零基础学习方法 *很多朋友想必在零基础学习STM32F1这系列单片机时会感觉无从下手,或者不知道写程序时到底是用库函数好还是寄存器好.* 我个人认为一个零基础的朋友可以通过以 ...

  4. 《计算机辅助教学及应用实践研究》,《论文_浅谈计算机辅助教学(定稿)》

    <论文_浅谈计算机辅助教学(定稿)> (3页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 摘要:计算机辅助教学中要用到多媒体课件 ...

  5. python判断两个对象是否为相等使用的运算符是_Python入门_浅谈逻辑判断与运算符...

    这是关于Python的第6篇文章,主要介绍下逻辑判断与运算符. (一) 逻辑判断: 如果要实现一个复杂的功能程序,逻辑判断必不可少.逻辑判断的最基本标准:布尔类型. 布尔类型只有两个值:True和Fa ...

  6. tcp转串口_浅谈串口转以太网技术

    浅谈串口转以太网技术 1.概述串口转以太网目前可以采用串口转以太网模块来实现,变得非常简单易用,但是在该技术中出现的一些新问题.使用误区需要引起注意.串口转以太网并不是简单传输媒介的变化,而是串口到T ...

  7. python sys模块作用_浅谈Python中的模块

    模块 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在Python中,一个.py文件就称之为一个模块(Mod ...

  8. python的re2和re区别_浅谈Python中re.match()和re.search()的使用及区别

    1.re.match()fvk免费资源网 re.match()的概念是从头匹配一个符合规则的字符串,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None.fvk免费资源网 包含的参数如下: ...

  9. python读取图像数据流_浅谈TensorFlow中读取图像数据的三种方式

    本文面对三种常常遇到的情况,总结三种读取数据的方式,分别用于处理单张图片.大量图片,和TFRecorder读取方式.并且还补充了功能相近的tf函数. 1.处理单张图片 我们训练完模型之后,常常要用图片 ...

最新文章

  1. ApplicationEventPublisherAware--待完善
  2. SimpleAdapter与listview,gridview的组合用法
  3. 嵌入式操作系统内核原理和开发(内存分配算法)
  4. thinkphp删除某一学生_基于ThinkPHP实现批量删除
  5. activemq网络桥接_ActiveMQ –经纪人网络解释–第5部分
  6. Java 并发编程之 FutureTask
  7. Operators一句话介绍(RxJava版)
  8. 平均聚类系数_Python聚类算法的应用实例
  9. neo4j︱Cypher 查询语言简单案例(二)
  10. 【翻译】MobileWeb开发的性能调优技巧
  11. 做柜员还是程序员_未来的程序员,还是“高薪一族”吗?
  12. java时间管理番茄时钟小程序源码
  13. 聚币网API[Python2版]
  14. 网吧管理系统的设计与实现
  15. [封装插件]酒仙网和京东左侧动态菜单栏案例
  16. Thinkpad 笔记本电源状态指示灯
  17. 记录小程序中获取公众号的信息授权实现过程
  18. MacOs 恢复系统后无法更新版本
  19. 美国人日常生活中常用的五星级句子
  20. Android | navigation入门详解

热门文章

  1. Python Tricks(十二)—— 有理数的加法
  2. 身份证号第18位的计算
  3. delphi 获取数组长度_Java中的数组(基础篇六)
  4. python基础知识-python基础知识,python必背内容,一、python的基
  5. python从入门到放弃-学Python方法用错,直接从入门到放弃!
  6. python零基础学习书-Python零基础到进阶必读的书藉:Python学习手册pdf免费下载
  7. python和c++哪个好-Scratch和Python与C++选哪个合适
  8. python怎么读写文件-怎么用python读取和写入TIFF文件1
  9. python编程入门经典-Python编程入门经典PDF文档免费下载
  10. python骗局-如何识破python小课骗局_怎样选择学校呢