我们还是贯彻我们的学习方法
1.什么是串口
2.如何去配置串口
3.串口的具体使用
什么是串口?
串口是异步,全双工,串行通信。
何为异步?
通信双方不在同一个时钟脉冲工作,没有时钟线。
何为全双工?
有两条数据线:发送和接收线;
何为串行?
通过一根线进行一位一位地发送。
谈到通信就不得不说串口的数据帧:起始位(1) 数据位(8) 停止位
接下来我们去查看串口的控制器框图
我们还是通过老办法,分开看
控制器引脚部分:
TX:数据发送口(GPIO口)
RX:数据节后口
CTS:
清除以发送(Clear To Send),n 表示低电平有效。如果使能 CTS 流控制,
发送器在发送下一帧数据之前会检测 nCTS 引脚,如果为低电平,表示可以发送数据,
如果为高电平则在发送完当前数据帧之后停止发送。该引脚只适用于硬件流控制。
RTS:
请求以接收(Request To Send),n 表示低电平有效。如果使能 RTS 流控制,
当 USART 接收器准备好接收新数据时就会将 nRTS 变成低电平;当接收寄存器已满时,
nRTS 将被设置为高电平。该引脚只适用于硬件流控制
, 这是串口控制器的收发寄存器,我们在实际的使用时不分TDR和RDR,收发使用DR,即对DR赋值或者读取DR的值就能实现读写。
控制器内部具体的寄存器,我们可以通过查看框图,根据需要来配置该控制器。
波特率寄存器:因为是异步通信,通信双方设备没有用同一时钟,所以双方要约定好相同的数据传输速度,对总线提供的时钟分频达到需要的频率。
波特率计算公式:
Tx/Rx 波特率 = fCK/(8*(2-OVER8)*USARTDIV)
fCK :总线提供的时钟
OVER8 : 过采样
USARTDIV:要往波特率寄存器里写的值
串口控制器初始化配置函数
{
IO口控制器配置--复用
某个串口控制器配置
}
串口发送一个字节数据函数
{
等待之前的数据发送完成(等待状态寄存器的发送完成位置1)
要发送的数据赋值给数据寄存器
}
串口接收一个字节数据函数
{
等待数据接收完成(等待状态寄存器中的接收完成位置1)
将数据寄存器的值赋值给一个变量;
返回这个变量
}
以下为具体代码:
#include "stm32f4xx.h" // Device header
#include "stdio.h"
/***********************************************
*函数名 :Usart_Init
*函数功能 :串口控制器初始化配置
*函数参数 :u32 band
*函数返回值:无
*函数描述 :USART1--TX---PA9
USART1--RX---PA10
************************************************/
void Usart_Init(u32 band)
{
//IO口配置
//IO口时钟使能
RCC->AHB1ENR |= (1<<0);
//端口模式寄存器--复用功能
GPIOA->MODER &= ~((3<<18)|(3<<20));
GPIOA->MODER |= ((2<<18)|(2<<20));
//输出类型寄存器
GPIOA->OTYPER &= ~(1<<9);
//输出速度寄存器--2m
GPIOA->OSPEEDR &= ~(3<<18);
//上下拉寄存器
GPIOA->PUPDR &= ~(3<<18)|(3<<20);
//复用功能寄存器--H
GPIOA->AFR[1] &=~(15<<4);
GPIOA->AFR[1] |= (7<<4);
GPIOA->AFR[1] &=~(15<<8);
GPIOA->AFR[1] |= (7<<8);
//串口控制器配置
//时钟使能
RCC->APB2ENR |= (1<<4);
//波特率配置
USART1->BRR=84000000/band;
//控制器1配置
USART1->CR1 &= ~(1<<15);
USART1->CR1 &= ~(1<<12);
USART1->CR1 |=(1<<3);
USART1->CR1 |=(1<<2);
//控制器2配置
USART1->CR2 &= ~(3<<12);
//串口使能
USART1->CR1 |=(1<<13);
}
/***********************************************
*函数名 :Usart_Rec
*函数功能 :串口接收数据函数
*函数参数 :无
*函数返回值:u8
*函数描述 :
************************************************/
u8 Usart_Rec(void)
{
u8 data;
while((USART1->SR & (1<<5))==0);
data =USART1->DR;
return data;
}
/***********************************************
*函数名 :Usart_Sen
*函数功能 :串口发送数据函数
*函数参数 :u8 data
*函数返回值:无
*函数描述 :
************************************************/
void Usart_Sen(u8 data)
{
while((USART1->SR & (1<<6))==0);
USART1->DR=data;
}
/***********************************************
*函数名 :Usart_Sen_Str
*函数功能 :串口发送字符串函数
*函数参数 :u8 *str
*函数返回值:无
*函数描述 :
************************************************/
void Usart_Sen_Str(u8 *str)
{
while((*str)!='\0')
{
Usart_Sen(*str);
str++;
}
}
/***********************************************
*函数名 :Usart_Rec_Str
*函数功能 :串口接收字符串函数
*函数参数 :u8 *str
*函数返回值:无
*函数描述 :
************************************************/
void Usart_Rec_Str(u8 *str)
{
while(1)
{
* str=Usart_Rec();
if(*str=='#')
{
break;
}
str++;
}
*str='\0';
}