比特138

 找回密码
 立即注册
搜索
查看: 28|回复: 0

stm32寄存器版USART 配置笔记

[复制链接]

485

主题

485

帖子

104

积分

初级会员

Rank: 2

金币
104
发表于 2020-5-24 17:40:28 | 显示全部楼层 |阅读模式
USART的模式功能有很多本次配置的是最初级的模式,将数据发送到电脑串口助手上,以便于程序的调试.今日写下配置步骤,以及调试的经验总结.
配置分为三个模块,一者GPIO
二者USART
三者printf输出重定向函数
硬件连接(PA9/TX,PA10/RX)

GPIO模块
首先不仅要有个疑问,为何USART模块不是GPIO模块,也不用点亮LED灯,为什么要配置他那.原因很简单,因为虽然不用GPIO点灯,却需要RX,TX与外部通信,也就是GPIO引脚不是普通的GPIO了,而是连接到USART的复用功能的引脚了.所以只要是内部外设需要与芯片外步连接的话就需要GPIO配置成复用功能.
   具体来讲只要用到了GPIO模块就需要先将GPIO的时钟打开.接下来才可以具体配置引脚.配置引脚配置哪个引脚?上一段说了,GPIO可以用到通用功能用来电灯等操作,还可以作用复用功能如USART,SPI等功能.不仅如此不要小看看这小小的芯片.USART等外设对应(连接)着自己的固定的引脚,而且不是固定的一个,根据引脚的多少不同可能对应着两个三个甚至四个,这便是STM32的重映射功能.查看手册USART1可用外部连接有(PA9/TX,PA10/RX),(PB6/TX,PB7/RX).
C8T6只有两个,F411有三个,这样一来就为PCB电路设计提供了方便.当然这个外设就需要要有个控制器去选择到底将USART模块映射到哪里.这个控制额模块就是AFIO模块.所以复用的时候需要查看是否重映射了,如果是的话,要将其配置好.
以上两段说了三个关键词,通用GPIO的通用,GPIO的复用,GPIO的重映射.还有配置的两个步骤一打开GPIOA或者B...的时钟,二确定是否重映射,确定好硬件连接.
接下来便是配置具体的引脚.
本次USART1有两个,选择了(PA9/TX,PA10/RX),确定了功能之后,要配置成输入模式还是输出模式当然也已经确定好了.但是输入有浮空输入,模拟输入,上拉下拉到底选哪一个(输入模式没有复用功能的选择),这个数据手册里每一个外设模块有,输出也有.可以查看.至于速度的话,一般通信的引脚配置成最大的输出速度,通用GPIO的时候配置成最小的速度即可,根据实际情况来.
这样一来GPIO模块就配置完成,配置的具体的代码如下
  1. {
  2.         RCC->APB2ENR |=(1<<2); //开启GPIOA的时钟
  3.         AFIO->MAPR &=~(1<<2); //UART1没有重映像(TX/PA9,RX/PA10)

  4.         GPIOA->CRH |= (3<<4); //PA9配置为50MHz输出模式
  5.         GPIOA->CRH |=(2<<6); //复用推挽输出模式

  6.         GPIOA->CRH &= ~(3<<8); //PA10配置为输入模式
  7.         GPIOA->CRH |=(1<<10); //浮空输入模式模式
  8. }
复制代码
接下来就是配置USART模块了,与GPIO模块一样也需要先打开USART1的时钟,与GPIO模块不同的是USART模块在最后配置完成后还需要有个模块使能.在配置完USART模块的所有功能后需要将它使能.在我看来这是没有必要的.时钟都打开了,已经说明我要用这个模块了,为什么还要使能这个模块那,有些多余.,技术手册上写的是清零USART的输出和分频器禁止.分频器禁止了,难道输入还可以.我要试一试.如果可以的话,不算鸡肋,否则就是无用;
一头一尾的两条语句说完,接下来就是USART的具体配置了.USART是同步异步通信,这里的功能用到的是全双工的异步通信方式.所以没有用到是时钟,只需要两根线就可以把实现他的通信.
其配置的步骤与其通信的格式有关.如数据位,校验位,停止位的位数,还有发送和接收使能.还有波特率(计算.需要花费点功夫),具体代码如下.
  1. void USART1_Init(uint32_t bound)
  2. {
  3.   float temp;
  4.         u16 mantissa;
  5.         u16 fraction;

  6.         USART1_GPIO_Config();

  7.         RCC->APB2ENR |=1<<14;//开启UART1的时钟

  8.         USART1->CR1 &= ~(1<<12);//一个起始位八个数据位
  9.         USART1->CR1 &= ~(1<<10);//禁止校验位
  10.         USART1->CR2 &= ~(3<<12);//一个停止位

  11.         USART1->CR1 |=(1<<2);//接收使能
  12.         USART1->CR1 |=(1<<3);//发送使能

  13.         temp=(float)(72*1000000)/(bound*16);        
  14.         mantissa=temp;                                                         
  15.         fraction=(temp-mantissa)*16;                 
  16.         mantissa<<=4;
  17.         mantissa += fraction;
  18.         USART1->BRR=mantissa;  //设置波特率         

  19.         USART1->CR1 |= 1<<13;//使能USART模块
  20. }
复制代码
至于重定向函数,上网上找到函数,只需要把库函数改成寄存器函数即可,本质就是,printf调用fputc函数的时候,fputc把输出的位置不定义到电脑屏幕,而是改变这个函数,把printf要输出的的字符通过串口发送出去,打印到串口助手的屏幕上去.如下.
  1. int fputc(int ch, FILE *f)
  2. {

  3.         USART1->DR = (unsigned char) ch;
  4.         while((USART1->SR &(1<<7))==0);
  5.         return(ch);
  6. }
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|比特138 |网站地图

GMT+8, 2020-9-29 01:45 , Processed in 0.025887 second(s), 7 queries , Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表