STM32循环队列串口通信(工程末尾自取)

2023-05-16

STM32循环队列串口通信

包含内容:

  • 循环队列

  • 环形队列

    循环队列本质是先进先出的线性序列,通过定义的头尾指针对一个数组或者一个合法的内存进行循环访问的方式存入和取出数据,通过数组或者合法内存形成数据的缓冲区。

    1.这是一段连续的内存存储和头、尾指针
    2.初始化状态令头、尾指针都置于内存起始地址
    在这里插入图片描述3
    3.为避免数据假溢出 形成循环队列 令指针移动到内存末地址时重新回到内存的起始地址
    在这里插入图片描述
    4.编写初始化代码

typedef struct
{
 uint16_t Head;//头指针 取出数据时移动头指针
 uint16_t Tail;//尾指针 存入数据时移动尾指针
 uint16_t Lenght;//长度  尾指针和头指针间的距离 代表存储数据的长度
 uint8_t Ring_Buff[200];//缓冲大小 申请了200长度的数组用于存取数据
}RingBuff_t;
extern RingBuff_t ringBuff; 
void RingBuff_Init();缓冲区初始化
uint8_t Write_RingBuff(uint8_t data);//入队
uint8_t Read_RingBuff(uint8_t *rData);//出队

void RingBuff_Init(void) //初始化函数
{
 ringBuff.Head=0; //头指针置于起始位
 ringBuff.Tail=0; //尾指针置于起始位
 ringBuff.Lenght=0; //计录当前数据长度 判断是否存有数据
}

5.入队代码

uint8_t Write_RingBuff(uint8_t data) //存入指定的缓冲数组并通过数据长度判断是否溢出 返回值0正常 1溢出
{
 if(ringBuff.Lenght>=200) //200是申请的内存长度 可以修改 如果超过则为溢出
 {
  return 1; //确认数据溢出返回值1
 }
 ringBuff.Ring_Buff[ringBuff.Tail]=data;  //将数据通过尾指针指向的地址存入Ring_Buff缓冲数组中
 ringBuff.Tail=(ringBuff.Tail+1)%200;     //构建尾部指针的循环 指针累加 指针地址超过199 则重新置于0
 ringBuff.Lenght++;  //记录存入数据的长度 判断数据的存有数量和溢出情况
 return 0; //无溢出情况存入数据 返回值0
}

6.出队代码

uint8_t Read_RingBuff(uint8_t *rData) //从指定的缓冲数组中读出头指针指向地址的数据
{
 if(ringBuff.Lenght==0)  //如果数据长度为0 则此时缓冲数组中未存有数据
 {
  return 1; //取出数据失败 返回值0
 }
 *rData=ringBuff.Ring_Buff[ringBuff.Head]; //在Ring_buff中从头指针指向的地址中取出数据
 ringBuff.Head=(ringBuff.Head+1)%200;  //构建头部指针的循环 指针累加 指针地址超过199 则重新置于0
 ringBuff.Lenght--; //取出数据时减去相应的数据长度
 return 0; //取出数据正常 返回值0
}

本代码多有参考 在基础上加入了自身的理解和注释 记录学习过程中的一些细节 参考博客在下方链接 对接串口通信的详细后续补充

参考博客-图片
参考博客—代码

补充串口部分

uint16_t uart_puts(uint8_t *src, uint16_t len);
uint16_t uart_read(uint8_t* buf, uint16_t read_len);

uint8_t *pDataByte;

uint8_t Data = 0;
uint8_t Flag = 0;
uint16_t Len = 0;      

uint8_t Data_BUF[200];

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统终端优先级2
	delay_init(168);		//延时初始化
	uart_init(115200);	//串口初始化波特率115200
	LED_Init();		  		//初始化与LED连接的IO
	memset(Data_BUF,'1',200);
	RingBuff_Init();
	while(1)
	{
//		uart_read(Data_BUF,10);
		uart_puts(Data_BUF,10);
		delay_ms(4);
	}
}

uint16_t uart_puts(uint8_t *src, uint16_t len)
{
	pDataByte = src;
	Len=len;
	USART_ITConfig(USART1, USART_IT_TXE, ENABLE);  //发送标志位使能
	return 0;
}

uint16_t uart_read(uint8_t* buf, uint16_t read_len)
{
	static uint8_t n = 0;
		if(n > read_len)
		{
			n = 0;
			buf = Data_BUF;
			Flag = 1;		
		}
		if(0 == Read_RingBuff(&Data) && Flag == 0)            //???????????
		{
				*buf++ = Data;
				n++;
		}	  
	return 0;
}

串口初始化及接收部分

#include "sys.h"
#include "usart.h"	
// 	 
//Èç¹ûʹÓÃucos,Ôò°üÀ¨ÏÂÃæµÄÍ·Îļþ¼´¿É.
#if SYSTEM_SUPPORT_OS
#include "includes.h"					//ucos ʹÓÃ	  
#endif

extern uint8_t Flag;
extern uint16_t Len;
extern uint8_t* pDataByte;

typedef struct
{
 uint16_t Head;//???
 uint16_t Tail;//???
 uint16_t Lenght;//??
 uint8_t Ring_Buff[200];//????
}RingBuff_t;

RingBuff_t ringBuff;

extern RingBuff_t ringBuff;

void RingBuff_Init(void)
{
 ringBuff.Head=0;
 ringBuff.Tail=0;
 ringBuff.Lenght=0;
}

uint8_t Write_RingBuff(uint8_t data)
{
 if(ringBuff.Lenght>=200)
 {
  return 1;
 }
 ringBuff.Ring_Buff[ringBuff.Tail]=data;
 ringBuff.Tail=(ringBuff.Tail+1)%200;
 ringBuff.Lenght++;
 return 0;
}

uint8_t Read_RingBuff(uint8_t *rData)
{
 if(ringBuff.Lenght==0)
 {
  return 1;
 }
 *rData=ringBuff.Ring_Buff[ringBuff.Head];
 ringBuff.Ring_Buff[ringBuff.Head]=0;
 ringBuff.Head=(ringBuff.Head+1)%200;
 ringBuff.Lenght--;
 return 0;
}


//¼ÓÈëÒÔÏ´úÂë,Ö§³Öprintfº¯Êý,¶ø²»ÐèҪѡÔñuse MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//±ê×¼¿âÐèÒªµÄÖ§³Öº¯Êý                 
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//¶¨Òå_sys_exit()ÒÔ±ÜÃâʹÓðëÖ÷»úģʽ    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//Öض¨Òåfputcº¯Êý 
int fputc(int ch, FILE *f)
{ 	
	while((USART1->SR&0X40)==0);//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   
	USART1->DR = (u8) ch;      
	return ch;
}
#endif
 
#if EN_USART1_RX   //Èç¹ûʹÄÜÁ˽ÓÊÕ
//´®¿Ú1ÖжϷþÎñ³ÌÐò
//×¢Òâ,¶ÁÈ¡USARTx->SRÄܱÜÃâĪÃûÆäÃîµÄ´íÎó   	
u8 USART_RX_BUF[USART_REC_LEN];     //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
//½ÓÊÕ״̬
//bit15£¬	½ÓÊÕÍê³É±êÖ¾
//bit14£¬	½ÓÊÕµ½0x0d
//bit13~0£¬	½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
u16 USART_RX_STA=0;       //½ÓÊÕ״̬±ê¼Ç	

//³õʼ»¯IO ´®¿Ú1 
//bound:²¨ÌØÂÊ
void uart_init(u32 bound){
   //GPIO¶Ë¿ÚÉèÖÃ
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //ʹÄÜGPIOAʱÖÓ
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//ʹÄÜUSART1ʱÖÓ
 
	//´®¿Ú1¶ÔÓ¦Òý½Å¸´ÓÃÓ³Éä
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9¸´ÓÃΪUSART1
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10¸´ÓÃΪUSART1
	
	//USART1¶Ë¿ÚÅäÖÃ
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9ÓëGPIOA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸´Óù¦ÄÜ
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//ËÙ¶È50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //ÍÆÍ츴ÓÃÊä³ö
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //ÉÏÀ­
	GPIO_Init(GPIOA,&GPIO_InitStructure); //³õʼ»¯PA9£¬PA10

   //USART1 ³õʼ»¯ÉèÖÃ
	USART_InitStructure.USART_BaudRate = bound;//²¨ÌØÂÊÉèÖÃ
	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_ITConfig(USART1, USART_IT_TC, ENABLE);
//	USART_ClearFlag(USART1, USART_FLAG_TC);
	
#if EN_USART1_RX	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//¿ªÆôÏà¹ØÖжÏ

	//Usart1 NVIC ÅäÖÃ
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//´®¿Ú1ÖжÏͨµÀ
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//ÇÀÕ¼ÓÅÏȼ¶3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//×ÓÓÅÏȼ¶3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQͨµÀʹÄÜ
	NVIC_Init(&NVIC_InitStructure);	//¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷¡¢

#endif
	
}


void USART1_IRQHandler(void)                	//´®¿Ú1ÖжϷþÎñ³ÌÐò
{
#if SYSTEM_SUPPORT_OS 		//Èç¹ûSYSTEM_SUPPORT_OSΪÕ棬ÔòÐèÒªÖ§³ÖOS.
	OSIntEnter();    
#endif
	static uint16_t x = 1;
 if( USART_GetITStatus(USART1, USART_IT_TXE) == SET  )
	{
		if( *pDataByte == '\0' || x == Len)//x == Len
		{
			USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
			x=1;
			Flag = 0;
		}
		else
		{
			USART_SendData(USART1, *pDataByte );
			pDataByte++;
			x++;
		}
	}
//		if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //
//		{
//			USART_ClearITPendingBit(USART1,USART_IT_RXNE); 
//			Write_RingBuff(USART_ReceiveData(USART1));//(USART1->DR);	//¶ÁÈ¡½ÓÊÕµ½µÄÊý¾			
//		} 
#if SYSTEM_SUPPORT_OS 	//Èç¹ûSYSTEM_SUPPORT_OSΪÕ棬ÔòÐèÒªÖ§³ÖOS.
	OSIntExit();  											 
#endif
} 
#endif	

 [完整工程代码](https://download.csdn.net/download/zx201902020050/87389516)




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32循环队列串口通信(工程末尾自取) 的相关文章

  • 常用Arduino板介绍

    目录 NANO板介绍烧录说明 UNO板介绍烧录说明 Pro mini板介绍烧录说明 DUE板介绍烧录说明 NANO板介绍 概述 xff1a Arduino Nano是一款基于ATMega328P xff08 Arduino Nano 3 x
  • Modbus设备在Modbus scan上面的使用方法

    操作教程 参数 xff1a DeviceID xff1a 485从站 寄存器地址 xff1a 查询设备地址表 北醒雷达Dist在0x0000开始 读取寄存器长度 xff1a 雷达数据长度值 格式 xff1a MODBUS RTU 串口协议
  • Raspberry Pi Pico C/C++语言在Windows环境下开发环境搭建 Raspberry Pi Pico C/C++ SDK

    目录 前言Raspberry Pi Pico介绍需要支持的软件软件安装配置及注意事项ARM GCC compiler的安装CMake的安装Git 安装Visual Studio 2019的安装Visual Studio Code的配置Pyt
  • 【LoRa32U4II】介绍以及基于Arduino IDE编译环境搭建及测试

    目录 LoRa 模块LoRa32u4 II介绍LoRa32u4 II 资料下载LoRa32u4 II 规格介绍LoRa32u4 II 脚位说明 编译环境介绍电脑系统编译软件Arduino需求库 编译环境搭建及测试LoRa32u4 II 测试
  • 【Benewake(北醒) 】短距 TF-LC02 2m资料整理

    目录 1 TF LC02简要说明1 1 性能参数1 2产品图片及尺寸 2 运用2 1 在开源板Arduino上的运用2 2 在Python上的应用 1 TF LC02简要说明 1 1 性能参数 1 2产品图片及尺寸 2 运用 2 1 在开源
  • 【Arduino】Benewake(北醒) TF-LC02(TTL)基于Arduino 开发板运用说明

    目录 前言Benewake 北醒 TF LC02产品简要说明Arduino开发板介绍Benewake 北醒 TF LC02 接口及通讯协议说明接口定义串口协议说明通讯协议说明功能码说明 接线示意图例程说明配置软硬串口定义获取TOF数据的结构
  • 【Benewake(北醒) 】中距 TF02-i 40m工业版本CAN/485介绍以及资料整理

    目录 1 前言2 产品介绍3 产品快速测试3 1 产品规格书及使用说明书3 2 通用指令串口助手使用说明3 3 产品快速测试说明 4 基于开源硬件的运用整理4 1 在开源飞控上的运用 5 基于其他的运用整理5 1 在PLC上的运用说明5 2
  • 【ESP32 DEVKIT_V1】基于Arduino IDE环境搭建

    目录 一 前言二 板子介绍三 环境搭建1 Arduino IDE的安装2 在Arduino IDE上添加外包链接3 添加好外包链接后就可以下载对应的板子库文件 测试1 先把开发板接到电脑 xff0c 并在Arduino IDE上选择对应的开
  • 【ESP32 DEVKIT_V1】北醒TF系列雷达在ESP32 DEVKIT_V1开发板上的运用

    目录 前言一 硬件准备二 硬件接线说明串口接线示意图 xff1a I2C接先示意图 三 软件搭建及测试1 使用Arduino IDE编译教程2 使用vsCode 43 Arduino教程2 1 在vsCode上使用Arduino的环境搭建2
  • 【vsCode + Arduino】在Visual Studio Code编译Arduino项目

    目录 前言一 参考文档二 操作步骤2 1 安装Arduino IDE2 2 在vsCode里安装Arduino插件2 3 配置arduino的安装路径2 4 配置好后打开一个Arduino的项目文件夹进行相应的配置 三 目前已知问题 前言
  • 蓝牙:GATT,属性,特性,服务

    接着上一篇 通用属性配置文件 xff08 Generic Attribute Profile xff09 1 GATT简介 通用属性配置文件Generic Attribute Profile简称GATT GATT定义了属性类型并规定了如何使
  • RS232 RS422 RS485详细介绍

    1 RS 232 C RS 232 C是美国电子工业协会EIA xff08 Electronic Industry Association xff09 制定的一种串行物理接口标准 RS是英文 推荐标准 的缩写 xff0c 232为标识号 x
  • stm32串口使用以及串口中断接收不定长度字符串

    开始使用cubemx配置PA9 PA10分别为TX RX端 xff0c 在使能串口中断 之后其余值直接使用默认的就可以了 点击生成代码即可 span class token class name uint8 t span rx buff s
  • STM32-串口通信printf重定向

    前言 xff1a 平时我们进行c语言编程的时候会经常用到printf函数进行打印输出 xff0c 来调试代码 可是这个printf函数C库已经帮我们实现好了 xff0c 通常只需要直接调用即可 xff0c 但是如果在一个新的开发平台 xff
  • FMCW毫米波雷达原理

    Radar系列文章 传感器融合是将多个传感器采集的数据进行融合处理 xff0c 以更好感知周围环境 xff1b 这里首先介绍毫米波雷达的相关内容 xff0c 包括毫米波雷达基本介绍 xff0c 毫米波雷达数据处理方法 xff08 测距测速测
  • VMware虚拟机安装ubuntu16.04系统教程

    对于没有接触过Ubuntu系统的小伙伴来说 xff0c 直接在物理机上安装Ubuntu单系统或者windows Ubuntu双系统一件比较刺激的事情 xff0c 因为一不小心可能就会把电脑整崩溃 xff0c 或者出现各种问题 xff0c 所
  • c#实验五 文件与流

    实验五 文件与流 WPF还不太会 抄STZG的 xff0c 其他自己写的 一 实验目的 掌握文件类的使用 xff1b 掌握文件流的操作 xff1b 掌握二进制数据 文本数据的读写 xff1b 继续应用WPF技术进行界面编程 二 实验内容 要
  • 简易入门MFC

    工作需要用到MFC xff0c 需要能快速上手 xff0c 中间碰到不懂的简单的看了下源码 xff0c 参考了些资料 目标 xff1a 做一个简单的计算器 xff0c 代码就不考虑了 xff0c 主要强调如何上手MFC xff0c 和简单了
  • Problem: 美丽的黄山 (指针)

    Description 众所周知 xff0c 黄山市一片山 xff08 而不是一座山 xff09 假设这些山排成了一排 xff0c 每座山有各自的高度 现在游客们从最左边看山 xff0c 有些山因为高度没有它左边的某座山高 xff0c 就会
  • (冒泡排序) Problem: 并列排名

    冒泡排序原理就是 xff1a 如果有n个数 xff0c 相邻的两个数进行比较 xff0c 就是1号和2号 xff0c 2号和3号 n 1号和n号比较 xff0c 每次比较确定一个数的位置 也就是第一个轮回比较n 1次 xff0c 第二个就比

随机推荐