找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2162|回复: 3
打印 上一主题 下一主题
收起左侧

老年人用药助记神器 单片机源程序

[复制链接]
跳转到指定楼层
楼主
ID:568756 发表于 2019-9-6 19:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为了帮助老年人在用药时比较容易忘记的难题,本人特结合用药特点,设计了本程序。本程序特点:
程序有四个按键,其功能分别为:
1、用药一次,即可按此键,以便总用药次数加1;
2、用药次数有误时,可按此键,让用药次数减1;
3、用药次数置零;
3、用药次数及时间清零,并启用时间计时器,计时器自00-00-00,时-分-秒格式计时计数

本程序功能有:
1、程序硬件有AT24C02存储器,以便对每次用药的参数进行存储,关闭电源后,相关数据不会丢失;
2、程序硬件有时间芯片DS1302,可通过按键,启用时间计时,方便记录类似于热敷、浸泡类事项的时间;
3、相关信息,通过液晶1602显示出来。
4、本程序是单片机爱好者的练习之作,亦可为家里老人尽一份孝心的小物件。

单片机源程序如下:
  1. #include<reg51.h>
  2. #include"lcd.h"
  3. #include"ds1302.h"
  4. #include "i2c.h"
  5. #include "delay.h"
  6. #include "string.h"                 /*利用C语言库函数memcpy可以整体复制。memcpy声明与string.h中,形式为:
  7.                                                 void * memcpy(void *dst, void *src, int length);
  8.                                                 其功能为将src地址上长度为length字节的数据,复制到dst上。                 */

  9. void LcdDisplay(unsigned char addr);
  10. void Scan_KEY();
  11. void num_display(void);

  12. sbit KEY1=P1^3;                                 //加1 四个按键共了,其再与74LS21与门并联,相与后联接P3.2口,实现INT0中断
  13. sbit KEY2=P1^4;                                 //减1
  14. sbit KEY3=P1^5;                                 //次数置0
  15. sbit KEY4=P1^6;                                 //次数与时间均置0

  16. sbit LED1=P2^5;                                 //按键1存储指示灯
  17. bit KeyPressFlag;                         //定义按键标志位
  18. //---存储顺序是  秒  分  时    日    月    周    年,  存储格式是用BCD码---//
  19. //uchar TIME2[7] = {10, 20, 0x00, 0x07, 0x07, 0x07, 0x68};
  20. //uchar *jxhj[]= {"Mon","Tues","Wed","Thur","Fri","Sat","Sun"};

  21. unsigned char num=0;                  //用于记录次数
  22.                                                          
  23. void main()
  24. {
  25.         IRcvStr(0xae,0,&num,1);        //&符号的作用是取一个变量的地址。                 
  26.         LcdInit();
  27.         Ds1302Init();

  28.         EA=1;                 //中断总开关
  29.            EX0=1;                 //外部中断INT0使能
  30.         IT0=1;       //下降沿触发  IT0=0为低电平触发

  31.         while(1)
  32.         {       
  33.                 if(KeyPressFlag==1)
  34.                 {
  35.                           KeyPressFlag=0;  //按键标志清零,以便下次检测
  36.                         Scan_KEY();
  37.                 }       
  38.                 else
  39.                 {
  40.                         Ds1302ReadTime();                                                        //读取时间参数
  41.                         LcdDisplay(0x00);                                                        //第一行地址是0x00,第二行是0x40;       
  42.                         LcdWriteCom(0xC0);               
  43.                         LcdWriteData('F');
  44.                         LcdWriteData('R');
  45.                         LcdWriteData('E');
  46.                         LcdWriteData('Q');
  47.                         LcdWriteData('U');
  48.                         LcdWriteData('E');
  49.                         LcdWriteData('N');
  50.                         LcdWriteData('C');
  51.                         LcdWriteData('Y');
  52.                         LcdWriteData(':');
  53.                            LcdWriteCom(0xC0+13);                                                //移动光标指令,0x80是固定指令值,后面是移动的绝对值
  54.                         LcdWriteData(num/10%10+0x30);
  55.                         LcdWriteData(num%10+0x30);                                        //+0x30就是把个位数值转换成 字符0~9的ASCII码
  56.                 }                           
  57.         }
  58.        
  59. }


  60. /*******************************************************************************
  61. * 函数名         : LcdDisplay()
  62. * 函数功能                   : 显示函数
  63. * 输入           : 无
  64. * 输出                  : 无
  65. *******************************************************************************/
  66. void LcdDisplay(unsigned char addr)
  67. {
  68. //        LcdWriteCom(0x80);                                                    //第一行地址
  69. /*        LcdWriteData('1');                                                        //确定日期的年代转换
  70.         LcdWriteData('9');
  71.         LcdWriteData('0'+TIME[6]/16);                                //年
  72.         LcdWriteData('0'+(TIME[6]&0x0f));
  73.         LcdWriteData('-');
  74.         LcdWriteData('0'+TIME[4]/16);                                //月
  75.         LcdWriteData('0'+(TIME[4]&0x0f));
  76.         LcdWriteData('-');
  77.         LcdWriteData('0'+TIME[3]/16);                                //日
  78.         LcdWriteData('0'+(TIME[3]&0x0f));
  79.         LcdWriteCom(0x80+13);                                                //移动光标指令,前面是固定的,后面是移动的数值
  80.         LcdWriteData('0'+(TIME[5]&0x07));                           //星期                         
  81. */
  82.         LcdWriteCom(addr+0X80);                                                //书写的位置
  83.         LcdWriteData('S');
  84.         LcdWriteData('T');
  85.         LcdWriteData('A');
  86.         LcdWriteData('R');
  87.         LcdWriteData('T');
  88.         LcdWriteData(':');
  89.         LcdWriteCom(0x80+7);
  90.         LcdWriteData('0'+TIME[2]/16);                                //时 ds1302输出的是压缩BCD码,除16就得到十位数的10进制数
  91.         LcdWriteData('0'+(TIME[2]&0x0f));                        //8位压缩BCD码,即高四位是一个0-9的BCD码,低四位亦同样是一个BCD码         
  92.         LcdWriteData('-');
  93.         LcdWriteData('0'+TIME[1]/16);                                //分
  94.         LcdWriteData('0'+(TIME[1]&0x0f));                        //相与后保留低四位,即个位
  95.         LcdWriteData('-');
  96.         LcdWriteData('0'+TIME[0]/16);                                //秒  
  97.         LcdWriteData('0'+(TIME[0]&0x0f));                        //数值同0x0f相与后就是个位数了,这只对BCD码有效。                                  
  98. }


  99. void Scan_KEY()                                                     
  100. {
  101.         unsigned char i;
  102.         if(KEY1==0)                                                   //按键按下
  103.         {
  104.                 DelayMs(20);                                     //延时,去抖
  105.                 if(KEY1==0)                                       //确认按键按下
  106.                 {
  107.                  for(i=0;i<100;i++)             //此处消抖程序非常经典,怎么按都绝对不会产生抖动。
  108.             {
  109.                     if(KEY1==0) i=0;
  110.             }                                                        //自下面开始写程序

  111.                    if(num<100)                                    //加操作 次数控制在99以内
  112.             {
  113.                   num++;
  114.               ISendStr(0xa0,0,&num,1);  //写入24c02
  115.               DelayMs(10);
  116.                           num_display();
  117.             }
  118.          }
  119.      }

  120.         if(KEY2==0)                                                   //按键按下
  121.         {
  122.                 DelayMs(20);                                     //延时,去抖
  123.                 if(KEY2==0)    //                           //确认按键按下
  124.                 {
  125.                  for(i=0;i<100;i++)             //此处消抖程序非常经典,怎么按都绝对不会产生抖动。而且直到松手后再执行后面程序
  126.             {
  127.                     if(KEY2==0) i=0;
  128.             }
  129.                       if(num>0)  //减操作
  130.                  {
  131.                   num--;
  132.               ISendStr(0xa0,0,&num,1);  //写入24c02
  133.               DelayMs(10);
  134.                           num_display();
  135.              }
  136.          }
  137.      }

  138.         if(KEY3==0)                                                   //按键按下
  139.         {
  140.                 DelayMs(20);                                     //延时,去抖
  141.                 if(KEY3==0)    //                           //确认按键按下
  142.                 {
  143.                  for(i=0;i<100;i++)             //此处消抖程序非常经典,怎么按都绝对不会产生抖动。
  144.             {
  145.                     if(KEY3==0)        i=0;
  146.              }
  147.                         Ds1302Init();                                          
  148.                         LcdDisplay(0x40);                                                        //第一行地址是0x00,第二行是0x40;       
  149.          }
  150.      }


  151.         if(KEY4==0)                                                   //按键按下
  152.         {
  153.                 DelayMs(20);                                     //延时,去抖
  154.                 if(KEY4==0)    //                           //确认按键按下
  155.                 {
  156.                  for(i=0;i<100;i++)             //此处消抖程序非常经典,怎么按都绝对不会产生抖动。
  157.             {
  158.                     if(KEY4==0)i=0;
  159.             }
  160.                         Ds1302Init();                                          
  161.                         LcdDisplay(0x40);                                                        //第一行地址是0x00,第二行是0x40;       
  162.                         num=0;
  163.             ISendStr(0xa0,0,&num,1);  //写入24c02
  164.                         num_display();
  165.          }
  166.      }
  167. }

  168. void num_display(void)                                                          //专门用来显示num值的
  169. {
  170.         LcdDisplay(0x40);                                                        //第一行地址是0x00,第二行是0x40;       
  171.            LcdWriteCom(0xC0+13);                                                //移动光标指令,0x80是固定指令值,后面是移动的绝对值
  172.         LcdWriteData(num/10%10+0x30);
  173.         LcdWriteData(num%10+0x30);                                        //+0x30就是把个位数值转换成字符了
  174. }
  175. /*INT0中断函数 */
  176. void  counter0(void) interrupt 0                     //INT0 是四个按键接入74LS21四与门输入,然后输出口接入P3.2口
  177. {
  178.         EX0=0;                                                          //关闭中断
  179.         KeyPressFlag=1;                                           //表明按键有动作,可以进行按键扫描
  180.           EX0=1;                                                                //再次打开中断
  181. }

  182. /*------------------------------------------------
  183.                  定时器中断子程序
  184. ------------------------------------------------*/
  185. void Timer0_isr(void) interrupt 1                                 //定时对液晶屏数值进行更新
  186. {
  187.         TH0=(65536-12000)/256;                                                  //重新赋值 2ms
  188.         TL0=(65536-2000)%256;
  189.         LcdDisplay(0x00);                                                        //第一行地址是0x00,第二行是0x40;       
  190.         LcdWriteCom(0x80+11);                                                //移动光标指令,后面是移动的绝对值
  191.         LcdWriteData(num%10+0x30);                                        //+0x30就是把个位数值转换成字符了
  192. }
复制代码

所有代码51hei提供下载:
老年人用药助记神器.rar (66.16 KB, 下载次数: 22)

评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2019-9-6 20:08 | 只看该作者
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

板凳
ID:342822 发表于 2019-9-6 20:25 | 只看该作者
建议加提示音早中晚用药数量~~~
回复

使用道具 举报

地板
ID:568756 发表于 2019-9-6 21:09 | 只看该作者
taotie 发表于 2019-9-6 20:25
建议加提示音早中晚用药数量~~~

好的。谢谢。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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