博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32系统滴答_及不可不知的延时技巧 - (下)
阅读量:6576 次
发布时间:2019-06-24

本文共 4183 字,大约阅读时间需要 13 分钟。

  hot3.png

下面为大家介绍一个曾见过的在裸机系统中,非阻塞延时的巧妙设计,当时它是被用在一导航影音娱乐系统的MCU驱动软件中,在此我对其作了一定的改动。

此章节涉及到STM32内容不多,以软件为主。

此延时软件的设计可以直接进行1050100ms1s的查询定时,并且当若需其它时间要求的定时或延时可以很方便的自己编写软件很简单方便设定。

 

首先需要设置SysTick 定时中断为10MS进入一次。然后在定时中断函数中作如下处理

 

void SysTick_Handler(void){                bTemp10Msec = TIMER_SET;               ++gTimer.Tick10Msec;        if (0 == (gTimer.Tick10Msec % 5))        {            bTemp50Msec = TIMER_SET;        }               if (0 == (gTimer.Tick10Msec % 10))        {            bTemp100Msec = TIMER_SET;        }               if (100 == gTimer.Tick10Msec)        {            gTimer.Tick10Msec = 0;            bTemp1Sec = TIMER_SET;        }}

 

gTimer是定义的一全局结构体变量,Timer_Struct  gTimer;

此软件设计巧妙之处首先在结构体的设计上:

typedef struct{    u8 Tick10Msec;    Char_Field Status;} Timer_Struct;

 

其中Char_Field 为一联合体,设计如下:

typedef union{    unsigned char byte;    Timer_Bit     field;} Char_Field;

 

而它内部的Timer_Bit是一个可按位访问的结构体

typedef struct{    unsigned char bit0: 1;    unsigned char bit1: 1;    unsigned char bit2: 1;    unsigned char bit3: 1;    unsigned char bit4: 1;    unsigned char bit5: 1;    unsigned char bit6: 1;    unsigned char bit7: 1;} Timer_Bit;

此联合体的这样设计的目的将在后面的代码中体现出来;

 

定时中断里的bTempXXX及后面定时或延时查询用的bSystemXXX 是宏定义,如下:

#define bSystem10Msec          gTimer.Status.field.bit0#define bSystem50Msec          gTimer.Status.field.bit1#define bSystem100Msec         gTimer.Status.field.bit2#define bSystem1Sec            gTimer.Status.field.bit3#define bTemp10Msec            gTimer.Status.field.bit4#define bTemp50Msec            gTimer.Status.field.bit5#define bTemp100Msec           gTimer.Status.field.bit6#define bTemp1Sec              gTimer.Status.field.bit7

 

定时中断里的TIMER_SET 为真(1)可用宏定义,也可如下定义:

typedef enum{    TIMER_RESET = 0,    TIMER_SET = 1,} TimerStatus;

以上便是非阻塞延时软件的整体结构设计。

 

另外还需要在系统运行大的循环中调用设计的控制函数,

void SysTimer _Process(void){    gTimer.Status.byte &= 0xF0;       if (bTemp10Msec)    {        bSystem10Msec = TIMER_SET;    }       if (bTemp50Msec)    {        bSystem50Msec = TIMER_SET;    }       if (bTemp100Msec)    {        bSystem100Msec = TIMER_SET;    }       if (bTemp1Sec)    {        bSystem1Sec = TIMER_SET;    }       gTimer.Status.byte &= 0x0F;}

此函数开头与结尾两句

gTimer.Status.byte &= 0xF0;gTimer.Status.byte &= 0x0F;

就巧妙的实现了bSystemXXX  bTempXXX的消除工作,不用再定时到来后手动把计数值消除。此处便用到了联合体中的变量共用一个起始存储空间的特性。

 

下面一个简单的应用举例,比如我们想让一LED灯每100MS亮或灭一次,就可以这样设计:

 int main(void){    while(1)    {         SysTimer _Process();         if(TIMER_SET == bSystem100Msec)         {             LED = !LED;         }    }}

附此软件的整体代码

#define bSystem10Msec          gTimer.Status.field.bit0#define bSystem50Msec          gTimer.Status.field.bit1#define bSystem100Msec         gTimer.Status.field.bit2#define bSystem1Sec            gTimer.Status.field.bit3#define bTemp10Msec            gTimer.Status.field.bit4#define bTemp50Msec            gTimer.Status.field.bit5#define bTemp100Msec           gTimer.Status.field.bit6#define bTemp1Sec              gTimer.Status.field.bit7typedef enum{    TIMER_RESET = 0,    TIMER_SET = 1,} TimerStatus;typedef struct{    unsigned char bit0: 1;    unsigned char bit1: 1;    unsigned char bit2: 1;    unsigned char bit3: 1;    unsigned char bit4: 1;    unsigned char bit5: 1;    unsigned char bit6: 1;    unsigned char bit7: 1;} Timer_Bit;typedef union{    unsigned char byte;    Timer_Bit     field;} Char_Field;typedef struct{    u8 Tick10Msec;    Char_Field Status;} Timer_Struct;//定义一全局变量Timer_Struct gTimer;void SysTick_Handler(void){    bTemp10Msec = TIMER_SET;    ++gTimer.Tick10Msec;    if (0 == (gTimer.Tick10Msec % 5))    {        bTemp50Msec = TIMER_SET;    }    if (0 == (gTimer.Tick10Msec % 10))    {        bTemp100Msec = TIMER_SET;    }    if (100 == gTimer.Tick10Msec)    {        gTimer.Tick10Msec = 0;        bTemp1Sec = TIMER_SET;    }}void SysTimer _Process(void){    gTimer.Status.byte &= 0xF0;        if (bTemp10Msec)    {        bSystem10Msec = TIMER_SET;    }        if (bTemp50Msec)    {        bSystem50Msec = TIMER_SET;    }        if (bTemp100Msec)    {        bSystem100Msec = TIMER_SET;    }        if (bTemp1Sec)    {        bSystem1Sec = TIMER_SET;    }        gTimer.Status.byte &= 0x0F;}

 

 181235_I12u_578802.jpg

转载于:https://my.oschina.net/czzhu/blog/261802

你可能感兴趣的文章
2015-郭辉-项目采购管理+文档配置管理
查看>>
基于 jQuery & CSS3 实现智能提示输入框光标位置
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
java加密解密___MD5的简单使用
查看>>
ThreadLocal分析
查看>>
mysql优化:连接数
查看>>
github的使用(git shell )
查看>>
如何优化js代码(1)——字符串的拼接
查看>>
PHP 时间操作 / 跳转问题
查看>>
Windows 2012 R2 FSMO角色相关小记录
查看>>
2017年6月12日笔记
查看>>
(小蚂蚁站长吧)网站优化做好这八步你就是seo第一
查看>>
使用流的方式往页面前台输出图片
查看>>
java核心技术反射
查看>>
我的友情链接
查看>>
Maven创建新的依赖项目
查看>>
2015年10月26日作业
查看>>
LAMP,安装脚本
查看>>
面向对象题目
查看>>