找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2787|回复: 0
打印 上一主题 下一主题
收起左侧

stm32寄存器版USART 配置笔记

[复制链接]
跳转到指定楼层
楼主
ID:677275 发表于 2020-4-26 20:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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模块就配置完成,配置的具体的代码如下
void USART1_GPIO_Config()
{
        RCC->APB2ENR |=(1<<2); //开启GPIOA的时钟
        AFIO->MAPR &=~(1<<2); //UART1没有重映像(TX/PA9,RX/PA10)

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

        GPIOA->CRH &= ~(3<<8); //PA10配置为输入模式
        GPIOA->CRH |=(1<<10); //浮空输入模式模式
}

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

void USART1_Init(uint32_t bound)
{
  float temp;
        u16 mantissa;
        u16 fraction;

        USART1_GPIO_Config();

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

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

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

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

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




int fputc(int ch, FILE *f)
{

        USART1->DR = (unsigned char) ch;
        while((USART1->SR &(1<<7))==0);
        return(ch);
}


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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