技术交流QQ群【JAVA,C++,Python,.NET,BigData,AI】:170933152
SR寄存器主要是,串口的一些状态,比如接收到的数据什么的.
然后DR寄存器,
这个DR寄存器,比如要发送数据了,首先要把数据写入到这个DR数据寄存器中
然后如果要接收数据了,也要首先把数据存入这个DR寄存器,然后再从这个寄存器中读取数据.
BRR寄存器,用来设置一些波特率的一些设置.
这里先看这个SR状态寄存器的位5,这个作用是比如,对于RX接收数据来说,当RDR移位寄存器中的
数据被转移到了USART_DR寄存器中,那么这个位就会被置1,表示,已经接收到完整的数据了.MCU可以去读取数据了.
然后看一下这个TC发送完成这个位.设置为1,就是发送完成了.
其他的位也可以看看,SR寄存器是状态位.
这个DR寄存器,数据寄存器,如果发送数据的话,就去写入数据就可以了.
如果接收数据就读取这个就可以了.
有8位数据位,可以看到.
这个BRR寄存器,这个用到了低16位,这个16位,就记录了上面说的产生时钟源的时候分频规则,
0到3位定义了小数部分的分频,4到15位定义了整数部分的分频.
上面也说过.时钟源产生的时钟,实际上也就是PCLK1和PCLK2
注意,这里的时钟来源,对于STM32F103系列,这个串口的时钟来源,
串口1 UART1的时钟来源于PCLK2
串口2-4的时钟来源是PCLK1
这里对应的时钟产生时钟频率以后,再根据这个BRR寄存器来实现分频功能.
这个分频和小数整数,怎么实现的,后面会说.
这里的波特率怎么算,是这样的:
PCLK2前面说,可以产生72m的时钟,然后这个72m的时钟,72后面6个0,然后
因为上面的公式,就是波特率=PCLK2的时钟/(16*USARTDIV)的分频,这样的话
USARTDIV的分频,具体就可以算出来就是,比如这里如果波特率是115200那么
72000000/(115200*16)这样就可以算出来,这个USARTDIV了.
然后这里就把对应的计算出来的值,设置给BRR寄存器就可以了,要把整数位和小数位分别设置.
然后看一下代码实现.
再这之前,先看一下这个CR1寄存器.
这个CR1寄存器,可以进行一些位的使能.
然后还有发送完成使能,中断使能,也就是发送完成以后会产生中断.
发送缓冲区中断使能,这个部分的使能,上一课也说过.
然后看函数,这里主要是分三组,一组是获取状态标志位,然后一组是串口的舒适化使能,中断等.
然后还有中间的是发送数据,接收数据.
打开一个串口实验的代码看看
找到串口的头文件.看看里面有刚说到的函数.
接下来主要看上面第二行的USART_Init这个函数.
这里看这个函数,第一个参数是串口的标号比如哪个串口,第二个是初始化的一个结构体,去看
这个结构体.
这个结构体,第一个是USART_BaudRate这个是波特率的设置.
第二个USART_WordLength这个是字长,比如这里说过的用8位来传输数据
然后第三个USART_StopBits是停止位,前面说过
然后第四个USART_Parity是奇偶校验位,是奇校验,还是偶校验,还是不使用等.
然后第五个USART_Mode是这个发送接收使能mode,我们要打开发送使能,接收使能,还是只打开一个,还是都打开.
等等
然后最后一个是USART_HardwareFlowControl这个是硬件流控制,这个咱们没有用到.
这个步骤:
NVIC_Init(); 初始化优先级,先设置优先级模式,选择优先级分组什么的
USART_ITConfig(); 然后还要设置具体要调用什么中断等,确定开启哪一个中断
⑥使能串口:USART_Cmd();
⑦编写中断处理函数:USARTx_IRQHandler();
上面步骤完了以后就要编写中断服务函数.
⑧串口数据收发:
然后就可以进行串口数据发送接收的方法调用了.
void USART_SendData();//发送数据到串口,DR
uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
⑨串口传输状态获取:
比如这里产生了一个中断,那么这个可以获取到对应的标志位来进一步检查一下看看到底是不是这个标志位.
可以做个检查.
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
先看一下硬件的连接,可以看到这里PA9,PA10,是连接到芯片对应的引脚的.
然后还有两个跳线帽,把这个PA9,PA10的发送,接收,连接到了下面的一个电路
实际上下面电路的功能就是把这个PA9,PA10的串口TTL电平,转换为USB的电平信号,
以便可以连接电脑.
可以看到发送接收,连接到了这个USB的串口电路.以便连接到电脑
3
如果电脑上安装了这个CH340这个串口驱动的话,那么这个USB的接口,就会被虚拟出一个串口出来,
就把这个USB口当成串口用.
然后写一个简单的串口通信实例:
然后这里,用template这个案例进行继续写.
首先做步骤1到6.
首先使能串口
这里这个过程我们自己写个函数.
然后首先1.使能GPIOA
然后2.使能这个USART1这个串口功能.
然后上面写的那个串口复位就先不用管了.
然后第三步,设置GPIO口的模式,设置为复用
这里,第三步的代码,就是首先要声明IO口,初始化的结构体,然后
再初始化这个结构体,然后初始化这个PA9,PA10就可以了.
对应的设置,也可以去查文档.
注意这里要注意,这个,这里有输入,有输出,所以这类这个除了设置推挽复用输出模式之外,还要设置输入模式
可以看到这个PA10是接收,也就是输入,要设置为浮空输入模式.这样IO口的初始化就写完了.
然后再写串口的初始化
可以看到用USART_init这个函数初始化,
首先设置波特率,然后设置硬件流,这个硬件流,可以去定义里面去看,可以设置不使用硬件流
然后模式,设置为可以发送,也可以接收模式,
然后奇偶校验,设置为不使用奇偶校验.
然后停止位用1个停止位.
数据长度,这个因为,咱们不用奇偶校验位,所以这里设为在
那么也就是0到7位是数据位,就设置为8bit了.
然后这样的话,就初始化了这个串口.
然后再去使能这个串口
去使能串口的这个函数中去看看
实际上用的是这个USART_Cmd来使能这个串口
实际上如果 不使用中断的话,那么这个使能就算完成了.到这里.
然后再看一下这个中断优先级,用下面这个函数来配置,前面有说过.
下面再去设置这个优先级分组
优先级分组设置为2
然后再去配置中断去.
这里这个中断配置,可以去定义,第一个是配置哪个中断,这里配置USART1的中断,然后
第二个是配置为中断的类型,这里配置为也就是只要有数据接收,就会产生中断,第三个是开启使能.
然后再去配置中断优先级,这里
可以看到用这个函数NVIC_Init来配置,
第一个参数是通道.
类似前面一课说的那样配置就可以
然后再去写中断服务函数,
注意这个中断函数为什么要是这个名字呢,因为这个是提前定义好的,也就是
只有这样写,才能被系统调用.
可以在启动文件中有定义好的.
然后咱们去写一个简单中断函数,可以看到这里:
USART1_IRQHandler(void){
}
这个函数:
void USART1_IRQHandler(void)
{
u8 res;
if(USART_GetITStatus(USART1,USART_IT_RXNE))//1.首先这里是判断得到寄存器的状态
//判断这个是不是USART1,的接收引脚已经置1了,做个判断
{
//2.判断以后就可以来接收数据了,这里先接收数据然后把接收的数据发送出去.
res= USART_ReceiveData(USART1);
USART_SendData(USART1,res);
}
}
另外:
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//1.设置优先级分组规则
My_USART1_Init();//调用串口初始化.
while(1);//3.这里写个死循环,就是让程序一直执行等待.
//当串口有数据接收到的时候,他就会自己去执行这个中断
//去发送数据这样.
}
//1.再main函数中,首先定义这个串口的初始化
还有个需要注意的,因为这个串口初始化函数,可以作为一个共通函数
在System文件夹中定义了这个函数了已经.,
那么如果自己写的main.c中又定义了肯定是会冲突的,所以这个时候
可以战时把usart.c这个文件删除掉.
删除掉以后,可以编译一下,
然后打开串口调试助手,XCOM
打开xcom选择里面的这个USB这块 CH3400这个开发版.
可以看到首先要连接上usb到电脑,然后电脑上需要安装CH3400的驱动,串口驱动.
然后:
可以看到开发版没有反应.
这个时候
再去配置一下XCom调试助手.
可以看到,代码中的设置,要跟xcom中的设置要是对应的才行.
可以看到波特率都是115200
然后停止位都是1,数据位都是8,奇偶校验也一样都是,没有奇偶校验
可以看到这个时候:在上面的黑屏的部分,他显示的是
当串口收到什么数据的时候,这个黑屏就会显示对应的内容,所以
这里我通过这个串口发送A,那么上面就显示了A,也就是指的是我们的程序生效了,跟咱们写的代码
是一致的.
接收到什么就从这个串口发出去.