一、通信协议的定义
通信是指通信双方的一种约定,包括对数据格式、同步方式、传送速度、传送步骤、检纠错方式等问题作出统一规定。也称通信控制规程。
二、串行通信和并行通信的优缺点
并行通信:
- 传输原理:数据各个位同时传输。
- 优点:速度快
- 缺点:占用引脚资源多
串行通信:
- 传输原理:数据按位顺序传输。
- 优点:占用引脚资源少
- 缺点:速度相对较慢
三、串行通信的通信方式
同步通信:带时钟同步信号传输。(SPI、IIC通信接口)
异步通信:不带时钟同步信号。(USART(通用异步收发器),单总线)
异步串行通信的特点:以字符为信息单位传送。即:传送同一字符的每一位时是同步的,而字符与字符之间是异步的。
同步串行通信的特点:以数据块为信息单位传送。即:字符内部位与位之间传送是同步的,字符与字符之间传送也是同步的。
四、USART帧格式
在异步通信中数据一般以一个字符为单位进行传送。用一帧来表示一个字符,一帧信息由起始位(为0信号,占1位)、数据位(传输时低位在先,高位在后)、奇偶较验位(可要可不要)和停止位(为1信号,可1位、1.5位或2位)组成。
五、波特率及其设置
在串行通信中,数据是按位进行传送的,因此传送速率用每秒钟传送格式位的数目来表示,称之为波特率(band rate)。每秒传送一个格式位就是1波特。1波特=1bps(位/秒)
常用的有: 1200、2400、4800、9600、19200、115200波特。
接收器和发送器的波特率在USARTDIV的整数和小数寄存器中的值应设置成相同的。波特率通过USART_BRR寄存器来设置,包括12位整数部分和4位小数部分。
发送和接收的波特率计算公式为:
波特率 = fPCLKx / (16 × USARTDIV)
其中,fPCLKx(x=1、2)是给外设的时钟,PCLK1用于USART2、3、4、5,PCLK2用于USART1。
USARTDIV是一个无符号的定点数。USARTDIV的计算见下例。
例1:
如果 DIV_Mantissa = 27,DIV_Fraction = 12 (USART_BRR=0x1BC),
则:Mantissa (USARTDIV) = 27;Fraction (USARTDIV) = 12/16 = 0.75,
所以USARTDIV = 27.75。
例2:
要求 USARTDIV = 25.62,
则:DIV_Fraction = 16×0.62 = 9.92。取最接近的整数是:10 = 0x0A。DIV_Mantissa = mantissa (25.620) = 25 = 0x19 。
于是,USART_BRR = 0x19A 。
例3:
要求 USARTDIV = 50.99,
则:DIV_Fraction = 16×0.99 = 15.84。最接近的整数是:16 = 0x10 => DIV_frac[3:0]溢出 => 进位必须加到小数部分。
DIV_Mantissa = mantissa (50.990 + 进位) = 51 = 0x33。
于是,USART_BRR = 0x330,USARTDIV=51。
六、USART初始化(需要设置哪些参数)
初始化步骤:
1、GPIO口初始化;(PA9,PA10)
2、串口时钟设置;打开串口时钟
3、串口初始化;波特率,帧格式
4、串口使能;
5、发送字符;
6、发送字符串;
7、主程序
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TXD
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //RXD
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //浮空输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void Usart_Init(void)
{
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能串口1时钟
USART_InitStructure.USART_BaudRate = 9600;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送使能和接收使能
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
USART_ClearFlag(USART1, USART_FLAG_TC); //清除UASRT1发送完成标志位
}
void USART_Transmit(u8 data)
{
USART_SendData(USART1, data);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
void put_S(u8 *s)
{
while(*s)
{
USART_transmit(*s);
s++;
}
}
int main(void)
{
GPIO_Init();
Usart_Init();
while(1)
{
put_s("CSDN--阿牛哥dd");
put_s("\n");
}
}