STM32串口通信之轮询标志位、中断方式以及队列实现

STM32串口通信之队列实现

1、学习资源

学习资源来自于B站优质单片机up铁头山羊,有需要全程学习的同学可以点击如下链接:
铁头山羊教程
铁头山羊

2、为什么要用队列实现串口的消息收发?

为了实现串口消息收发这一目的,我们有许多方式,包括轮训标志位中断收发队列收发,其中。队列收发可看做中断收发的一种升级形式,其能更好的收发消息,避免消息的遗失。下面我们来看一下具体为什么。

2.1 轮训标志位

2.1.1 数据的发送

总代码如下

#include "stm32f10x.h"
#include "stm32f10x_pal.h"
#include <string.h>

int main(void)
{
   
	GPIO_InitTypeDef GPIOInitStruct;
	
	PAL_Init();
	
	// 初始化Tx PB6 AF_PP 10MHz
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 开启GPIOB的时钟
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_6;
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIOInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOB, &GPIOInitStruct);
	
	// 初始化Rx PB7 IPU
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_7;
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOB, &GPIOInitStruct);
	
	// 重映射USART1的Tx和Rx引脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //开启AFIO的时钟
	GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE); 
	
	// 使能USART1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	// 设置USART1的参数
	USART_InitTypeDef USARTInitStruct;
	USARTInitStruct.USART_BaudRate = 9600;
	USARTInitStruct.USART_WordLength = USART_WordLength_8b;
	USARTInitStruct.USART_StopBits = USART_StopBits_1;
	USARTInitStruct.USART_Parity = USART_Parity_No;
	USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USARTInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	
	USART_Init(USART1, &USARTInitStruct);
	
	// 闭合USART1的总开关
	USART_Cmd(USART1, ENABLE);
//	
 发送单个数据	
//	// 1. 等待TDR寄存器清空
//	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}
//		
//	// 2. 写入要发送的数据
//	USART_SendData(USART1, 0x5a);
//		
//	// 3. 等待数据发送完成
//	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){}

//
发送一个数组
//  uint8_t a[] = {0,1,2,3,4,5};
//	uint32_t i;
//---------------------------------------------------------------
//	方法一:
//	for(i=0;i<sizeof(a) / sizeof(uint8_t);i++)
//	{
   
//		// 1. 等待TXE置位
//		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
//		// 2. 数据写入TDR
//		USART_SendData(USART1, a[i]);
//	}
//	
//	// 3. 等待数据发送完成
//	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
//------------------------------------------------------------------
//方法二:
//  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
//	USART_SendData(USART1, 'a');
//	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);

发送一个字符串:
//  const char *str = "Hello world";
//	uint32_t i;
//	for(i=0; i<strlen(str);i++)
//	{
   
//		// 1. 等待TXE置位
//		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
//		// 2. TDR
//		USART_SendData(USART1, str[i]);
//	}
//	// 3. TC置位
//	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);


  

轮询标志位最大的特点就是在USART/UART初始化时没有对NVIC进行配置,同时在消息收发时采用如下代码对标志位进行检验:
单个数据的发送

	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){
   }
		
	// 2. 写入要发送的数据
	USART_SendData(USART1, 0x5a);
		
	// 3. 等待数据发送完成
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){
   }

数组的发送


  uint8_t a[] = {
   0,1,2,3,4,5};
	uint32_t i;
	
	for(i=0;i<sizeof(a) / sizeof(uint8_t);i++)
	{
   
		// 1. 等待TXE置位
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
		// 2. 数据写入TDR
		USART_SendData(USART1, a[i]);
	}
	
	// 3. 等待数据发送完成
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
	USART_SendData(USART1, 'a');
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
	

字符串的发送

  const char *str = "Hello world";
	uint32_t i;
	for(i=0; i<strlen(str);i++)
	{
   
		// 1. 等待TXE置位
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
		// 2. TDR
		USART_SendData(USART1, str[i]);
	}
	// 3. TC置位
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值