单片机软件系统框架和多任务调度

2023-10-26

弄成图片貌似比较好保存
这里我用的单片机算是中颖的sh79f9401芯片

UART底层驱动相关函数:
	
		//UART相关寄存器初始化
		void Uart_Init(void)
		{
			PCON = 0x00;//选择SSTAT0
			SCON = 0x50;//01000000  方式一
			SBRTL = (u8int)(_SBRT & 0xFF);
			SBRTH= (u8int)((0x80)|((_SBRT >> 8) & 0xFF));
			SFINE = _SFINE;
			ES0 = 1;//允许EUART0中断 
		}
		
		//UART中断服务程序
		void	EUART_0_ISP(void) interrupt 4
		{
			if(TI)
			{
				TI = 0;
				Drv_Uart_Tx_It_Handle(UART_PORT_0);
			}
			if(RI)
			{
				RI = 0;
				Drv_Uart_Rx_It_Handle(UART_PORT_0,SBUF);
			}
		}
		
		//UART发送一Byte数据
		void Drv_Hardware_uart_SendByte(UART_PORT_TYPE ePort,char Data)
		{
			if(ePort == UART_PORT_0)
			{
				ACC = Data;
				SBUF = ACC;载入要发送的数据	
			}
		}
		
		
中间层UART相关函数:
		#define _DRV_UART_C_
		#include "drv.h"
		#include "mw_uart.h"
		
		//这里是发送和接受数据的缓冲区
		u8int Uart_0_TxBuf[UART_0_TX_SIZE] = {0};//UART_0_TX_SIZE在uart.h头文件里根据需求和硬件资源自定义大小
		u8int Uart_0_RxBuf[UART_0_RX_SIZE] = {0};//UART_0_RX_SIZE在uart.h头文件里根据需求和硬件资源自定义大小
		
		//UART相关结构体
		typedef struct
		{
			u8int * pu8TxAdd;//添加数据的地址,该地址数据无效
			u8int * pu8TxValid;//有效数据的首
			u8int * pu8TxMinAddr;//缓冲区最小地址
			u8int * pu8TxMaxAddr;//缓冲区最大地址
			u8int u8TxBufDataSize;//缓冲区已使用空间,有效数据大小
			BOOL bTxIsStop;//中断是否在发送标记
		
			u8int * pu8RxAdd;
			u8int * pu8RxValid;
			u8int * pu8RxMinAddr;
			u8int * pu8RxMaxAddr;
			u8int u8RxBufDataSize;
		}DRV_UART_INFO;
		DRV_UART_INFO sDrvUartInfo[1];
		
		//初始化UART数据缓冲区
		void MW_Uart_Data_Init(void)
		{
			sDrvUartInfo[UART_PORT_0].pu8TxAdd = &Uart_0_TxBuf[0];
			sDrvUartInfo[UART_PORT_0].pu8TxValid = &Uart_0_TxBuf[0];
			sDrvUartInfo[UART_PORT_0].pu8TxMinAddr = &Uart_0_TxBuf[0];
			sDrvUartInfo[UART_PORT_0].pu8TxMaxAddr = &Uart_0_TxBuf[UART_0_TX_SIZE - 1];
			sDrvUartInfo[UART_PORT_0].u8TxBufDataSize = 0;
			sDrvUartInfo[UART_PORT_0].bTxIsStop = TRUE;
			sDrvUartInfo[UART_PORT_0].pu8RxAdd = &Uart_0_RxBuf[0];
			sDrvUartInfo[UART_PORT_0].pu8RxValid = &Uart_0_RxBuf[0];
			sDrvUartInfo[UART_PORT_0].pu8RxMinAddr = &Uart_0_RxBuf[0];
			sDrvUartInfo[UART_PORT_0].pu8RxMaxAddr = &Uart_0_RxBuf[UART_0_RX_SIZE - 1];
			sDrvUartInfo[UART_PORT_0].u8RxBufDataSize = 0;
		}
		
		//将需要发送的数据添加到待发送的数据缓冲区,所有数据实际上是再终端里面发送
		void MW_Uart_Send_Data_Add(UART_PORT_TYPE ePort,u8int * buf,u16int Size)
		{
			u8int Len = 0;
			//if((UART_0_TX_SIZE - sDrvUartInfo[ePort].u8TxBufDataSize) >= Size)
			{剩余空间比要发送的数据大才会发送,否则丢弃要发送的数据
				sDrvUartInfo[ePort].u8TxBufDataSize = sDrvUartInfo[ePort].u8TxBufDataSize + Size;更新剩余空间大小
				while(Len < Size)
				{
					*sDrvUartInfo[ePort].pu8TxAdd = buf[Len];
					if(sDrvUartInfo[ePort].pu8TxAdd < sDrvUartInfo[ePort].pu8TxMaxAddr)
					{
						sDrvUartInfo[ePort].pu8TxAdd ++;
					}
					else
					{
						sDrvUartInfo[ePort].pu8TxAdd = sDrvUartInfo[ePort].pu8TxMinAddr;
					}
					Len ++;
				}
				if(sDrvUartInfo[ePort].bTxIsStop)
				{
					sDrvUartInfo[ePort].bTxIsStop = FALSE;
					Drv_Hardware_uart_SendByte(ePort,*sDrvUartInfo[ePort].pu8TxValid);
				}
			}
		}
		
		
		//这个是中断发送函数
		void MW_Uart_Tx_It_Handle(UART_PORT_TYPE ePort)
		{	
			对上次中断进行指针移动同时更新剩余空间大小
			sDrvUartInfo[ePort].u8TxBufDataSize --;
			if(sDrvUartInfo[ePort].pu8TxValid < sDrvUartInfo[ePort].pu8TxMaxAddr)
			{
				sDrvUartInfo[ePort].pu8TxValid ++;
			}
			else
			{
				sDrvUartInfo[ePort].pu8TxValid = sDrvUartInfo[ePort].pu8TxMinAddr;
			}
			
			如果发送剩余空间小于缓冲区大小说明还有数据等待发送
			if(sDrvUartInfo[ePort].u8TxBufDataSize > 0)
			{
				Drv_Hardware_uart_SendByte(ePort,*sDrvUartInfo[ePort].pu8TxValid);
			}
			else
			{
				sDrvUartInfo[ePort].bTxIsStop = TRUE;
			}
		}
		
		//这个是中断接收函数
		void MW_Uart_Rx_It_Handle(UART_PORT_TYPE ePort,u8int Data)
		{
			//if(sDrvUartInfo[ePort].u8RxBufDataSize < UART_0_RX_SIZE)缓冲区空间没满,填数据,否则丢弃数据
			{
				直接往缓冲里填接收到的数据
				*sDrvUartInfo[ePort].pu8RxAdd = Data;
				sDrvUartInfo[ePort].u8RxBufDataSize ++;
				if(sDrvUartInfo[ePort].pu8RxAdd == sDrvUartInfo[ePort].pu8RxMaxAddr)
				{
					sDrvUartInfo[ePort].pu8RxAdd = sDrvUartInfo[ePort].pu8RxMinAddr;
				}
				else
				{
					sDrvUartInfo[ePort].pu8RxAdd ++;
				}
			}
		}
		
		//用户获取从串口接收到的数据
		void MW_Uart_Get_Rx_Data(UART_PORT_TYPE ePort,UART_UserDataType *psData)
		{
			u16int u16Count = 0;
			u8int* pu8UserBuf;
			u8int *pu8GetData;
			pu8UserBuf = &psData->u8UserData[0];
			pu8GetData = sDrvUartInfo[ePort].pu8RxValid;
			while(u16Count < sDrvUartInfo[ePort].u8RxBufDataSize)复制所有数据
			{
				*pu8UserBuf = *pu8GetData;
				if(pu8GetData == sDrvUartInfo[ePort].pu8RxMaxAddr)
				{
					pu8GetData = sDrvUartInfo[ePort].pu8RxMinAddr;
				}
				else
				{
					pu8GetData++;
				}
				pu8UserBuf++;
				u16Count ++;
			}
			psData->u16Size = sDrvUartInfo[ePort].u8RxBufDataSize;
		}
		
		//用户获取从串口接收到的数据后应当释放相应大小的缓冲区数据
		void MW_Uart_Free_Rx_Buffer(UART_PORT_TYPE ePort, u8int u8Len)
		{
			while (u8Len --)
			{
				if (sDrvUartInfo[ePort].pu8RxValid == sDrvUartInfo[ePort].pu8RxMaxAddr)
				{
					sDrvUartInfo[ePort].pu8RxValid = sDrvUartInfo[ePort].pu8RxMinAddr;
				}
				else
				{
					sDrvUartInfo[ePort].pu8RxValid ++;
				}
				sDrvUartInfo[ePort].u8RxBufDataSize --;
			}
		}

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

单片机软件系统框架和多任务调度 的相关文章

  • C++程序员应了解的那些事(117)~进程、线程、协程

    相关博文 程序员应了解的那些事 111 进程 线程及堆栈关系 线程堆栈 so what的博客 CSDN博客 概念与区分 1 进程 进程是程序一次动态执行的过程 是程序运行的基本单位 每个进程都有自己的独立内存空间 不同进程通过进程间通信来通
  • angular路由传参和获取路由参数的方法

    1 首先是需要导入的模块 import Router from angular router 路由传参用到 import ActivatedRoute Params from angular router 获取路由传参用到 2 第二步 注入
  • 3DMAX、MAYA、C4D区别

    一 3Dmax 优势 1 3DMAX主要面向建筑动画 bai建筑漫游和室内设计 用于室du内和室外渲染的基本建zhi模 材料分配 映射使用和照明创建的图形文件 2 3DMAX软件的应用主要是动画制作 游戏动画制作 建筑效果图 建筑动画等 3
  • STL——list详解

    一 list基本使用 1 1 初始化 在C 11之前 std list容器没有提供初始化列表的构造函数 因此需要使用push back或push front函数向列表中添加元素 以下是一些常见的std list初始化方式 使用默认构造函数创
  • javascript对任意颜色获取更亮或更暗的颜色值

    预处理CSS 比如Sass和less可以通过设定一个特定值 让任何颜色变得更亮或者更暗 但是在javascript中却没有这种方法 下面这个方法能在javascript中得到一个更亮或者更暗的值 通过一个给定的十六进制颜色值 比如 F06D
  • 【数据分析】基于RFM模型的线上零售中的客户细分(二):RFM模型实战

    基于RFM模型的线上零售中的客户细分 二 摘要 在上一篇博客 基于RFM模型的线上零售中的客户细分 一 客户细分 中 我们了解了什么是客户细分 这篇博客将会结合具体的商业实例介绍同期群分析 RFM模型 并利用K Means聚类算法在RFM模
  • 【已解决】XAMPP无法启动mysql

    最近在学习安卓开发 为了免于自己搭服务器 选择连接到XAMPP的mysql数据库 在这贴出自己遇到的一些问题 It seems that the port 3306 is already in use aer you sure you wa
  • ubuntu系统安装Anaconda与使用入门

    一 什么是Anaconda Anaconda是一个开源的Python发行版本 包含了conda Python等180多个科学包及其依赖项 可以用于包管理器和环境管理 比如A项目中用了Python2 而B项目使用Python3 而同时安装两个
  • Pygame实战:Python开挂版无敌小恐龙【源码免费领】

    导语 hi 大家好呀 你们还记得 很久很久以前 那只谷歌断网之后的
  • 通俗解释卡尔曼滤波

    汽车位置p和速度v例子 有点矩阵 https blog csdn net codesamer article details 81191487 飞机速度和位置 跟上面差不多 但是无矩阵 https blog csdn net varysha
  • nexus 搭建maven私服

    环境是 nexus 2 7 0 maven 3 1 1 jdk 1 7 45 CentOs 6 2 一 首先从首先从 http nexus sonatype rog downloads 下载最新版的Nexus 目前最新的版本是 nexus
  • Docker学习(23)——Docker 三剑客之 Docker Swarm集群(图形化界面管理swarm集群、添加服务等等,更方便)

    搭建过程如下 这个是基于上一片篇文章写的 1 在server1上面清空之前的所有的web服务和监控服务 我们接下来使用更加牛逼的图形化管理界面 比命令 文件的部署方式简单多了 2 可以看到server2 server3 server4上面的
  • Android减小Apk包大小的常用方法

    我们之所以要减小apk的大小 一方面是为了节省用户手机的内存 另一方面是为了节省用户在App安装和版本升级时的流量 直接减小apk文件大小的方法 1 使用图片压缩工具 目前常用的工具是 ImageOptim 压缩效果很好 使用默认配置即可
  • js 时分秒 转换为 秒

    p p
  • HTML+CSS小实战案例

    HTML CSS小实战案例 登录界面的美化 综合最近所学进行练习 网页设计先布局 搭建好大框架 然后进行填充 完成页面布局 1 2 3 4 5
  • GitHub Star超3.3K的超实用AI工具,涵盖OCR、目标检测、NLP、语音合成多个方向

    点击左上方蓝字关注我们 今天为大家推荐一个相当牛的项目 本周暴涨1300 Star 厚着脸皮大胆预判 这个项目肯定能更火 未来Star数应该可以到10k甚至20k 着急的 可以Github直接去看源码 传送门 https github co
  • 互联网上年入10万的新玩法?

    这句话说的有道理 不要用战术上的勤奋掩盖战略上的懒惰 战略是一个宏大的全局框架 总体构思 战术是微观层面的具体细节 执行步骤 做好每日复盘才能及时调整方向 完善正确的战略决策 不要闭门造车 多结交有价值的人脉圈子 经年累月耳濡目染就会变得和
  • OpenSea上如何创建自己的NFT(Polygon)

    发现 收藏和销售非凡的艺术品NFT OpenSea 是世界上第一个也是最大的 NFT 市场 一起来了解下如何通过Polygon网络 创建自己喜爱的NFT艺术品并进行收藏和交易 Polygon网络解决了ETH网络高昂的GAS费用和拥堵问题 使
  • 小程序canvas绘制邀请码

    针对小程序邀请好友功能 可以下载当前的海报图 分享给好友 好友通过扫描二维码跳转至小程序 但是邀请好友 要根据当前登录者的信息去生成二维码 目的是把邀请到的好友绑定到该用户下 所以会将二维码嵌入背景海报中 合成一张图后 生成一个临时地址 再

随机推荐