嵌入式_一种非常简单实用的基于GD32的裸机程序框架

news2024/9/22 17:19:35

嵌入式_一种非常简单实用的基于GD32的裸机程序框架

搜索了一下关于GD或ST裸机程序的问题,网上有非常多也非常的例子,但是针对裸机开发的程序框架却比较少,这里简单整理了一下在项目中使用过的一种比较小巧便携的裸机程序框架(确切点说算不上框架,只能说一种写法)。


文章目录

  • 嵌入式_一种非常简单实用的基于GD32的裸机程序框架
  • 前言
  • 一、框架原理
  • 二、步骤分析
    • 1.定时器中断配置
    • 2.中断函数
    • 3.任务管理函数
    • 4.主函数
  • 总结


前言

之前常见的裸机程序框架就是流水账框架,比如某个做STM32开发系列教程的****团队,先是一堆初始化,然后一个大while循环,循环里面可以无限添加代码,一个功能一个函数往里加,随着经手的coder越来越多,一行一行往上加,慢慢得就成了屎山代码。我在第一家公司曾经接收手一个七代单传流传下来的祖传代码,一个main函数就有260多行,while循环占了一大半,结构冗余,效率极低。后来花大力气改了框架直接重构。

这个框架基于GD32F103CBT6硬件平台,标准的72MHz系统时钟, 使用标准库GD32F10x_Firmware_Library_V1.0.0此库坑多慎用


一、框架原理

框架大致原理就是使用定时器模拟一个实时操作系统,每1ms产生一个中断并进行累加计数,计数到10、50、100、500、1000时会对相关的标记位置位,表示此时间对应的函数应该执行,在主函数中while(1)循环就是对标记位进行判断并执行对应的任务函数和对标记位进行复位,说白了就是模拟的一个非常简单的μC-OS操作系统,大致原理图如图所示。
在这里插入图片描述

二、步骤分析

1.定时器中断配置

为了不占用资源,我们选择使用系统自带的滴答定时器,是其产生1ms中断,并且要保证其优先级最高,使其不被其他中断打断。

代码如下(示例):

/**
  * @brief  Configure SysTick.
  * @param  None
  * @retval None
  */
void SysTick_Configuration(void)
{    
    /* Setup SysTick Timer for 108Hz interrupts */
    if (SysTick_Config(SystemCoreClock / 1000)) // 1ms tick
    {
        /* Capture error */
        while (1);
    }
    /* Configure the SysTick handler priority */
    NVIC_SetPriority(SysTick_IRQn, 0x00);
}

2.中断函数

中断函数中,我们使用静态局部变量对中断次数进行累计并判断,在时间性要求不高的情况下,为了保证各个任务可错开,我们进行取模运算来判断是否触发相关任务,如果触发则对标记位数组中的对应位置位。
代码如下(示例):

#define TASKFUNNUMBER  		6
#define TASKMAXCOUNTER		6000

typedef struct
{
	uint16_t Period;
	uint16_t Remainder;
}TaskTimeType;

static uint8_t TaskFlag[TASKFUNNUMBER] = {0, 0, 0, 0, 0, 0};
static TaskTimeType TimeArr[TASKFUNNUMBER] = 
 {
   {10, 2},
   {50, 49},
   {100, 97},
   {500, 497},
   {1000, 999},
   {2000, 1999}
 };
 
void Task_1msNotification(void)
 {
   static uint16_t Counterms = 0;
   uint8_t i = 0;
  
	 if(1msCounter > TASKMAXCOUNTER)
	 {
			1msCounter = 0;
	 }
	 else
	 {
			Counterms ++;

			for(i = 0; i < TASKFUNNUMBER; i++)
			{
				if((Counterms % TimeArr[i].Period) == TimeArr[i].Remainder)
				{
					TaskFlag[i] = TRUE;
				}
			}
	 }
}

3.任务管理函数

轮询判断标记位数组中的各个标记位,如果被置位,则通过函数指针调用相关时间片函数即可。
代码如下(示例):

typedef void (*TaskFunType)(void);

static TaskFunType TaskFunPtr[TASKFUNNUMBER] = 
 {
   &TASK_10msFunc,
   &TASK_50msFunc,
   &TASK_100msFunc,
   &TASK_500msFunc,
   &TASK_1000msFunc
   &TASK_2000msFunc
 };
 
void MainFunction(void)
 {
   uint8_t i = 0;
   
   for(i = 0; i < TASKFUNNUMBER; i++)
   {
     if(TaskFlag[i] == TRUE)
     {
       if(TaskFunPtr[i] != NULL)
       {
         TaskFunPtr[i]();
         TaskFlag[i] = FALSE;
       }
     }
   }
 }

4.主函数

主函数中先对各个模块进行初始化,初始化完成后在while(1)循环中调用上面的MainFunction()函数,轮流调用执行时间片函数,其他各个模块例如LED或串口模块的使用只需要在对应的时间片函数中即可。
代码如下(示例):

int main(void)
{
  SystemInit();
  SysTick_Configuration();
  IO_Init();
  USART0_Init();
  SPI_Init();
  LED_Init();
  Appliction_Init();
  FWDG_Init();
  while(1)
  {
    MainFunction();
  }  
}

void TASK_10msFunc(void)
{
	//Appliction();
}
void TASK_50msFunc(void)
{
	//LED_ManageFunc();
	//SPI_SendManageFunc();
}
void TASK_100msFunc(void)
{
}
void TASK_500msFunc(void)
{	
	//Usart_SendManageFunc();
}
void TASK_1000msFunc(void)
{
	//LED_ManageFunc();
}
void TASK_2000msFunc(void)
{
	//FWDG_FeedWdg();
}

总结

之前在一个项目中使用这种框架,还是比较方便,可以根据各个模块的时间要求选择对应的时间片函数,比如我需要1秒反转一次LED灯,我就直接将反转函数写入1s任务中,不会像“流水账”框架由于某些任务执行时间长短不一而导致我的LED反转时间误差较大,这种框架(确切点说算不上框架)主打就是一个简单便携,如果有什么疑问欢迎留言讨论,有言必回!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/739875.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

cloud Alibab+nacos+gateway集成swaggerui,统一文档管理(注意点)

首先说明&#xff1a;本文只说整合注意点 效果图和功能参考链接 1.使用gateway访问nacos服务&#xff0c;503 在网关服务添加依赖即可解决 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign&…

1.入门matlab数理统计随机数的产生(matlab程序)

1.简述 一、常见分布的随机数的产生 随机数是专门的随机试验的结果。在统计学的不同技术中需要使用随机数&#xff0c;比如在从统计总体中抽取有代表性的样本的时候。而matlab直接提供了产生随机数的通用函数&#xff0c;但针对不同的分布&#xff0c;函数形式会有所不同&#…

DITA技巧:将DITA或Markdown发布成CHM

- 1 - 场景 CHM是英文Compiled HTML Help的缩写&#xff0c;是微软公司专有的联机帮助格式&#xff0c;由HTML页面、索引和其他导航工具的集合组成。这些文件被压缩并部署为二进制格式&#xff0c;扩展名为.CHM&#xff0c;用于编译HTML。CHM格式通常用于软件文档。 虽然CHM…

16. 最接近的三数之和(双指针+减去多余步骤)

16. 最接近的三数之和 双指针减去多余步骤测试代码测试结果 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1&#xff1a; 输入&…

JSP环境搭建教程(保姆级!!)

简介 Java Server Pages (JSP) 是一种由 Sun Microsystems 开发的用于创建动态网页的技术。它是 Java EE (Java Enterprise Edition) 技术的一部分&#xff0c;允许开发者在 HTML 中嵌入 Java 代码&#xff0c;从而实现动态内容的生成。 JSP 主要由两部分组成&#xff1a;静态…

LiveGBS流媒体平台GB/T28181功能-如何对接海康大华宇视等监控摄像头报警消息报警订阅国标报警信息

LiveGBS流媒体平台GB/T28181功能-如何对接海康大华宇视等监控摄像头报警消息报警订阅国标报警信息 1、报警信息1.1、报警查询1.2、配置开启报警订阅1.2.1、国标设备编辑1.2.2、选择开启报警订阅 1.3、配置摄像头报警1.3.1、配置摄像头报警通道ID1.3.2、配置摄像头开启侦测1.3.3…

红外雨量计(光学雨量传感器)在预防地质灾害中怎样发挥作用

红外雨量计&#xff08;光学雨量传感器&#xff09;在预防地质灾害中怎样发挥作用 红外雨量计是一种利用红外线原理测量雨量的设备。在预防地质灾害中&#xff0c;红外雨量计可以发挥以下作用&#xff1a; 1.准确测量雨水的降雨量。地质灾害往往与雨水的降雨量密切相关&#x…

【Java EE】-JVM

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的主页&#x1f319; 专栏&#xff1a;【JavaEE】 分享: 雨下整夜 我的爱溢出就像雨水 ——《七里香》 主要内容&#xff1a;JDK&#xff0c;JRE&#xff0c;JVM三者之间的联系。JVM内存区域划分&#xff1a;本地方法栈…

物联网技术的智能配电室综合监控系统设计

安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;配电室是电力系统的重要基础设施&#xff0c;可以保障供配电系统的安全稳定运行。但是&#xff0c;配电室数量多、部署分散、管理复杂&#xff0c;人工现场巡检管理方式费时费工、错误率高&#xff0c;如果发生故障隐…

智能工厂-亿发生产型企业信息化ERP管理系统,打造智能制造工业

对于制造业来说&#xff0c;生产就是发展的动力。传统制造工厂在生产管理中存在很多不足和缺点&#xff0c;流程管理混乱&#xff0c;生产状态不稳定。在制造工厂中实施机械生产工厂ERP管理系统可以解决生产管理中低效率问题&#xff0c;使得制造工厂向着更科学化、智能化的方向…

ETHERNET/IP转RS485/RS232网关profinet与Ethernet通讯卡

网络数据传输遇到的协议不同、数据互通麻烦等问题&#xff0c;一直困扰着大家。然而&#xff0c;现在有一种神器——远创智控YC-EIP-RS485/232&#xff0c;它将ETHERNET/IP网络和RS485/RS232总线连接在一起&#xff0c;让数据传输更加便捷高效。 那么&#xff0c;它是如何实现…

Jmeter接口关联(一)【使用json层级方式提取值】与python中使用层级方式提取值 完成接口关联

文章目录 前言一、按照 json 的路径来提取 ​​​​​​​&#xff08;1&#xff09;成功匹配到数据的案例&#xff08;按照层级匹配&#xff09;&#xff08;2&#xff09;失败未匹配到数据的案例&#xff08;没有按照层级匹配&#xff09;json提取器二、使用完整的接口关联&a…

地方废物回收机构管理系统

方废物回收机构管理系统的开发运用java技术&#xff0c;MIS的总体思想&#xff0c;以及MYSQL等技术的支持下共同完成了该系统的开发&#xff0c;实现了地方废物回收机构的信息化&#xff0c;使用户体验到更优秀的地方废物回收机构管理&#xff0c;管理员管理操作将更加方便&…

奔赴猿田地,开垦一亩三分产

点击上方蓝色字体&#xff0c;选择“设为星标” 回复”云原生“获取基础架构实践 大家好&#xff0c;很久没开荒了&#xff0c;最近一直在想着要不要开始分享最近的一些小技术&#xff0c;看到互联网泡沫化日益严重&#xff0c;程序猿下岗失业&#xff0c;bibi皆是。但不管外界…

Linux如何设置固定IP

首先&#xff0c;Linux的默认网关和DNS解析都是一个地址。 IPV4 IP地址是32位2进制 前缀默认是24但是格式还是得写 DNS解析域名&#xff0c;类似Map&#xff0c;根据域名寻找IP DHCP 如果是自动设置IP&#xff0c;就是由他来自行分配&#xff0c;但是手动的话&#xff0c;就需…

软件测试-基础篇

一、接口的认识 什么是接口 电脑&#xff1a;USB&#xff0c;投影机&#xff08;数据传输&#xff09; 软件&#xff1a;API&#xff0c;application program interface.微信提现与充值&#xff0c;支付宝支付&#xff0c;银联支付接口。&#xff08;鉴权码&#xff1a;token…

港联证券|暑期亲子游和避暑游需求旺盛 数据要素产业价值有望加速释放

上周五&#xff0c;A股再度回调&#xff0c;沪指失守3200点&#xff0c;创业板指、科创50指数跌约1%。截至收盘&#xff0c;沪指跌0.28%报3196.61点&#xff0c;深成指跌0.73%报10888.55点&#xff0c;创业板指跌1.05%报2169.21点&#xff0c;科创50指数跌1.02%&#xff1b;两市…

Vue生态及实践 - Nuxt

Nuxt.js Nuxt.js - Vue.js 通用应用框架 | Nuxt.js 中文网 Nuxt.js 中文教程_w3cschool 开源社区仁人志士创建了开箱可用的&#xff1a;Nuxt.js框架&#xff0c;帮助我们更快的实现ssr的同构。 Nuxt.js是一个基于Vue.js的通用应用框架它是对客户端&#xff0c;服务端基础架…

LeetCode 打卡day59--单调栈

一个人的朝圣 — LeetCode打卡第59-60天 知识总结 Leetcode 739. 每日温度题目说明代码说明 Leetcode 496. 下一个更大元素 I题目说明代码说明 Leetcode 84. 柱状图中最大的矩形题目说明代码说明 知识总结 今天做了单调栈的三道题 总结了一个模版套路: 寻找下一个更大的数 f…

Spring IOC - Bean的扫描

Component及其衍生注解&#xff1a;Configuration、Controller、Service、Repository标记的类&#xff0c;被Spring IOC扫描到后&#xff0c;即可被容器管理起来。其原理基本涵盖在AnnotationConfigApplicationContext构造函数体的三行代码里。 public AnnotationConfigApplic…