软定时器实验

软定时器实验
一.实验目的
本程序展示了small rtos51 中使用一个任务实现多个软定时器管理,软定时器的精度
达到1 个系统节拍。
二.设备及器件
ibm pc 机 一台
dp-51proc 单片机综合仿真实验仪 一台
三.实验步骤
1. 将a2 区的a0~a2 分别连接到b3 区的a0~a2。
2. 将a2 区的p10 连接到b3 区的rst。
3. 将a3 区的y0 连接到b3 区的/cs。
4. 将a2 区的a15~a10 分别连接到a3 区的相关控制引脚,如下:
a15 --- /g2b
a14 --- /g2a
a13 --- g1
a12 --- c
a11 --- b
a10 --- a
5. 在b3 区的j92 插入图形液晶模块(单色,128×64 点)。
6. 将b3 区的j85 短接,a3 区的jp4 短接。
四.实验参考程序主要部分
/**********************************************************
** small rtos(51)
** the real-time kernel(for keil c51)
** (c) copyright 2002-2002, chenmingji
** all rights reserved
** v1.20
**************************************************************/
#include config.h
uint8 timeadd[4]; //时间计数,用于纪录从复位以来的时间
void timesum(void);
/**********************************************************
** 函数名称: main
** 功能描述: 主函数,用户程序从这里执行
**********************************************************/
void main(void)
{
osinit();
tmod = (tmod & 0xf0) | 0x01;
th0 = (65536 - (11059200 / 12) / 100) / 256;
tl0 = (65536 - (11059200 / 12) / 100) % 256;
tr0 = 1;
et0 = 1;
tf0 = 0;
ossemcreate(zl12864_sem, 1);
lcm_dispini();
osdispclr();
ostaskcreate(timesum, null, 0);
ostaskcreate(softtimer, null, 1);
while(1)
{
pcon = pcon | 0x01; /* cpu 进入休眠状态 */
}
}
/**********************计时*************************/
void softtimerfunction2(void);
/*******************************************************
** 函数名称: softtimerfunction1
** 功能描述: 软定时器0 运行的任务,与软定时器1 配合使lcd 显示的“:”闪烁
********************************************************/
void softtimerfunction1(void)
{
osdispchar(3, 7, ':');
softtimerrun(1,(os_ticks_per_sec + 1) / 2,softtimerfunction2);
}
/*********************************************************
** 函数名称: softtimerfunction2
** 功能描述: 软定时器1 运行的任务,与软定时器0 配合使lcd 显示的“:”闪烁
***********************************************************/
void softtimerfunction2(void)
{
osdispchar(3, 7, ' ');
softtimerrun(0,os_ticks_per_sec / 2,softtimerfunction1);
}
/************************************************************
** 函数名称: softtimerfunction3
** 功能描述: 软定时器2 运行的任务,与任务timesum 配合使lcd 显示闪烁
*************************************************************/
void softtimerfunction3(void)
{
osdispchar(3, 5, ' ');
osdispchar(3, 6, ' ');
osdispchar(3, 8, ' ');
osdispchar(3, 9, ' ');
softtimerrun(2,os_ticks_per_sec * 4,softtimerfunction3);
}
/**************************************************************
** 函数名称: timesum
** 功能描述: 记录复位以来的时间的任务
***********************************************************/
void timesum(void)
{
/* 初始化软定时器模块 */
initsofttimer();
/* 运行两个软定时器 */
softtimerrun(1,os_ticks_per_sec / 2,softtimerfunction2);
softtimerrun(2,os_ticks_per_sec * 4
+ os_ticks_per_sec / 2,softtimerfunction3);
osdispchar(3, 7, ':');
while (1)
{
osdispchar(3, 5, timeadd[0] + '0');
osdispchar(3, 6, timeadd[1] + '0');
osdispchar(3, 8, timeadd[2] + '0');
osdispchar(3, 9, timeadd[3] + '0');
oswait(k_tmo,os_ticks_per_sec);
/* 计时并显示 */
timeadd[3]++;
if (timeadd[3] >= 10)
{
timeadd[3] = 0;
timeadd[2]++;
if (timeadd[2] >= 6)
{
timeadd[2] = 0;
timeadd[1]++;
if (timeadd[1] >= 10)
{
timeadd[1] = 0;
timeadd[0]++;
if(timeadd[0] >= 10)
{
timeadd[0] = 0;
}
}
}
}
}
}
softtimer. c 文件源代码
#define in_soft_timer
#include config.h
/* 软定时器的数据结构 */
typedef soft_timer_mem_sel struct _tysofttimerdata
{
uint8 falg; /* 软定时器状态 */
uint16 delaytime; /* 软定时器运行时间 */
void (const * fuction)(void); /* 软定时器溢出调用的函数 */
};
#if max_soft_timer > 0
uint16 softtimercnt; /* 辅助定时器 */
uint16 softtimerthisdelay; /* 辅助定时器初始值 */
struct _tysofttimerdata soft_timer_mem_sel softtimerdata[max_soft_timer];
/**********************************************************
** 函数名称: softtimersum
** 功能描述: 每次系统节拍处理时调用的函数,一个辅助定时器
******************************************************************/
void softtimersum(void)
{
if( --softtimercnt == 0)
{
osintsendsignal(soft_timer_task_id);
}
}
/**************************************************************
** 函数名称: initsofttimer
** 功能描述: 初始化软定时器模块
************************************************************/
void initsofttimer(void)
{
uint8 i;
os_enter_critical();
for (i = 0; i 0
if (index >= max_soft_timer)
{
return not_ok;
}
#endif
if (delay != 0 && fuction != null)
{
os_enter_critical();
softtimerdata[index].fuction = fuction;
softtimerthisdelay -= softtimercnt;
softtimercnt = 0;
softtimerdata[index].delaytime = delay + softtimerthisdelay;
softtimerdata[index].falg &= ~soft_timer_timer_out;
softtimerdata[index].falg |= soft_timer_timer_run;
os_exit_critical();
ossendsignal(soft_timer_task_id);
return soft_timer_ok;
}
else
{
return not_ok;
}
}
/*********************************************************
** 函数名称: softtimerstop
** 功能描述: 停止一个正在运行的软定时器
** 输 入: index:软定时器的索引
** 输 出: not_ok:软定时器不存在
** soft_timer_ok:操作成功
** 全局变量: softtimerdata
** 调用模块: os_enter_critical(),os_exit_critical()
************************************************************/
uint8 softtimerstop(uint8 index)
{
#if en_soft_timer_chk > 0
if (index >= max_soft_timer)
{
return not_ok;
}
#endif
os_enter_critical();
softtimerdata[index].delaytime = 0;
softtimerdata[index].fuction = null;
softtimerdata[index].falg &=
~(soft_timer_timer_out | soft_timer_timer_run);
os_exit_critical();
return soft_timer_ok;
}
/***************软定时器任务***************************************/
/****************************************************************
** 函数名称: softtimer
** 功能描述: 软定时器管理任务
***************************************************************/
void softtimer(void)
{
uint16 thisdelay;
uint8 i;
softtimercnt = 0;
while (1)
{
os_enter_critical();
// 找到定时最短的定时器
thisdelay = -1;
for (i = 0; i< max_soft_timer; i++)
{
if (softtimerdata[i].delaytime != 0 &&
softtimerdata[i].delaytime -softtimercnt)
{
softtimercnt += thisdelay;
}
else
{
softtimercnt = 1;
}
softtimerthisdelay = thisdelay;
oswait(k_sig,0);
thisdelay = softtimerthisdelay;
// 查询定时到的软定时器
for (i = 0; i < max_soft_timer; i++)
{
softtimerdata[i].falg &= ~soft_timer_timer_out;
if (softtimerdata[i].delaytime != 0)
{
if (softtimerdata[i].delaytime <= thisdelay)
{
softtimerdata[i].delaytime = 0;
if (softtimerdata[i].fuction != null)
{
softtimerdata[i].falg |= soft_timer_timer_out;
}
}
else
{
softtimerdata[i].delaytime -= thisdelay;
}
}
}
softtimerthisdelay = 0;
os_exit_critical();
// 执行软定时器指定的任务
for (i = 0; i < max_soft_timer; i++)
{
if (((softtimerdata[i].falg & soft_timer_timer_out) != 0) &&
(softtimerdata[i].fuction != null))
{
softtimerdata[i].falg &= ~soft_timer_timer_out;
softtimerdata[i].fuction();
}
}
}
}
#endif
五.实验例程简析
本软件定时器所使用的存储空间由程序自己分配,并通过一个唯一的索引(即序号)
来表示每一个软定时器。由于软定时器执行的任务时间等因素不确定,所以一般把这个任务
优先级定得比较低(表示任务的优先权越高)。
要使用软定时器模块,首先需要初始化软定时器模块。这是由调用函数initsofttimer( )
实现的。初始化后,就可以调用函数softtimerrun( )来运行一个软定时器,或是调用函数
softtimerstop( )来停止一个定时器。
在模块初始化之后,任务就可以调用函数softtimerrun( )运行一个软定时器。
softtimerrun9( )有三个参数。第一个参数index 用来指示使用的软定时器;第二个参数delay
用来设置定时器运行的时间,以系统时钟节拍为单位,范围大约是0~65000;第三个参数
function 是一个函数指针,指向一个无参数、无返回值的函数,当软定时器溢出时会调用这
个函数。图5.1 为softtimerrun( )函数的伪流程图。
为了提高程序的执行效率,程序没有使用让每一个时钟节拍将每一个软定时器的计数
值都减1 的方法。这种方法虽然简单易懂,但会大量消耗cpu 时间。而且,由于软定时器
引入了不确定的函数,为了避免这些不确定的函数对系统造成大的影响,软定时器管理任务
的优先级比较低。这样,当每个系统节拍都需要处理每一个软件定时器时,如果高优先级的
任务运行时间超过一个时钟节拍,则软定时器就会出现误差,且误差会积累。本程序使用一
个辅助减计数器来减少这些负面影响。软定时器管理任务首先要查找这些软定时器中等待时
间最短的,然后将它的等待值赋予辅助减计数器。辅助减计数器每个系统节拍都减一,且与
系统时钟节拍处理函数一起执行。当辅助减计数器溢出时通知软定时器管理任务,软定时器
管理任务再进行其他处理。辅助减计数器的代码见函数softtimersum ( )。
图5.2 为软定时器处理任务的流程图。

婚庆策划APP开发方案
LoRa协议给智能家居的体验带来了什么
关于基站170W电源方案的性能分析和应用
深度剖析可靠性技术与试验
呕吐毒素检测仪FD-600
软定时器实验
谷歌无人驾驶汽车技术
杂牌手机解锁大全
周剑:人形服务机器人距离技术成熟还需几十年
欧洲如何实现零碳电力发展转型
电子标签的分类_电子标签的作用是什么
Imagga利用DGX Station实现快速图像识别
新时代物联网安全的要求有哪些?
芯讯通LPWA模组SIM7080G顺利通过AT&T认证
新思科技收购Ansys,引领芯片系统设计解决方案
吉时利推出超快C-V测量系统4225-PMU,可单机实现三大
家装要多方协调?三翼鸟卡萨帝001号店襄阳开业一站解决
民用电或进入1元/度时代,储能系统万亿市场开启
钒电池市场扩张—钒资源“水涨船高”
小米6评测:小米6和小米5有什么区别?看完小米6的这些优缺点,再决定买小米6也不迟