本帖最后由 正版长小强 于 2023-11-11 07:40 编辑
#每日话题# #申请原创# #技术资源#
《芯圣51内核单片机HC89F0xx库分享》- 软定时器库
一、前言
项目需要近期接触芯圣HC89F0xx系列51核单片机 ,超高的 性价比、灵活性 深深的吸引了我 。 为后续项目更快落地,开始做基础功能的封装库工作。
在代码编写过程中 时间要素是关键的 ,初期往往使用阻塞式Delay 延时函数 ,慢慢的 会借用定时器 ,状态机 方式 ,几年前在51核上做一个软定时器模块,一直在用,芯圣上也可以使用 ,为项目功能验证带来极大便利 。现在分享出来 。
往期分享地址 :
《芯圣51内核单片机HC89F0xx库分享》-GPIO库
/*************************************************************************************************************************/
二、分享内容
软件定时器工作原理 , 首先需要为软定时器提供一个 基准心跳 一般是10mS , 这决定了定时器的计时最小单位 。心跳 可以是其他的 。软定时器 提供了一个定时器结构体 ,以及相关的 操作接口 。
1: 声明一个软定时器 xdata new_t sec_t; 定时器是静态的 ,声明了就如变量一般一直存在 ,占用内容 ,推荐大家在xdata 区域定义
2: 配置定时器 new_time_create(&sec_t ,NEW_TIME_TICK_SEC,NEW_TIME_MODE_WHILE,sec_run);
&sec_t :我们刚刚声明的定时器地址
NEW_TIME_TICK_SEC :设定定时器溢出时间 ,这个宏定义与 基准心跳有关 10mS 时值是100 ,注意定时器的计数值范围是 0 - 255 U8 类型
NEW_TIME_MODE_WHILE :定时器工作模式 ,默认代码 两种 持续工作 、到达时间后关闭 ,可通过修改代码实现设定次数
sec_run :回调函数 ,定时器到达时间后会执行这个函数 ,当前没有做参数功能 。
3:启动定时器 new_time_cmd(&sec_t,NEW_TIME_ON);
使用过程很简单 ,需要注意 :不要重复配置定时器(没有做定时器ID 管理 ,制作了链表功能,注意就好 最小配置) 会导致定时器链表异常 ,内存溢出。
/*************************************************************************************************************************/
三、移植过程
在主函数中 10mS 周期 new_time_run_main();
在中断函数中10mS 调用 new_time_run_clock();
注意不要在中断函数中调用new_time_run_main(); 会让定时周期不可控, 如果你对定时器时间要求很低 可以把这两个函数都放在 主函数 10mS 变量盘内。
例:
bit t_10ms_flag = 0;
void Timer1_ISR (void) interrupt TIMER1_VECTOR
{
TL1 = TL1_VALUE;
TH1 = TH1_VALUE;
#ifdef USER_NEW_TIME
new_time_run_clock();
#endif
}
//主函数 while(1) 循环内
if(t_10ms_flag == 1) //10MS 心跳标志
{
#ifdef USER_NEW_TIME
new_time_run_main();
#endif
t_10ms_flag = 0;
}
如果不出意外 :就可以开心的使用软定时器了 ,如果你内存允许 ,可以开很多软定时器 。
/*************************************************************************************************************************/
四、定时器数据机构 、宏定义
struct new_time
{
unsigned char settime; //设定时间
unsigned char contr; //当前时间
unsigned char mode:1; //模式
unsigned char on_off:1; //开关
unsigned char oveflag:1; //溢出标志
void (*run)(void); //回调函数
struct new_time *up_p; //链表
struct new_time *down_p;
};
typedef struct new_time new_t;
#define NEW_TIME_TICK_SEC (100) //定时器每秒最大定时次数
#define NEW_TIME_ON 1 //定时器状态打开
#define NEW_TIME_OFF 0 //定时器状态关闭
#define NEW_TIME_MODE_WHILE 0 //定时器循环触发模式
#define NEW_TIME_MODE_ONE 1 //定时器触发一次后处于关闭状态
/*************************************************************************************************************************/
五、源码分享- #ifdef USER_NEW_TIME
- struct new_time
- {
- unsigned char settime;
- unsigned char contr;
- unsigned char mode:1;
- unsigned char on_off:1;
- unsigned char oveflag:1;
- void (*run)(void);
- struct new_time *up_p;
- struct new_time *down_p;
- };
- typedef struct new_time new_t;
- #define NEW_TIME_TICK_SEC (100) //定时器每秒最大定时次数
- #define NEW_TIME_ON 1 //定时器状态打开
- #define NEW_TIME_OFF 0 //定时器状态关闭
- #define NEW_TIME_MODE_WHILE 0 //定时器循环触发模式
- #define NEW_TIME_MODE_ONE 1 //定时器触发一次后处于关闭状态
- /*
- 函数功能:创建一个软定时器
- 参数:*nt定时器结构,settime 定时时间10ms最小单位 ,mode 模式,(*run)定时器到达时间要运行的函数
- 返回:无
- */
- extern void new_time_create(new_t *nt,unsigned char settime,unsigned char mode,void (*run)(void));
- /*
- 函数功能:控制某个定时器状态
- 参数:*nt定时器结构,off_on 定时器状态
- 返回:无
- 副作用:无
- */
- extern void new_time_cmd(new_t *nt,unsigned char off_on);
- /*
- 函数功能:修改定时器周期
- 参数:*nt定时器结构,settime 定时时间10ms最小单位
- 返回:无
- */
- extern void new_time_set(new_t *nt,unsigned short settime);
- /*
- 函数功能:清空定时器计时值
- 参数:*nt定时器结构
- 返回:无
- */
- extern void new_time_reset(new_t *nt);
- /*
- 函数功能:删除这个定时器检查任务
- 参数:*nt定时器结构
- 返回:无
- */
- /*
- extern void new_time_delete(new_t *nt);
- */
- /*
- 函数功能:查询计时结束的定时器并执行指向函数
- 参数:无
- 返回:无
- 循环调用
- */
- extern void new_time_run_main(void);
- #endif
|