专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
[代码分享]一个简单好用的轮询延时器模块
2019-12-16 22:38
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
5149
38
39
本帖最后由 Jmhh247 于 2017-5-23 10:08 编辑
关键字:延时器;非阻塞自由延时
在一些按键或其它形式的命令响应中,要求严格的话通常会需要队列缓存命令,以防丢失。
但是我通常还会遇到一些要求非常不严格的场景,这些场景甚至要限制响应的次数或频率(这里指不能响应太快)。
比如(只是个例子),我的产品是一个根据接收到的串口命令来工作的。串口命令发送的速度是不确定的,有时候1秒
会发送10帧命令过来,有的时候1秒确能发送100帧,但是这个产品每秒只打算处理20帧命令。而且由于命令有多个,
对于有些命令码可能每秒响应40帧或30帧等,这种场景用多个延时器就很合适了。
延时器模块的接口函数一共3个,如下:
/* Exported functions ------------------------------------------------------- */
bool zl_poll_delay_set(uint8_t chUserId, uint16_t hwTime);
bool zl_poll_delay_timeout(uint8_t chUserId);
void zl_poll_delay_tick(void);
复制代码
看下接口函数的实现,很简单的
/* Z L _ P O L L _ D E L A Y _ S E T */
/*-------------------------------------------------------------------------
功能描述 : 设定延时时间,同时启动延时。
输入参数 : uint8_t chUserId 延时器ID
uint16_t hwTime 延时时间
输出参数 : 无
返 回 值 :
修改历史
1.日 期 : 2017年2月6日
作 者 : zys
修改内容 : 新生成函数,OK。
-------------------------------------------------------------------------*/
bool zl_poll_delay_set(uint8_t chUserId, uint16_t hwTime)
{
if (chUserId >= ZL_POLL_DELAY_NUM) {
return false;
}
if (0 == hwTime) {
return false;
}
s_tPollBuf[chUserId].Time = hwTime;
return true;
}
/* Z L _ P O L L _ D E L A Y _ T I M E O U T */
/*-------------------------------------------------------------------------
功能描述 : 查询给定ID的延时器是否超时。
输入参数 : uint8_t chUserId
输出参数 : 无
返 回 值 : true 超时;false 未超时。
修改历史
1.日 期 : 2017年5月22日
作 者 : zys
修改内容 : 新生成函数。
-------------------------------------------------------------------------*/
bool zl_poll_delay_timeout(uint8_t chUserId)
{
if (chUserId >= ZL_POLL_DELAY_NUM) {
return false;
}
if ( !s_tPollBuf[chUserId].Time) {
return true;
}
return false;
}
/* Z L _ P O L L _ D E L A Y _ T I C K */
/*-------------------------------------------------------------------------
功能描述 : 延时模块的驱动任务,在心跳中断里运行。
输入参数 : void
输出参数 : 无
返 回 值 :
修改历史
1.日 期 : 2017年5月22日
作 者 : zys
修改内容 : 新生成函数。
-------------------------------------------------------------------------*/
void zl_poll_delay_tick(void)
{
uint8_t i;
for ( i = 0 ; i < ZL_POLL_DELAY_NUM; i++ ) {
if (s_tPollBuf[i].Time) {
s_tPollBuf[i].Time--;
}
}
}
复制代码
模块的使用
使用很简单,首先把模块源文件添加到工程中,然后把
void zl_poll_delay_tick(void)
复制代码
放到心跳中断里,我一般用1ms的心跳中断。
现在就能使用
bool zl_poll_delay_set(uint8_t chUserId, uint16_t hwTime)
复制代码
来设置延时器了,入参分别是延时器的ID和延时时间,延时时间单位和心跳中断有关,看自己需求了。。。
然后用
bool zl_poll_delay_timeout(uint8_t chUserId)
复制代码
来查询延时器是否超时,入参是要查询的延时器ID号。
延时器的可用最大数量通过宏定义配置
/* 定义可用的延时数量 */
#define ZL_POLL_DELAY_NUM 5
复制代码
模拟一个应用场景演示代码
/* 定义延时器信息,便于阅读修改 */
#define DELAY_ID0 0
#define DELAY_TIME0 50
#define DELAY_ID1 1
#define DELAY_TIME1 900
/* 模拟一个应用场景 */
void xxx_cmd_process(uint8_t chCmd)
{
switch (chCmd) {
case CMD_LEFT:
/* 该命令执行间隔不能小于50ms */
if (zl_poll_delay_timeout(DELAY_ID0)) {
zl_poll_delay_set(DELAY_ID0, DELAY_TIME0);
cmd_do_left();
}
break;
case CMD_RIGHT:
/* 该命令执行间隔不能小于900ms */
if (zl_poll_delay_timeout(DELAY_ID1)) {
zl_poll_delay_set(DELAY_ID1, DELAY_TIME1);
cmd_do_left();
}
break;
case CMD_UP:
/* 该命令无限制,来就执行 */
cmd_do_up();
break;
case CMD_DOWN:
break;
default:
break;
}
}
/* 在1ms心跳(时基)中断里运行 */
void st_systick_1ms_irq(void)
{
zl_poll_delay_tick()
}
复制代码
延时器的用处还有很多,可以灵活。。。
zlib poll delay模块源码.rar
(2.02 KB, 下载次数: 108)
2017-5-23 10:07 上传 点击文件名下载附件
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
38条回答
Jmhh247
2019-12-19 05:12
fm007 发表于 2017-7-19 16:30
感谢楼主分享,我目前也使用过这种思路的,但是用的是离散的结构体标志
结构体标志也不错
加载中...
查看其它38个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
结构体标志也不错
一周热门 更多>