真正的单片机程序框架------->小巧的软件定时器....O(∩_∩)O
本帖最后由 misra 于 2021-3-11 20:13 编辑#申请原创#
还在用各种标志位 全局变量搞定时器,换种更优雅的方式吧{:smile:}好了首先搞个需求引入 软件定时器的这个话题吧。
需求1:让4个任务分别以1000ms、500ms、500ms、800ms周期性执行。怎么弄?{:sweat:}直接给出需求1的代码:/*-----------------------------------------------------*/void test1(void)
{
MLPeriod.init();
while (1) {
MLPeriod.run();
if (MLPeriod.check(1000)) {
//task1
}
if (MLPeriod.check(500)) {
//task2
}
if (MLPeriod.check(500)) {
//task3
}
if (MLPeriod.check(800)) {
//task4
}
}
}
/*-----------------------------------------------------*/
需求2:让20个变量,分别以111,111,123,127,118,99,88,58,58,47,33,38,29,1111,2456,678,6789,457,451,20毫秒 周期性变化。 怎么弄?{:dizzy:}直接给出应用代码:/*-----------------------------------------------------*/ml_u32_t var[20] = {0}; //20个变量
ml_u32_t init_period[20] = {111, 111, 123, 127, 118, 99, 88, 58, 58, 47, 33, 38, 29, 1111, 2456, 678, 6789, 457, 451, 20}; //20个变量的周期值
void test (void)
{
ml_u32_t j;
MLPeriod.init();
while (1) {
MLPeriod.run();
for (j = 0; j < 20; j++) {
if (MLPeriod.check(init_period)) {
var++;
}
}
}
}
/*-----------------------------------------------------*/
代码是不是看起来很简单 没错!使用起来就是这么简单。
源码在1楼
有疑问或者建议请跟帖回复。
本帖最后由 misra 于 2021-3-13 19:42 编辑
1楼占个位
源码链接(21IC这个超链接似乎不好用,大家费点事,复制粘贴吧{:titter:}):
https://github.com/steven-lyan/microLite_timer/blob/main/src/microLite_timer.h
https://github.com/steven-lyan/microLite_timer/blob/main/src/microLite_timer.c
移植到51单片机的视频(电脑浏览器 单击鼠标全屏):
更多内容可关注微信公众号:microLite裸机系统
如果有空的话 ,可以去50楼逛一逛。
//1ms定时中断
u16 g_usTick;
void ISR_1ms(void)
{
g_usTick++;
}
u16 GetCurTick(void)
{
u16 ulTmp;
__disable_int();
ulTmp = g_usTick;
__enable_int();
return ulTmp;
}
u16 g_TaskVal;
u16 g_TaskBase = {0};
const u16 TASK_IVL = {111,456,123,127,118,99,88,77,58,47,33,38,29,1111,2456,678,6789,457,451,20};
void main(void)
{
Init();
while (1)
{
u8 i;
for (i=0; i<20; i++)
{
if (GetCurTick() - g_TaskBase >= TASK_IVL)
{
g_TaskVal++;
g_TaskBase += TASK_IVL;
}
}
}
} ayb_ice 发表于 2021-2-25 09:48
一看就是很牛的了{:lol:}
再给你来个
一个灯亮3秒后 灭,111ms后亮,88ms后灭,999ms后亮 misra 发表于 2021-2-25 10:02
一看就是很牛的了
再给你来个
void main(void)
{
Init();
while (1)
{
u8 i;
for (i=0; i<20; i++)
{
if (GetCurTick() - g_TaskBase >= TASK_IVL)
{
g_TaskVal++;
g_TaskBase += TASK_IVL;
}
}
if (1)
{
void LED_Ctrl(void);
LED_Ctrl();
}
}
}
//一个灯亮3秒后 灭,111ms后亮,88ms后灭,999ms后亮
void LED_Ctrl(void)
{
static u8 s_ucLedStage = 0;
static u16 s_ulBase;
static bLed;
switch(s_ucLedStage)
{
case 0:
bLed = 1;
if (GetCurTick() - s_ulBase >= 3000)
{
bLed = 0;
s_ucLedStage++;
s_ulBase = GetCurTick();
}
break;
case 1:
if (GetCurTick() - s_ulBase >= 111)
{
bLed = 1;
s_ucLedStage++;
s_ulBase = GetCurTick();
}
break;
case 2:
if (GetCurTick() - s_ulBase >= 88)
{
bLed = 0;
s_ucLedStage++;
s_ulBase = GetCurTick();
}
break;
case 3:
if (GetCurTick() - s_ulBase >= 999)
{
bLed = 1;
s_ucLedStage++;
s_ulBase = GetCurTick();
}
break;
case 4:
//完成
break;
if (bLed)
{
LED_ON();
}
else
{
LED_OFF();
}
}
} misra 发表于 2021-2-25 10:02
一看就是很牛的了
再给你来个
针对这个问题,实际上我有专门的驱动来实现,但不是一两句代码能说的清楚的,分两步调用,第 一步
3000+111,完成后再调用88+999 就这,你十年功力,就玩这个。你就这个东西是很普通的软件定时器,到处都是源码,linux,和一些开源软件都有。
很多RTOS都有。
是定时器任务,不是什么框架。
看看下面这个才叫做framwork
http://www.state-machine.com/ 来个通用版的
typedef struct{
u8 ucMax;
u8 ucCur;
bool bStart;
bool bOut;
u16 ausTick; //最大8个状态
u16 usBase;
}LED_Typedef;
LED_Typedef g_stLed;
void LED_Init(u16* pTick, bool bOut, u8 ucMax)
{
u8 i;
g_stLed.ucMax = ucMax;
g_stLed.bOut = bOut;
for (i=0; i<ucMax; i++)
{
g_stLed.ausTick = pTick;
}
g_stLed.ucCur = 0;
g_stLed.usBase = GetCurTick();
g_stLed.bStart = 1;
}
void LED_Ctrl(void)
{
if (g_stLed.bStart)
{
if (GetCurTick() - g_stLed.usBase >= g_stLed.ausTick)
{
g_stLed.bOut = !g_stLed.bOut;
g_stLed.usBase = GetCurTick();
g_stLed.ucCur++;
if (g_stLed.ucCur >= g_stLed.ucMax)
{
g_stLed.bStart = 0;
}
}
if (g_stLed.bOut)
{
LED_ON();
}
else
{
LED_OFF();
}
}
}
void main(void)
{
Init();
if (1)
{
//一个灯亮3秒后 灭,111ms后亮,88ms后灭,999ms后亮
const u16 LED_TABLE[] = {3000,111,88,999};
LED_Init(LED_TABLE, 1, 4);
}
while (1)
{
u8 i;
for (i=0; i<20; i++)
{
if (GetCurTick() - g_TaskBase >= TASK_IVL)
{
g_TaskVal++;
g_TaskBase += TASK_IVL;
}
}
if (1)
{
void LED_Ctrl(void);
LED_Ctrl();
}
}
} 支持百家争鸣,百花齐放
都来发下吧, 非常简单的一个定时呀,一个计数器就可以分别产生 非常棒。 20楼,早就有了 +1=14 用RTOS不就可以了,创建4个任务,各干各的。 进来看看。 凑楼数 八仙过海,各显神通。。。。 看看楼主怎么实现的?
这个可以学习下