目录
通信方式
硬件电路
软件部分
USART外设(同步/异步收发器)
波特率
引脚复用
初始化基本流程
发送
接收
语言简述
常用的函数
使用的结构体
引脚模式
打印数据的三种方法
使用printf
在实际的串口中,只能发送二进制数,也就是十六进制的最直接数据。如果想发送字符,就需要一个数据->字符的映射表(如ASCII表)
通信方式
全双工:两根线,数据的发送和接收互不影响。
半双工:一根线,一发一收。
单工:数据只能从一个设备到另一个设备。
举例子->
全双工:打电话。半双工:对讲机。单工:广播
有时钟线,同步通信
无时钟线,异步,甚至需要添加帧头帧尾使数据对齐。
单端信号(电平):它们引脚的高低电平都是对GND的电压差,所以单端通信的双方都必须共地,就是把GND接到一起。
而差分信号则不用。
硬件电路
TX、RX、GND是必须要接的,而VCC若两个设备都有独立供电,可以不接。
使用TTL电平。
软件部分
俩种形式
有校验位就是9位数据位,没有就是8位。
数据低位先行
预发送数据 0x0f (H)0000 1111(L)
L->H
检验位采用奇偶校验的方法(如果数据错了可以丢弃或者重传)
校验3法 : 无校验 奇校验 偶校验
- 无校验 如1帧10位 没有校验位
- 奇校验 包括校验位会出现奇数个1
- 偶校验 包括校验位会出现偶数个1
如 奇校验 0000 1111 总共4个1,于是校验位就会补一个1,保证其是奇数。
奇偶校验只能保证一定程度上的验出率,更高级还是得了解CRC校验。
USART外设(同步/异步收发器)
【注意】USART1是挂在APB2总线上的,而其他是在APB1总线上的。
STM32F103C8T6 USART资源 :USART1(APB2)、USART2、USART3(APB1)
开启时钟的时候需要控制。
波特率
波特率发生器就是分频器,APB时钟进行分频,得到发送和接收移位的时钟。
USART1挂载在APB2【中文参考手册---系统架构】,所以就是PCLK2的时钟,一般是72M。其余的是APB1,也就是36M。
然后进行分频。晶振除以一个USARTDIV的分频系数,分频完之后还要再除以16
引脚复用
初始化基本流程
参考中文手册USART部分
发送
接收
语言简述
- 开启外设,开启时钟,把需要用的USART和GPIO的时钟打开
- GPIO初始化,把TX配置成复用输出,RX配置成输出
- 配置USART,直接使用一个结构体
- 如果只需要发送功能,直接开启USART初始化就结束了。如果还需要接收还需要开启中断。在开启中断之前,再加上ITConfig和NVIC的代码。
常用的函数
使用的结构体
USART_InitTypeDef、
USART_ClockInitTypeDef【同步时钟,但是我们一般使用的是异步通信,所以不怎么用】
引脚模式
TX是USART外设控制输出脚,所以选择复用推挽输出(GPIO_Mode_AF_PP);
RX是USART外设数据输入脚,所以选择输入模式。输入模式并不分什么普通输入、复用输入,一根线只能有一个输出,但可以有多个输入。所以输入脚外设、GPIO都可以使用。RX一般是浮空输入or上拉输入。因为串口波形空闲状态是高电平,所以不采用下拉输入。
void USART_Config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//GPIO配置控制
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //RX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//USART配置控制
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStructure);
//接收使能,接受不为空的时候产生中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//NVIC配置控制
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1, ENABLE);
}
ctrl+alt +space 开启联想
打印数据的三种方法
1、printf
2、sprintf
3、封装sprintf(进阶学习--->C语言可变参数)
使用printf
还要进行重定向导入 stdio.h
printf->单。意思是只有一个串口可以使用。
sprintf->多。可以指定打印位置,不涉及重定向的东西。
格式+内容。 文章来源:https://www.toymoban.com/news/detail-528909.html
MicroLIB是keil为嵌入式平台优化的精简库,在keil里面使用printf函数要使用这个,然后还需要重定向,将怕printf函数打印的东西输出到串口。先include ->stdio.h,然后重写fputc(这个是printf的底层)文章来源地址https://www.toymoban.com/news/detail-528909.html
到了这里,关于串口通信-发送和接收数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!