1.1串口通信(Serial Communications)是一种按位(bit)发送和接收字节的通信方式。
如图可知,串口通信起始位,停止位分别是一个低电位,一个高电位
数据位可以是八位或者九位
校验位可以是0.5,1,1.5,2位
所以数据位简略为以下四种情况
1.无校验位,D0~D7,共8Bits=1Byte
2.有校验位,D0~D7+校验位,共8Bits=1Byte
3.无校验位,D0~D8,大于(8Bits=1Byte)
4.无校验位,D0~D6,小于(8Bits=1Byte)
1.2奇偶校验
我们以奇校验,一个校验位为例发送85(0101 0101)与情况2相同
发送方算上校验位有奇数个1,则校验成功进行发送;接收方在接收过程中数据位有个1变成了0,则算上校验位有偶数个1,则PE标志位(下文会提)会进行报错.
2.1USART模块:是一种支持同步和异步通信的串行通信接口。它通过串行数据传输实现设备间的数据交换。
2.2串、并行发送
串行发送:移位数据寄存器一个字一个字地发送数据
并行发送:移位数据寄存器一次性地发送一段数据
2.3USART波特率的设置方法、
通过控制波特率寄存器的(BRR)写值控制波特率
串口初始化引脚
3.1.1重映射
先通过数据手册查到串口收发引脚分别为PA9\PA10
查阅参考手册第8.3章得到
REMAP=0,不进行重映射;REMAP=1,进行重映射。
3.2.1配置表
查阅参考手册第8.1.11节得
几种工作模式的理解如下4.4
4.1.1串口发送数据
4.1.2TXE标志位:用于判断发送数据寄存器是否为空
注:发送数据寄存器——TDR
4.1.3TC标志位:用于判断发送是否完成
5.1.1串口接收数据
5.2.1RXNE标志位:用于判断接收数据寄存器是否为空
数据寄存器:RDR
5.3.1PE标志位:检查数据是有校验错误
5.4.1FE标志位:检查单个数据字,是否有效(常见的检查为检查不到停止位)
5.5.1NE标志位
5.6.1ORE标志位:检查传输数据是否过多
以下是通过串口控制PC13LED小灯亮灭的代码示例(main.c部分)
#include "stm32f10x.h"
void My_OnBoardLED_Init(void);
void My_USART1_Init(void);
int main(void)
{
My_USART1_Init();
My_OnBoardLED_Init();
while(1)
{
//#1.等待接收数据寄存器非空
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);
//#2.把数据从接收数据寄存器里读出来
uint8_t byteRcvd = USART_ReceiveData(USART1);
//#3.对数据进行处理
if(byteRcvd ==0)
{
GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);//亮灯
}
else if(byteRcvd ==1)
{
GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_RESET);//灭灯
}
}
}
//1简介:通过串口发送多个字节
//2参数 USARTx:填写串口名称
//3参数 pData:要发送的数据
//4参数Size:要发送数据的数量,单位是字节
//void My_USART_SendBytes(USART_TypeDef *USARTx,uint8_t *pData,uint16_t Size)
//{
// for(uint32_t i=0;i<Size ;i++)
// {
// while(USART_GetFlagStatus(USART1 ,USART_FLAG_TXE )==RESET);
// USART_SendData(USART1,pData[i]);
// }
// while(USART_GetFlagStatus (USART1,USART_FLAG_TC)==RESET);
//}
//1简介:对USART1进行初始化
// PB6 - TX, PB7 - Rx
// 115200,8,1,None,双向
//
void My_USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//#1,开启GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//#2.初始化IO引脚,PC13 通用输出推挽模式 2MHz
USART_InitTypeDef USART_initstruct = {0};
USART_initstruct.USART_BaudRate =115200;
USART_initstruct.USART_Mode =USART_Mode_Tx |USART_Mode_Rx ;
USART_initstruct.USART_WordLength = USART_WordLength_8b ;
USART_initstruct.USART_StopBits =USART_StopBits_1 ;
USART_initstruct.USART_Parity =USART_Parity_No ;
USART_Init(USART1 ,&USART_initstruct);
// GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd (RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig (GPIO_Remap_USART1,ENABLE);
//PB6
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStruct.GPIO_Pin =GPIO_Pin_6;
GPIO_InitStruct.GPIO_Mode =GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed =GPIO_Speed_10MHz;
GPIO_Init (GPIOB,&GPIO_InitStruct);
//PB7
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStruct.GPIO_Pin =GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode =GPIO_Mode_IPU;
GPIO_Init (GPIOB,&GPIO_InitStruct);
USART_Cmd(USART1,ENABLE);
// uint8_t bytestosend[]={1,2,3,4,5};
// My_USART_SendBytes(USART1,bytestosend ,5);
}
void My_OnBoardLED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStruct.GPIO_Pin =GPIO_Pin_13;
GPIO_InitStruct.GPIO_Mode =GPIO_Mode_Out_OD ;
GPIO_InitStruct .GPIO_Speed =GPIO_Speed_2MHz ;
GPIO_Init(GPIOC,&GPIO_InitStruct);
GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);
}