搜索
bottom↓
回复: 18

[多任务测试]AT89S51: 18B20每秒刷新,4位数码管每mS刷新,LCD1602液晶两个每500mS刷新,

[复制链接]

出0入0汤圆

发表于 2011-6-4 17:58:01 | 显示全部楼层 |阅读模式
要完成以下功能,要求实时性很高,数据刷新速度越高越好,大家都用什么办法?

18B20每秒刷新
4位数码管每mS刷新
LCD1602液晶两个每500mS刷新(一个是6根线驱动,1格式3根线驱动)
按键检测(支持单击双击长按)检测间隔500uS


(原文件名:截图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[4]= {0,0,0,0};
    static char string1[16] = "1234567890123456";//"FLYER HACKER";
    static char string2[16] = "6543210987654321";//"I'm F.H.";
   
    timer1_init();
    ds18b20_init();
        lcd1602_init();
        lcd1602_cgram_init();
       
        lcd1602_3p_init();
        lcd1602_3p_cgram_init();
       
        //看看字符效果
    //string2[10] = 1;
    //string2[11] = 2;
    //string2[12] = 3;
    //string2[13] = 4;
   
    while(1) //【注意关闭中断时,需要关断时间小于中断周期】      
    {
        
        temp = ds18b20_read(0);                         //每900mS自动刷新一次
        
        //温度负数还没处理
        display_data[3] = temp % 10;
        display_data[2] = 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[15] = i&0x0f;
        string2[15] = i&0x0f;
        i++;
        }
        
        //【方针时 还存在时间久了, 乱码问题 或 闪烁问题】
        lcd1602_display(string1 , string2 , 3);     //lcd1602 每500mS自动刷新一次,四位数据

        lcd1602_3p_display(string2 , string1 , 4);  //3根线驱动的LCD1602
   
    }
}

出0入0汤圆

发表于 2011-6-4 18:02:32 | 显示全部楼层
这个系统是外星人用的嘛?

出0入0汤圆

 楼主| 发表于 2011-6-4 18:07:31 | 显示全部楼层
纯粹是测试用的 在学习单片机 就试试多任务

教程里 很多是用 软件延时实现,要实现多任务不可能

所以想跟操作系统一样用 时间片控制 响应速度的 空间浪费都挺大的

要读取18B20的话,被打断了可能读取错误

所以 试了下 用定时器来延时

其他人怎么实现的还不太清楚

看着主程序 似乎很简单的

出0入0汤圆

发表于 2011-6-4 18:20:20 | 显示全部楼层
关注一下,不知道是个什么东西?

出0入0汤圆

发表于 2011-6-4 19:40:29 | 显示全部楼层
小石头,大智慧!
谢谢LZ。

出0入8汤圆

发表于 2011-6-4 20:12:17 | 显示全部楼层
貌似不错~记号

出0入0汤圆

发表于 2011-6-4 20:19:54 | 显示全部楼层
推荐楼主去看下 《时间触发嵌入式》

出0入0汤圆

发表于 2011-6-4 22:07:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-4 22:21:43 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-4 22:21:43 | 显示全部楼层
4位数码管每mS刷新: 可以按照1/25祯=40ms,然后10ms刷新 灰可以正常的显示。
按键检测(支持单击双击长按)检测间隔500uS,个人的经验也是可以10ms检测一次。
18B20胡每个bit都是以下降沿开始。然后每次 都不会 超过1ms。
而LCD1602完全无所谓时间。
所以上面 这样实现多任务还是可行的。

你的设计指标太高了点。

出0入0汤圆

发表于 2011-6-4 22:49:14 | 显示全部楼层
可以用一个定时器来搞定,时间到了,触发相应的函数即可

现在常用一个定时器办好几件事

出0入0汤圆

发表于 2011-6-4 23:09:12 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2011-6-5 00:09:10 | 显示全部楼层
回复【9楼】fjcqv
-----------------------------------------------------------------------

这个纯粹是测试,学习用的,设计时指标当然越高越好。

实际要求可能就会低很多了

这个程序的主循环 循环一次才500uS,1mS以上的延时全部用 一个定时器实现,用的是定时器1的8位自动填充方式,作为系统时钟

需要一个延时的话,先锁存住开始时间,然后再循环检测定时是否到 若到则返回标志位


详细资料看 上面的PDF  挺好的

从只会用 for 循环延时  到 用定时器 延时   的确算是一次不小的改变。

本人初学者,不过学会这个,就很容易把以前编的软件延时的程序 直接移植过来

并且可以多个模块 多任务

出0入0汤圆

 楼主| 发表于 2011-6-5 00:16:20 | 显示全部楼层
LCD1602 用的是3根线驱动的  效果还可以  速度也行  这个需要计算RC参数 和 延时

具体资料 可以参考 COWBOY的帖子

4线驱动的初始化得注意

个人找到个好办法(绝对原创,还没发现有人用这种方法呢,仿真和测试结果都不错)

就是发送
先发送命令 0X33 0X32
再发送     0X28

需要注意:LCD1602上电后 默认是8位的就可以
发送更改命令也是当做8位看待的

也就是 命令等效于
0X3?
0X3?
0X3?
0X2?
0X28

出0入0汤圆

发表于 2011-6-5 00:47:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-14 03:41:16 | 显示全部楼层
我也想这个问题,你搞出来没有

出0入0汤圆

发表于 2011-10-14 08:58:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-15 18:59:53 | 显示全部楼层
记号

出0入0汤圆

发表于 2012-2-20 00:29:41 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-7 17:35

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表