作者:蜗蜗家的逆时针 | 来源:互联网 | 2023-10-10 08:09
串口发送字节、半字、字、字符串、数组及实现串口控制简介串口的配置1.配置usart的TX和RX引脚2.配置串口模式3.配置串口的优先级(使用串口中断时)4.串口初始化编写发送函数发
串口发送字节、半字、字、字符串、数组及实现串口控制
- 简介
- 串口的配置
- 1. 配置usart的TX和RX引脚
- 2. 配置串口模式
- 3.配置串口的优先级(使用串口中断时)
- 4.串口初始化
- 编写发送函数
- 发送一个字节函数
- 发送半字函数
- 发送字函数
- 发送字符串函数
- 发送数组函数
- 重新定向printf函数
- 编写主函数
- 注意事项
简介
串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。
STM32的串口通信外设有USART和UART。USART是Universal Synchronous Asynchronous Receiver and Transmitter的缩写,即通用同步异步收发器可以灵活地与外部设备进行全双工数据交换。UART(Universal Asynchronous Receiver and Transmitter)在USART基础上裁减了同步通信功能,只有异步通信。
串口通过三个引脚从外部连接到其它设备,任何 USART 双向通信均需要至少两个引脚:接收数据输入引脚 (RX) 和发送数据输出 引脚(TX)。
串口的配置
1. 配置usart的TX和RX引脚
static void MyUsart_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //TX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; //RX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStruct);
}
这里配置的是:
TX—PA9;
RX—PA10
2. 配置串口模式
1.使能串口时钟
2.配置串口参数:
波特率(一般是9600或15200);
硬件控制流(一般是None);
模式(一般RX和TX都用);
奇偶校验(一般无);
停止位(一般为1);
字长(一般是8位);
static void MyUSART_Mode_Init(void)
{
USART_InitTypeDef USART_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
USART_InitStruct.USART_BaudRate = 9600;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
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);
}
3.配置串口的优先级(使用串口中断时)
static void MyUSART_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
4.串口初始化
1.初始化串口引脚
2.初始化串口模式
3(配置串口优先级)
4.使能串口
void MyUSART_Init(void)
{
//初始化串口引脚
MyUsart_GPIO_Init();
//初始化串口模式
MyUSART_Mode_Init();
//使能串口
USART_Cmd(USART1,ENABLE);
}
经过以上步骤串口的配置就完成了,接下来就是编辑串口的发送字节、半字、字、字符串、数组函数了。
编写发送函数
当然了,以下函数可以根据具体要求来裁剪。
发送一个字节函数
void MyUSART_SendByte(uint8_t data)
{
USART_SendData(USART1, data);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
发送半字函数
void MyUSART_SendHalfWord(uint16_t data)
{
uint8_t data_h,data_l;
data_h = (data&0xff00)>>8;
data_l = data&0xff;
USART_SendData(USART1, data_h);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
USART_SendData(USART1, data_l);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
发送字函数
void MyUSART_SendWord(uint32_t data)
{
uint16_t data_h,data_l;
data_h = (data>>16)&0xffff;
data_l = data&0xffff;
MyUSART_SendHalfWord(data_h);
MyUSART_SendHalfWord(data_l);
// while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)!=RESET)
}
发送字符串函数
void MyUSART_SendStr(uint8_t *str)
{
uint8_t i=0;
do
{
MyUSART_SendByte(*(str+i));
i++;
}while(*(str+i)!='\0');
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); //判断是否发送完成
}
发送数组函数
void MyUSART_SendArr(uint8_t *str,uint8_t count)
{
uint8_t i=0;
for(;i<count;i++)
{
MyUSART_SendByte(*(str+i));
}
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
}
重新定向printf函数
如果需要使用printf函数、putchar函数、getchar函数,则必须重新定向fputc和fgetc函数。否则c语言中的输入输出语句不能使用。
int fputc(int ch,FILE *f)
{
USART_SendData(USART1, (uint8_t)ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
return(ch);
}
int fgetc(FILE *f)
{
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);
return((int)USART_ReceiveData(USART1));
}
编写主函数
int main()
{
uint32_t a='我';
uint8_t b[5]={ 1,2,3,4,5};
uint8_t c[22]="单片机工程师\r\n";
LED_Init();
MyUSART_Init();
MyUSART_SendByte(0x61); //发送一个字节a
MyUSART_SendHalfWord(0x6263); //发送两个字节ab
MyUSART_SendWord(a); //发送字
MyUSART_SendStr((unsigned char*)"单片机"); //发送字符串
MyUSART_SendArr(b,5); //发送数组
printf(c); //发送字符串
putchar('n'); //输出一个字节
while(1) //实现串口控制,输入‘1’控制LED亮灭。
{
uint8_t ch;
ch = getchar();
if(ch=='1')LED0=!LED0;
}
}
运行的结果如下:
结果分析:
MyUSART_SendByte(0x61); 输出结果:a
MyUSART_SendHalfWord(0x6263); 输出结果:bc
MyUSART_SendWord(a); 输出结果:我
MyUSART_SendStr((unsigned char*)“单片机”);输出结果:单片机
MyUSART_SendArr(b,5);输出结果:为一个数组,结果要在串口调试助手上勾选“16进制显示”,如下图
printf©;输出结果:单片机工程师
putchar(‘n’);输出结果:n
while循环中不断扫描输入的数据,如果是‘1’,则点亮或熄灭LED灯。
注意事项
- 发送字节、半字、全字的时候,如果输入的16进制数大于128(十进制计算)会显示“?”。例如0X9797,97的十进制151,查询ask码表应该是ù,但实际中会显示“?”。查阅c语言书籍,有个小注:000-127是标准的,128-255是扩展的。难道扩展的不能显示吗?有懂的请告知,谢了。
- 使用串口时一定要在魔术棒的Target中勾选“USE Micro LIB”。
程序已经过调试验证,可正常输出,串口可控制LED
完整代码传送门:
https://download.csdn.net/download/m0_46195580/13773217