IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32程序架构内核移植(二) -> 正文阅读

[嵌入式]STM32程序架构内核移植(二)

四、队列算法讲解

1、队列的作用

队列简单来说就是开辟一个数组(内存空间),然后有一个队列头指针pHead和一个队列尾指针pTail。

为什么一个数组存储要搞这么复杂?目的是为了设定一个数据存储和读取规则,数据在这个数组里面遵循先进先出的规则,不能插队。

这样最大的好处就是,数据不会丢失。

比如说我们做串口通讯的时候,通常是一帧数据过来,然后在串口中断里面接收数据,同时while(1)循环里解析和处理数据。

这种方式可能会出现一个问题,就是while(1)循环里面的串口哦数据还没解析完,又有一帧新的数据传过来,那老的数据就会被覆盖掉(这就是“插队”),这个时候队列就发挥作用了。

串口中断直接把接受字节数据都丢进队列里,while(1)不断从队列里取数据,只要队列够大,基本不存在丢包和插队的问题。

2、队列算法代码

1、队列数据结构。

/* 队列结构体定义,定义不同大小的队列 */
typedef struct
{
	unsigned char *Head;  // 头指针,指向队列头地址
	unsigned char *Tail;  // 尾指针,指向队列尾地址
	unsigned char Buff[4+1];  // 队列数组的内存
}Queue4;

2、清空队列函数

/********************************************************************************************************
*  @函数名   S_QueueEmpty						                                                           
*  @描述     清空一个队列								                                     
*  @参数     Head-队列头地址,  Tail-队列尾地址,   HBuff-队列缓存
*  @返回值   无   
*  @注意    无
********************************************************************************************************/
void S_QueueEmpty(unsigned char **Head, unsigned char **Tail, unsigned char *HBuff)
{
		*Head = HBuff;
		*Tail = HBuff;
}

3、入列函数

/********************************************************************************************************
*  @函数名   S_QueueDataIn						                                                           
*  @描述     输入一个字节数据进队列								                                     
*  @参数     Head-队列头地址,  Tail-队列尾地址,   HBuff-队列缓存
*  @返回值   无   
*  @注意     无
********************************************************************************************************/
void S_QueueDataIn(unsigned char **Head, unsigned char **Tail, unsigned char *HBuff, unsigned short Len, unsigned char *HData, unsigned short DataLen)
{	
	unsigned short num;
	unsigned char IptStatus;
	
	if(CPUInterruptCtrlCBS != 0)
	{
		CPUInterruptCtrlCBS(CPU_ENTER_CRITICAL,&IptStatus);
	}
	for(num = 0; num < DataLen; num++, HData++)
	{
			**Tail = *HData;
			(*Tail)++;
			if(*Tail == HBuff+Len)
				*Tail = HBuff;
			if(*Tail == *Head)
			{
					if(++(*Head) == HBuff+Len)
						*Head = HBuff;		
			}
	}	
	if(CPUInterruptCtrlCBS != 0)
	{
		CPUInterruptCtrlCBS(CPU_EXIT_CRITICAL,&IptStatus);
	}
}

4、出列函数

/********************************************************************************************************
*  @函数名   S_QueueDataOut						                                                           
*  @描述     从队列里取出一个数据								                                     
*  @参数     Head-队列头地址,  Tail-队列尾地址,   HBuff-队列缓存
*  @返回值   取出的数据   
*  @注意     无
********************************************************************************************************/
unsigned char S_QueueDataOut(unsigned char **Head, unsigned char **Tail, unsigned char *HBuff, unsigned short Len, unsigned char *Data)
{					   
	unsigned char back = 0;
	unsigned char IptStatus;
	if(CPUInterruptCtrlCBS != 0)
	{
		CPUInterruptCtrlCBS(CPU_ENTER_CRITICAL,&IptStatus);
	}
	*Data = 0;
	if(*Tail != *Head)
	{
			*Data = **Head;
			back = 1; 				
			if(++(*Head) == HBuff+Len)
				*Head = HBuff;
	}
	if(CPUInterruptCtrlCBS != 0)
	{
		CPUInterruptCtrlCBS(CPU_EXIT_CRITICAL,&IptStatus);
	}
	return back;	
}

5、获取队列里数据个数函数

/********************************************************************************************************
*  @函数名   S_QueueDataLen						                                                           
*  @描述     判断队列里数据的长度							                                     
*  @参数     Head-队列头地址,  Tail-队列尾地址,   HBuff-队列缓存
*  @返回值   队列里有数据个数
*  @注意     无
********************************************************************************************************/
unsigned short S_QueueDataLen(unsigned char **Head, unsigned char **Tail, unsigned short Len)
{
		if(*Tail > *Head)
			return *Tail-*Head;
		if(*Tail < *Head)
			return *Tail+Len-*Head;
		return 0;
}

6、用法展示

Queue8  TestSend; // 开辟一个八个字节的队列

void hal_LedInit(void)
{
	unsigned char dat;
	hal_ledConfig();
	QueueEmpty(TestSend);  // 清空队列
	
	dat = 1;
	QueueDataIn(TestSend,&dat,1);
	
	dat = 2;
	QueueDataIn(TestSend,&dat,1);
	
	dat = 3;
	QueueDataIn(TestSend,&dat,1);
	
	
}

void hal_LedProc(void)
{
	unsigned char dat;
	static unsigned short i = 0;
	i++;
	if(i > 100)
	{
		i=0;
		hal_LedTurn();
	}
	
	QueueDataOut(TestSend,&dat);
	QueueDataOut(TestSend,&dat);
	QueueDataOut(TestSend,&dat);
}

7、在线仿真测试代码

在出列函数那里设置断点,查看dat的值的变化

?

?内核代码链接:

链接:https://pan.baidu.com/s/18UnOCch5dZd4ZJq3V8yGgA?
提取码:8zrs

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-10-12 23:37:07  更:2021-10-12 23:37:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:01:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码