[多任务测试]AT89S51: 18B20每秒刷新,4位数码管每mS刷新,LCD1602液晶两个每500mS刷新,
要完成以下功能,要求实时性很高,数据刷新速度越高越好,大家都用什么办法?18B20每秒刷新
4位数码管每mS刷新
LCD1602液晶两个每500mS刷新(一个是6根线驱动,1格式3根线驱动)
按键检测(支持单击双击长按)检测间隔500uS
http://cache.amobbs.com/bbs_upload782111/files_40/ourdev_645758PP9J3E.jpg
(原文件名:截图00.jpg)
【PROTEUS仿真】
数码管显示的是18B20的温度
点击此处下载 ourdev_645759TU1MLH.rar(文件大小:23K) (原文件名:desktop.rar)
【参考资料,绝对好】
点击此处下载 ourdev_645762BPUAAF.pdf(文件大小:4.79M) (原文件名:从单片机初学者迈向单片机工程师.pdf)
目录:
一、LED 主题讨论周第一章----写在前面......................................................... 1
二、LED 主题讨论周第二章----学会释放CPU................................................. 2
三、LED 主题讨论周第三章----模块化编程初识..............................................8
四、LED 主题讨论周第四章----渐明渐暗的灯................................................25
五、LED 主题讨论周第五章----多任务环境下的数码管编程设计................. 28
六、KEY 主题讨论第一章——按键程序编写的基础..................................... 37
七、KEY 主题讨论第二章——基于状态转移的独立按键程序设计.............. 40
八、综合应用之一——如何设计复杂的多任务程序...................................... 47
九、综合应用之二——DS1320/DS18B20 应用...............................................60
【下面是主函数】
#include "includes.h"
//【文件需要都添加到工程才行】
void main(void)
{
signed temp = 0;
unsigned char i = 0;
unsigned char display_data= {0,0,0,0};
static char string1 = "1234567890123456";//"FLYER HACKER";
static char string2 = "6543210987654321";//"I'm F.H.";
timer1_init();
ds18b20_init();
lcd1602_init();
lcd1602_cgram_init();
lcd1602_3p_init();
lcd1602_3p_cgram_init();
//看看字符效果
//string2 = 1;
//string2 = 2;
//string2 = 3;
//string2 = 4;
while(1) //【注意关闭中断时,需要关断时间小于中断周期】
{
temp = ds18b20_read(0); //每900mS自动刷新一次
//温度负数还没处理
display_data = temp % 10;
display_data = temp / 10;
//此处只是定义个最小扫描周期,具体由主循环周期决定
led7seg_display(display_data , 1*DT_MS , 1); //1mS刷新1次
P2_3 = ~P2_3 ; //可以通过示波器观察主循环周期
//实际测量500uS
button_extend(get_button); //拓展单键检测,可返回单击,双击,长按代码
//单键抗干扰采用计数1++ 或0-- 方式,未用延时
//按键响应速度由主循环周期决定,此处为500uS
if(delay_dt2(500*DT_MS , 2)) //500mS刷新数据
{
string1 = i&0x0f;
string2 = i&0x0f;
i++;
}
//【方针时 还存在时间久了, 乱码问题 或 闪烁问题】
lcd1602_display(string1 , string2 , 3); //lcd1602 每500mS自动刷新一次,四位数据
lcd1602_3p_display(string2 , string1 , 4);//3根线驱动的LCD1602
}
} 这个系统是外星人用的嘛? 纯粹是测试用的 在学习单片机 就试试多任务
教程里 很多是用 软件延时实现,要实现多任务不可能
所以想跟操作系统一样用 时间片控制 响应速度的 空间浪费都挺大的
要读取18B20的话,被打断了可能读取错误
所以 试了下 用定时器来延时
其他人怎么实现的还不太清楚
看着主程序 似乎很简单的 关注一下,不知道是个什么东西? 小石头,大智慧!
谢谢LZ。 貌似不错~记号 推荐楼主去看下 《时间触发嵌入式》 mark mark 4位数码管每mS刷新: 可以按照1/25祯=40ms,然后10ms刷新 灰可以正常的显示。
按键检测(支持单击双击长按)检测间隔500uS,个人的经验也是可以10ms检测一次。
18B20胡每个bit都是以下降沿开始。然后每次 都不会 超过1ms。
而LCD1602完全无所谓时间。
所以上面 这样实现多任务还是可行的。
你的设计指标太高了点。 可以用一个定时器来搞定,时间到了,触发相应的函数即可
现在常用一个定时器办好几件事 mark 回复【9楼】fjcqv
-----------------------------------------------------------------------
这个纯粹是测试,学习用的,设计时指标当然越高越好。
实际要求可能就会低很多了
这个程序的主循环 循环一次才500uS,1mS以上的延时全部用 一个定时器实现,用的是定时器1的8位自动填充方式,作为系统时钟
需要一个延时的话,先锁存住开始时间,然后再循环检测定时是否到 若到则返回标志位
详细资料看 上面的PDF挺好的
从只会用 for 循环延时到 用定时器 延时 的确算是一次不小的改变。
本人初学者,不过学会这个,就很容易把以前编的软件延时的程序 直接移植过来
并且可以多个模块 多任务 LCD1602 用的是3根线驱动的效果还可以速度也行这个需要计算RC参数 和 延时
具体资料 可以参考 COWBOY的帖子
4线驱动的初始化得注意
个人找到个好办法(绝对原创,还没发现有人用这种方法呢,仿真和测试结果都不错)
就是发送
先发送命令 0X33 0X32
再发送 0X28
需要注意:LCD1602上电后 默认是8位的就可以
发送更改命令也是当做8位看待的
也就是 命令等效于
0X3?
0X3?
0X3?
0X2?
0X28 mark 我也想这个问题,你搞出来没有 mark 记号 mark
页:
[1]