目录
基于正点原子stm32-min板进行学习。
背景知识
串口是一种串行通信协议,常用于微控制器、传感器、无线模块等设备之间进行通信。的线数据帧格式通常由起始位、数据位、校验位和停止位组成。简单双向串口通信有两根通信线(发送端TX和接收端RX),和其他设备通信时TX与RX要交叉连接。USART是stm32内部集成的硬件外设,自动对发送数据进行数据帧时序生成,从TX引脚发送出去。也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器中。低位先行,数据转化成8为2进制数据后,从低位开始发送/接收。
优点:
- 占用资源少,仅适用两根线
- 异步通信,无需使用时钟信号
- 具有奇偶检验位以允许进行错误检查
缺点:
- 不支持多个设备间通信
- 串口双方的波特率必须在彼此的10%以内
基本属性说明
其中校验位分为奇校验和偶校验:如果选择了奇校验,校验位被设置为使得整个数据帧(包括数据位和校验位)中“1”的数量是奇数。如果数据位中“1”的数量已经是奇数,那么校验位被设置为 0;如果数据位中“1”的数量是偶数,那么校验位被设置为 1,以确保整个数据帧中“1”的总数为奇数。偶校验反之。(一般选择无校验)
数据传输流程
配置流程
- 配置串口对应gpio口
- 创建USART_InitTypeDef结构体
- 使能串口时钟:除了使能gpio时钟还要使能对应外设时钟
- 配置串口基本属性
- 串口初始化:USART_Init()
- 使能串口:USART_Cmd()
- 配置串口中断:一般通过中断接收数据
- 开启串口接收中断:USART_ITConfig()
使用流程
代码
1.串口通信,将设备发送的数据发送回去。
main.c
#include "stm32f10x.h"
//#include "led.h"
#include "delay.h"
//#include "key.h"
void my_usart(u32 bound){
GPIO_InitTypeDef GPIO_InitStructure;//创建gpio初始化结构体
USART_InitTypeDef USART_InitStructure;//创建串口初始化结构体
NVIC_InitTypeDef NVIC_InitStructure;//创建中断配置结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);//串口1使用PA端口,使能PA口时钟和串口时钟
//PA9初始化
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//PA9,串口1 TX引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//频率为50mhz
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化PA9
//PA10初始化
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//PA10,串口1 RX引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化PA10
//串口初始化
USART_InitStructure.USART_BaudRate=bound;//设置波特率
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//关闭硬件流控制
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//及接受又发送
USART_InitStructure.USART_Parity=USART_Parity_No;//不需要校验位
USART_InitStructure.USART_StopBits=USART_StopBits_1;//停止位为1位
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//数据位为8位
USART_Init(USART1,&USART_InitStructure);//初始化串口1
USART_Cmd(USART1,ENABLE);//使能串口1
//中断初始化
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级为3
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//子优先级为3
NVIC_Init(&NVIC_InitStructure);//初始化中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收寄存器非空中断
}
u8 USART1_RX_BUF[100];//存储串口接收数据
u8 USART1_TX_BUF[100];//存储串口发送数据
u8 USART1_RX_STA=0;//接收数据状态记录
//串口中断函数
//将接受到的数据返回回去
void USART1_IRQHandler(void)
{
u8 res;
if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET){//接受到数据
res=USART_ReceiveData(USART1);//记录串口1接受到的数据
USART_SendData(USART1,res);//将数据发送回去
}
}
int main(void)
{
my_usart(115200);//串口初始化,波特率为115200,进行串口通行设备波特率也必须为115200
delay_init();//延时初始化
while(1)
{
}
}
注意将自带的串口1中断服务函数注解掉,否则会报重复定义错误。
注解的时候别把最后一个#endif注解了
否则报错