USART(上)
1、串口通信
1.1、简介
通过串口接收/发送数据。其中串口拥有TX(发送数据)和RX(接收数据)引脚。2个设备通过串口接收/发送数据时,这2个引脚需要交替连接。
1.2、数据帧
1.2.1、简介
串口接收/发送的数据是以数据帧进行传输的,那什么是数据帧呢?数据帧 = 起始位+数据位+停止位。起始位是低电平0,停止位是高电平1,而数据位可以是8位/9位。其中数据位中还包含1位校验位(有程序员自己规定)。而传输的时候是先传输数据帧的低位,在传高位。
数据进行传输时,如果不是连续传输时,则2个数据帧之间还有空闲位,它为高电平。
1.2.2、校验规则
校验规则分为:奇校验和偶校验,就是查询1的个数。
例如:发送方设定为奇校验,并且是9位数据位。当发送时,前8位数据位中有偶数个1,那么最后1位校验位则是1,这样就凑成了奇数个1。如果传输时出现了错误,接收方进行校验时,则检测到了偶数个1,则代表传输出现了错误。都是不能检测出是那一位出现了错误。
1.2.3、停止位的长度
停止位的长度可以是0.5位/1位/1.5位 /2位。可以由程序员规定。
1.3、异步通信的波特率
1.3.1、同步通信
2个设备进行同步通信时,则2个设备之间拥有1个时钟线(CLK)和1个数据线,例如 I2C。当时钟线位低电平时,主设备给数据线上写数据,当位高电平时,不能在写数据,从设备进行数据的读取。从设备读取成功后,给主设备返回一个应答信号,主设备继续写数据。这就是同步通信。
1.3.2、异步通信
异步通信和同步通信不同,没有时钟线,拥有2个数据线进行发送(TX)和接收(RX)数据。控制串口通信发送数据的速度是波特率和硬件流控。波特率就是没1s发送码元的个数(9600代表1s传输了9600个码元,传输1个码元占用了0.104ms),在计算机中每一位都代表一个码元。波特率越大,传输速率越快。
异步通信没有时钟线,那么通信是怎样数据传输的喃?答案是:进行数据的采集,例如当接收方采用相同的9600的波特率0时,就代表它采集间隔时间是0.104ms。接收方在空闲时进行高密度采集,当采集到一个下降沿时,代表后面的是数据了,所以间隔1.5个码元进行采集(也是高密度采集),刚好采集到数据位第一个码元的正中间,然后后面就每隔0.104ms进行采集。
1.3.3、硬件流控
硬件流控的作用主要是防止传输的数据丢失,当传输一个数据帧时,等待接收方返回一个反馈信号。如果反馈的是一个低电平,代表接收方可以继续接收数据,然后发送方继续发送数据。
2、USART
2.1、简介
USART也是STM32中的一个片上外设,用于异步串口通信。STM32F103C8T6一共有3个USART,分别为USART1,USART2,USART3。其中USART1挂载在RCC_APB2时钟总线上,所以使用时需要打开时钟。而2和3挂载在RCC_APB1时钟总线上面。
2.2、工作的原理
当单片机通过串口向外发送数据时,CPU向发送数据寄存器TDR写入数据,写入的时候是并行写入,然后进入并行转串行。打开发送控制器,通过TX引脚进行数据的串行发送。当单片机进行数据的接收时,RX接收来的串行数据,通过串行转并行,写入到接收寄存器RDR,然后CPU进行数据的读取。
2.3、相关寄存器
如下图为USART的结构图,他拥有如此多的寄存器,那这些寄存器拥有上面作用喃?交具体我们分析下
-
CR:配置寄存器
UE:USART的总开关,为0,USART禁止,为1,USART打开。需要配置波特率时,也需要打开这个开关。 TXE: 数据传输开关 RXE:数据接收开关 M:数据位长度选择,M = 0:数据位为8位,M = 1:数据位为9位 STOP:停止位长度选择,00为1位,01为0.5位,10为2位,11为1.5位 PE/PCE:奇偶校验使能,0关闭校验位,1打开校验位 PS:奇偶选择位,0偶校验,1奇校验
-
BRR:波特率寄存器
主要是用来配置分频器的系数,波特率 = RCC时钟/(分频系数 * 16)。例如需要9600波特率,选用72MHz时钟时,算出分频系数为468.75。
-
SR:状态寄存器
TXE:发送数据寄存器空,当发送数据寄存器TDR为空时,TXE为1,代表可以向TDR写入数据
RXNE:接收数据寄存器非空,为0,代表接收数据寄存器RDR没有数据,为1,代表接收数据寄存器有数据,可以把数据读出来
TC(TDR空&&移位寄存器空):发送完成寄存器,为0代表还在发送,为1代表发送完成
PE:奇偶校验错,为1,代表传输有出差
FE:帧格式错,为1,代表帧格式出错
NE:噪声错,为1,代表信号里面有噪声
ORE:过载错,为1,代表没有及时的将RDR里面的数据读出来,导致里面的数据被覆盖丢失。
3、标准库编程
3.1、编程接口
如下图所示,为常用的标准库编程接口。
-
USART_Init()
USART_InitTypeDef USARTInitStruct; USARTInitStruct.USART_WordLength = USART_WordLength_8b; USARTInitStruct.USART_Parity = USART_Parity_No; USARTInitStruct.USART_StopBits = USART_StopBits_1; USARTInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USARTInitStruct.USART_BaudRate = 9600; USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART1 ,&USARTInitStruct);
-
USART_Cmd
其实就是CR寄存器中的UE,USART的使能开关。USART_Cmd(USART1 ,ENABLE);//使能USART1
-
USART_SendData
USART_SendData(USART1,0x5a);//数据是16位,2个字节
-
USART_ReceiveData
uint8_t a = USART_ReceiveData(USART1); //将读取到的数据存储在变量a中
-
USART_GetFlagStatus
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET); if(USART_GetFlagStatus(USART1,USART_FLAG_PE)==SET) { }
4、程序代码
我们使用USART1让STM32和上位机进行串口通信。
4.1、使用串口发送数据
USART1的Tx连接的引脚是PA9,Rx连接的引脚是PA10,我们为了增加一下难度,我们使用USART1引脚的重映射。查阅数据手册如下。
代码①:发送一个字节
/*发送一个字节*/
#include "stm32f10x.h"
#include "stm32f10x_pal.h"
int main(void)
{
//1 对PB6,PB7进行配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIOInitStruct;
GPIOInitStruct.GPIO_Pin = GPIO_Pin_6;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//Tx
GPIOInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&GPIOInitStruct);
GPIOInitStruct.GPIO_Pin = GPIO_Pin_7;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;//Rx
GPIO_Init(GPIOB,&GPIOInitStruct );
//2 使能AFIO的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//3 USART1的复用重映射
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);//对USART1进行重映射
//4 使能USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 ,ENABLE);//打开RCC时钟上面的USART1
//5 对USART1进行配置
USART_InitTypeDef USARTInitStruct;
USARTInitStruct.USART_WordLength = USART_WordLength_8b;//数据位为8位
USARTInitStruct.USART_Parity = USART_Parity_No; //没有校验位
USARTInitStruct.USART_StopBits = USART_StopBits_1; //1位停止位
USARTInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//输入输出
USARTInitStruct.USART_BaudRate = 9600; //9600波特率
USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//没有硬件流控
USART_Init(USART1 ,&USARTInitStruct);
USART_Cmd(USART1 ,ENABLE); //使能USART1
//1. 等待TDR清空
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//TDR非空,TXE为0,则卡在这个循环
//2. 写入要发送的数据
USART_SendData(USART1,0x50);
//3. 等待数据发送完成
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET); //发送完毕后,TC为1
while(1)
{
}
}
代码②:发送一个字节数组
#include "stm32f10x.h"
#include "stm32f10x_pal.h"
int main(void)
{
//1 对PB6,PB7进行配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIOInitStruct;
GPIOInitStruct.GPIO_Pin = GPIO_Pin_6;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//Tx
GPIOInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&GPIOInitStruct);
GPIOInitStruct.GPIO_Pin = GPIO_Pin_7;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;//Rx
GPIO_Init(GPIOB,&GPIOInitStruct );
//2 使能AFIO的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//3 USART1的复用重映射
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);//对USART1进行重映射
//4 使能USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 ,ENABLE);//打开RCC时钟上面的USART1
//5 对USART1进行配置
USART_InitTypeDef USARTInitStruct;
USARTInitStruct.USART_WordLength = USART_WordLength_8b;//数据位为8位
USARTInitStruct.USART_Parity = USART_Parity_No; //没有校验位
USARTInitStruct.USART_StopBits = USART_StopBits_1; //1位停止位
USARTInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//输入输出
USARTInitStruct.USART_BaudRate = 9600; //9600波特率
USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//没有硬件流控
USART_Init(USART1 ,&USARTInitStruct);
USART_Cmd(USART1 ,ENABLE); //使能USART1
// //1. 等待TDR清空
// while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//TDR非空,TXE为0,则卡在这个循环
//
// //2. 写入要发送的数据
// USART_SendData(USART1,0x50);
//
// //3. 等待数据发送完成
// while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET); //发送完毕后,TC为1
uint8_t a[] = {0,1,2,3,4,5};
uint8_t i;
for(i = 0 ;i < (sizeof(a)/sizeof(uint8_t));i++)
{
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
USART_SendData(USART1,a[i]);
}
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
while(1)
{
}
}
代码③:发送一个字符数组
#include "stm32f10x.h"
#include "stm32f10x_pal.h"
int main(void)
{
//1 对PB6,PB7进行配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIOInitStruct;
GPIOInitStruct.GPIO_Pin = GPIO_Pin_6;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//Tx
GPIOInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&GPIOInitStruct);
GPIOInitStruct.GPIO_Pin = GPIO_Pin_7;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;//Rx
GPIO_Init(GPIOB,&GPIOInitStruct );
//2 使能AFIO的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//3 USART1的复用重映射
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);//对USART1进行重映射
//4 使能USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 ,ENABLE);//打开RCC时钟上面的USART1
//5 对USART1进行配置
USART_InitTypeDef USARTInitStruct;
USARTInitStruct.USART_WordLength = USART_WordLength_8b;//数据位为8位
USARTInitStruct.USART_Parity = USART_Parity_No; //没有校验位
USARTInitStruct.USART_StopBits = USART_StopBits_1; //1位停止位
USARTInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//输入输出
USARTInitStruct.USART_BaudRate = 9600; //9600波特率
USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//没有硬件流控
USART_Init(USART1 ,&USARTInitStruct);
USART_Cmd(USART1 ,ENABLE); //使能USART1
/*发送一个字节*/
// //1. 等待TDR清空
// while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//TDR非空,TXE为0,则卡在这个循环
//
// //2. 写入要发送的数据
// USART_SendData(USART1,0x50);
//
// //3. 等待数据发送完成
// while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET); //发送完毕后,TC为1
/*发送一个字节数组*/
// uint8_t a[] = {0,1,2,3,4,5};
// uint8_t i;
// for(i = 0 ;i < (sizeof(a)/sizeof(uint8_t));i++)
// {
// while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
// USART_SendData(USART1,a[i]);
// }
// while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
/*发送一个字符*/
// //1. 等待TDR清空
// while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//TDR非空,TXE为0,则卡在这个循环
//
// //2. 写入要发送的数据
// USART_SendData(USART1,'a');
//
// //3. 等待数据发送完成
// while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET); //发送完毕后,TC为1
uint8_t a[] = "hello world";
uint8_t i;
for(i = 0 ;i < sizeof(a)/sizeof(uint8_t) ;i++)
{
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
USART_SendData(USART1,a[i]);
}
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
while(1)
{
}
}
代码优化如下:
#include "stm32f10x.h" // Device header
void MyUSART_Init(void)
{
//1.开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//2.配置引脚,(TX)PA9,(RX)PA10
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;//复用开漏输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//3.配置USART1
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 9600;//波特率
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//发送接收模式
USART_InitStruct.USART_Parity = USART_Parity_No;//校验位
USART_InitStruct.USART_StopBits = USART_StopBits_1;//停止位
USART_InitStruct.USART_WordLength = USART_WordLength_8b;//字长
USART_Init(USART1, & USART_InitStruct);
//4.使能
USART_Cmd(USART1,ENABLE);
}
void USART_SendByte(uint8_t Byte)//发送一个字节
{
// while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//TDR非空,TXE为0,则卡在这个循环
USART_SendData(USART1,Byte);//向TDR寄存器里面写入一个数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//等待发送完成
}
void USART_SendArray(uint8_t* Array ,uint16_t Length)//发送一个数组
{
uint16_t i;
for(i = 0 ;i < Length;i++)
{
USART_SendByte(Array[i]);
}
}
void USART_SendString(char* String)//发送一个字符串
{
uint8_t i;
for(i = 0;String[i] != '\0';i++)
{
USART_SendByte(String[i]);
}
}
uint32_t Serial_Pow(uint32_t x,uint32_t y)//x^y
{
uint32_t Result = 1;
while(y--)
{
Result = Result * x;
}
return Result;
}
/*
4321
4 = 4321 / 1000 % 10
3 = 4321 / 100 % 10
2 = 4321 /10 & 10
1 = 4321 / 1 & 10
*/
void USART_SendNum(uint32_t Number,uint8_t Length)//发送整数以字符形式打印
{
for(uint16_t i =0 ; i<Length ;i++)
{
USART_SendByte(Number / Serial_Pow(10,Length - i-1) % 10 + 0x30);
}
}
4.2、使用串口接收数据
/*通过接收到的数据进行对LED灯的控制*/
#include "stm32f10x.h"
#include "stm32f10x_pal.h"
int main(void)
{
//1 对PB6,PB7进行配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIOInitStruct;
GPIOInitStruct.GPIO_Pin = GPIO_Pin_6;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//Tx
GPIOInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&GPIOInitStruct);
GPIOInitStruct.GPIO_Pin = GPIO_Pin_7;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;//Rx
GPIO_Init(GPIOB,&GPIOInitStruct );
//2 使能AFIO的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//3 USART1的复用重映射
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);//对USART1进行重映射
//4 使能USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 ,ENABLE);//打开RCC时钟上面的USART1
//5 对USART1进行配置
USART_InitTypeDef USARTInitStruct;
USARTInitStruct.USART_WordLength = USART_WordLength_8b;//数据位为8位
USARTInitStruct.USART_Parity = USART_Parity_No; //没有校验位
USARTInitStruct.USART_StopBits = USART_StopBits_1; //1位停止位
USARTInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//输入输出
USARTInitStruct.USART_BaudRate = 9600; //9600波特率
USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//没有硬件流控
USART_Init(USART1 ,&USARTInitStruct);
USART_Cmd(USART1 ,ENABLE); //使能USART1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
GPIOInitStruct.GPIO_Pin = GPIO_Pin_13;
GPIOInitStruct .GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC,&GPIOInitStruct);
uint8_t a;
while(1)
{
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == RESET);//RXNE为0代表没有数据
a = USART_ReceiveData(USART1);
if(a == '1')
{
GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_RESET);//开灯
}
if(a == '0')
{
GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);//关灯
}
}
}
代码优化如下:
USART.c文件的代码如下:
#include "stm32f10x.h" // Device header
uint8_t Data;
uint8_t Flag;
void MyUSART_Init(void)
{
//1.开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//2.配置引脚,(TX)PA9,(RX)PA10
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;//复用开漏输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//3.配置USART1
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 9600;//波特率
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//发送接收模式
USART_InitStruct.USART_Parity = USART_Parity_No;//校验位
USART_InitStruct.USART_StopBits = USART_StopBits_1;//停止位
USART_InitStruct.USART_WordLength = USART_WordLength_8b;//字长
USART_Init(USART1, & USART_InitStruct);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开始中断
//4.配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitTypeDef NVIC_InitTypeDef;
NVIC_InitTypeDef.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitTypeDef.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitTypeDef.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitTypeDef.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitTypeDef);
//5.使能
USART_Cmd(USART1,ENABLE);
}
uint8_t USART_GetData(void)//接收数据
{
return Data;
}
uint8_t USART_GetFlag(void)//标志位
{
if(Flag == 1)//触发中断函数,flag = 1
{
Flag = 0; //让flag = 0
return 1;
}
return 0;
}
void USART1_IRQHandler(void)//中断函数,利用中断函数接收数据
{
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == RESET);//等待接收,读取数据自动清除
Data = USART_ReceiveData(USART1);
Flag = 1;
}
主程序代码如下:
/*
使用USART发送数据
*/
#include "stm32f10x.h"
#include "OLED.h"
#include "USART.h"
uint8_t Data1;
int main(void)
{
MyUSART_Init();
OLED_Init();
while(1)
{
if(USART_GetFlag() == 1)
{
Data1 = USART_GetData();//数据的转存,将Data里面的数据存入Data1中
OLED_ShowHexNum(1,1,Data1,2);
USART_SendByte(Data1);
}
}
}