串口介绍
串口:全称串行接口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口 (Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。
STM32的串行通信接口:
1.UART:通用同步收发器。
2.USART:通用同步异步收发器。
(大容量STM32F10x系列芯片包含两个UART与三个USART)
USART概述
USART框图:
相关初始化:
typedef struct
{
uint32_t USART_BaudRate; //波特率设置
uint16_t USART_WordLength;//数据字长
uint16_t USART_StopBits;//停止位
uint16_t USART_Parity;//奇偶位校验
uint16_t USART_Mode;//模式(发送或接收)
uint16_t USART_HardwareFlowControl; //硬件流控制
} USART_InitTypeDef;
奇偶校验位:偶校验:输送的8位数据的1如果为偶数则为0,奇数为1。(使1为偶数)
奇校验:输送的8位数据的1如果为奇数则为0,偶数为1。(使1为奇数)
作用:提高数据传输的准确性。
波特率:每秒钟传送的码元符号的个数,它是对符号传输速率的一种度量,它用单位时间内载波调制状态改变的次数来表示,1波特即指每秒传输1个符号。(一个数字脉冲就是一个码元,如‘1’,'0’各是一个码元)
通信方式
按输送位数
1.并行通信:数据各个位同时传输(速度快但占用引脚多)。
2.串行通信:数据按位顺序传输(速度慢但占用引脚少)。
按传输方向
1.单工:只支持数据单方向传输。
2.半双工:允许数据双向传输,但同一时刻数据只能往一个方向传输,即方向可改变的单工通信。
3.全双工:允许数据同时在两个方向上传输。
按传输有无时钟
1.同步通信:带时钟同步信号传输(SPI,IIC通信接口)。
在约定的通信速率下,发送端和接收端的时钟信号频率始终保持一致(同步),保证了通信双方在发送和接收数据时具有完全一致的定时关系。
2.异步通信:不带时钟同步信号(UART通用异步收发器,单总线)。
同步通信与异步通信区别:
1.同步通信要求接收端时钟频率和发送端时钟频率一致,发送端发送连续的比特流;异步通信时不要求接收端时钟和发送端时钟同步,发送端发送完一个字节后,可经过任意长的时间间隔再发送下一个字节;
2.同步通信效率高,异步通信效率较低。(异步通信必须在每一个字符的开始和结束的地方加上标志,即加上开始位和停止位);
3.同步通信较复杂,双方时钟的允许误差较小;异步通信简单,双方时钟可允许一定误差;
4.同步通信可用于点对多点,异步通信只适用于点对点。
USART初始化步骤
1.串口时钟使能,GPIO时钟使能;
2.GPIO端口模式设置;
3.串口参数初始化;
4.开启中断并初始化NVIC;(若开启中断)
5.使能相应串口;
6.编写中断处理函数;
7.串口数据收发及传输状态获取。
例:
void MY_USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStrue;//相应结构体初始化
USART_InitTypeDef USART_InitStrue;
NVIC_InitTypeDef NVIC_InitStrue;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能串口时钟
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;//GPIO9的初始化
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStrue);
GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//GPIO10的初始化
GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStrue);
USART_InitStrue.USART_BaudRate=115200;//初始化串口相关参数
USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//使能发送与接收
USART_InitStrue.USART_Parity=USART_Parity_No;//取消奇偶校验
USART_InitStrue.USART_StopBits=USART_StopBits_1;
USART_InitStrue.USART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_InitStrue);
USART_Cmd(USART1,ENABLE);//使能串口
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//串口一中断函数:接收中断
NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;//确定通道
NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;//开启上述通道
NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;//设置抢占优先级
NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;//子优先级
NVIC_Init(&NVIC_InitStrue);//优先级初始化
}
void USART1_IRQHandler(void)//中断处理函数
{
u8 sju;
if(USART_GetITStatus(USART1,USART_IT_RXNE))//如果接收到数据
{
sju=USART_ReceiveData(USART1);//读该串口的数据
USART_SendData(USART1,sju);//把数据发送出去
}
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//系统优先级分组设置为2
MY_USART1_Init();
while(1);
}
附串口操作相关库函数:
void USART_Init();//串口初始化
void USART_Cmd();//使能串口
void USART_ITConfig();//使能相关中断
void USART_SendData();//发送数据到串口
uint16_t USART_ReceiveData();//接收数据
FlagStatus USART_GetFlagStatus();//获取状态标志位
void USART_ClearFlag();//清除状态标志位
ITStatus USART_GetITStatus();//获取中断状态标志位
void USART_ClearITPendingBit();//清除状态标志位
不成熟的小建议
串口通信这方面的知识不只是一个例程能够展现出来的,其中存在许多信息处理方面的知识,可以先大概了解串口通信的各个概念,将例程粗略看一遍,不太建议在一开始便深入研究。