串口发送数据通常指单片机通过串口(USART/UART)向电脑发送数据
串口接收数据通常指单片机通过串口接收来自电脑的数据
目录
1.回顾串口数据发送的过程
2.TxE标志位
TxE是发送数据寄存器空标志位,用来判断发送数据寄存器里面有没有数据,如果发送数据寄存器(TDR)是空时,TxE=1,否则TxE-0
通过查TxE标志位,可以避免发送数据丢失,比如发送数据寄存器里面有数据,你又发送了数据,这种情况下就会丢失数据
3.TC标志位
TC是发送完成标志位,用来指示USART里面的数据有没有发送完成。
当发送数据寄存器(TDR)是空且移位寄存器空时,TC=1,否则TC=0。
4.编程接口
4.1串口总开关
4.2查询标志位的值
4.3发送数据
用串口发送数据的时候一般用字节的方式发送,但uint16_t无符号的整形2个字节,因为当我们数据位9位的时候1个字节不够
5.编写代码
编写一个函数,实现使用串口一次性发送多个字节
USART_TypeDef 用来填写串口的名称
uint8_t 无符号八位指针类型
uint16_t 用来填写发送字节的数量
给电脑发送数据要准备USB TO TTL(USB转TTL模块)
可以把单片机的串口转换成USB接口,这样就可以实现单片机和电脑通信
注意TX和RX交替连接
下面图片用的是重映射的串口,所以选择PB6 PB7,当然你也可以不用映射的,那就选用PA9 PA10
串口调试工具
#include "stm32f10x.h" // Device header
void My_USART_SendBytes(USART_TypeDef *USARTx ,uint8_t *pDate,uint16_t Size);
int main(void)
{
//1.串口初始化
//开启USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//定义结构体
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate=115200;
USART_InitStruct.USART_Mode=USART_Mode_Tx | USART_Mode_Rx; //双向
USART_InitStruct.USART_WordLength=USART_WordLength_8b; //8数据位
USART_InitStruct.USART_Parity=USART_Parity_No; //无校验位
USART_InitStruct.USART_StopBits=USART_StopBits_1; //1位停止位
USART_Init(USART1,&USART_InitStruct);
//2.初始化IO引脚
//初始化USART1引脚 TX发送 PA9 复用推挽输出
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
//复用推挽输出
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
//最大速度
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//初始化USART1引脚 RX接收 PA10 输入上拉
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
//输入模式不用设置速度
GPIO_Init(GPIOA,&GPIO_InitStruct);
//3.USART模块的总开关
USART_Cmd(USART1,ENABLE);
uint8_t byteToSend[]={1,2,3,4,5};
My_USART_SendBytes(USART1,byteToSend,5);
while (1)
{
}
}
void My_USART_SendBytes(USART_TypeDef *USARTx ,uint8_t *pDate,uint16_t Size)
{
for(uint32_t i=0;i<Size;i++)
{
//1.等待发送数据寄存器为空 TXE=1是为空,等于0时不为空,而RESET=0,所以只要不为空,就会一直在while循环里面
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
//2.将要发送的数据写入到发送数据寄存器
USART_SendData(USARTx,pDate[i]);
}
//3.等待数据发送完成 TC为1时才表示发送完成,所以只要TC==0就一直循环
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
}
整理后的代码
#include "stm32f10x.h" // Device header
void My_USART_SendBytes(USART_TypeDef *USARTx ,uint8_t *pDate,uint16_t Size);
void My_USART1_Init(void);
int main(void)
{
My_USART1_Init();
uint8_t byteToSend[]={1,2,3,4,5};
My_USART_SendBytes(USART1,byteToSend,5);
while (1)
{
}
}
//
// @简介:通过串口发送多个数据并检测是否发送完成
// @参数 USARTx:填写串口的名称
// @参数 pDate:要发送的数据
// @参数 Size:要发送数据的数量,单位是字节
//
void My_USART_SendBytes(USART_TypeDef *USARTx ,uint8_t *pDate,uint16_t Size)
{
for(uint32_t i=0;i<Size;i++)
{
//1.等待发送数据寄存器为空 TXE=1是为空,等于0时不为空,而RESET=0,所以只要不为空,就会一直在while循环里面
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
//2.将要发送的数据写入到发送数据寄存器
USART_SendData(USARTx,pDate[i]);
}
//3.等待数据发送完成 TC为1时才表示发送完成,所以只要TC==0就一直循环
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
}
//
// @简介:对USART1进行初始化
// PA9 - Tx PA10 - Rx
// 15200 8位数据位 1位停止位 None校验位 双向
//
void My_USART1_Init(void)
{
//1.串口初始化
//开启USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//定义结构体
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate=115200;
USART_InitStruct.USART_Mode=USART_Mode_Tx | USART_Mode_Rx; //双向
USART_InitStruct.USART_WordLength=USART_WordLength_8b; //8数据位
USART_InitStruct.USART_Parity=USART_Parity_No; //无校验位
USART_InitStruct.USART_StopBits=USART_StopBits_1; //1位停止位
USART_Init(USART1,&USART_InitStruct);
//2.初始化IO引脚
//初始化USART1引脚 TX发送 PA9 复用推挽输出
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
//复用推挽输出
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
//最大速度
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//初始化USART1引脚 RX接收 PA10 输入上拉
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
//输入模式不用设置速度
GPIO_Init(GPIOA,&GPIO_InitStruct);
//3.USART模块的总开关
USART_Cmd(USART1,ENABLE);
}