当前位置:   article > 正文

嵌入式单片机智能药盒设计(含代码)_智能药盒代码流程图

智能药盒代码流程图

目录

前言

 设计的内容

(1)显示

(2)定时时间与用药量的设定

(3)实时时间调节

(4)报警功能

 时钟模块

 蓝牙模块

 

系统软件设计

 系统主程序

 按键函数

 中断服务函数

作品展示 

 测试药定时提醒功能

 完整代码


前言

近年来,疫情反复,这让一些家庭使得自己的家里的老人造成了没有人照看的状态,那这就会出现一个问题,那就是我国现在的医疗物资非常的紧张,因为收到了疫情的影响,相关的专业的人员都已经开始向智慧云药能方面开始发展了,同时现在也是大数据的社会在这样的时代的背景下,那些对自身健康问题越来越重视的人,就能够从网络上获取到很多有关于医疗的信息,所以为了迎合拿下记忆力下降而遇到事情就容易忘记的健忘人员,对于他们的需求,就由此提出了一种可以给基于嵌入式单片机的智能药盒的设计方案。

 设计的内容

首先介绍一下本设计的使用的LCD160液晶显示屏幕的显示的原理,以及实时时钟模块运行的原理和声控光控报警系统模块的原理。

系统的硬件部分由以下几个模块组成:STC90C51单片机、4×2键盘模块、LCD1602液晶显示屏幕模块、声光报警模块、HC-05蓝牙模块。其中LCD1602液晶显示屏幕模块可以实现实时日期、时间显示功能,键盘模块可以实现对时间、药物用量的设置,声光报警模块可以实现定时时间的提醒,HC-05模块建立单片机与手机之间的链接。

其中系统实现的基本功能具体如下:

(1)显示

采用LCD1602液晶屏幕显示实时日期时间、用药种类及用量等。

(2)定时时间与用药量的设定

系统将在LCD屏幕上显示并实现三种药物用量以及时间的定时设置,分别通过键盘模块中的七个按键完成。

其中七个按键的功能具体为:一个设置键,记为k1,负责进入设置状态;一个功能键记为k2,负责进入三种药品的用药量设置状态;两个调节键,分别记为k7、k8。其中k7的作用为药量增加1,k8的作用为药量减少1。三次定时对应的三个定时按键k4、k5、k6,按下即可停止蜂鸣器鸣警报。

(3)实时时间调节

实时时间通过三个按键进行调节,一个为设置键,记为k1,负责进入时间设置状态;另外两个个为调节键,记为k2、k3。其中k2的作用为增加时间,k3为减少时间。

(4)报警功能

系统内部程序存储器中,自动将系统时钟模块运行的实时时间与定时时间进行对比判断,在两者一致的情况下,蜂鸣器警报响起,且根据需要的服用药物种类,同时对应的LED发光二极管将持续闪烁。

本设计以STC90C516RD+单片机作为核心主控芯片,在本文中主要介绍系统复位电路以及内部振荡电路的原理。其中LCD1602屏幕显示模块则负责时间、日期、药物种类、用药量等设置[4],将简单介绍其原理组成、指令时序。由LED发光二极管与蜂鸣器电路组成的声光报警系统中,以蜂鸣器警报为主,LED则起到辅助报警功能。系统的基本原理为:各模块驱动程序运行后,系统主程序调用单片机和按键扫描子程序,将扫描结果发送给系统数据更新程序,反馈给LCD1602液晶屏幕显示模块,从而实现按键的输入信息显示功能。在声光报警电路中,程序将调用单片机细分读取数据并输入报警时间。

原理图

 

时间设置用三个按键完成,一个功能按键k1,两个调节按键k2、k3,在屏幕时间显示界面,按下功能按键后即可进入时间设置状态,两个调节按键k2、k3分别为时间增加1、减少1,最后按下功能按键直至退出设置状态,时钟开始工作。

药品用量设置用四个按键完成,两个功能按键,两个调节按键。其中一个功能键作用为屏幕由时间显示转换到药量显示,另一个即进入、退出设置状态。两个调节按键分别为药量增加1、减少1。

声光报警系统中,停止蜂鸣器警报与LED发光二极管的闪烁需要使用到三个按键,分别对应三种药物,按下即可停止;如果没有按下相应按键,则将在一分钟后,程序判定实时时钟超过固定时钟,即实时时间超过定时时间,判断结果为时间不相等,系统自动退出报警程序。

系统结构

 

药盒系统的最小系统图

 

LCD连接方式

 

LCD显示屏指令表

 

LCD屏操作时序

 

除了复位电路模块,在此次的单片机的应用系统中,按键键盘模块部分也是不可或缺的。键盘是计算机全部操作中使用的输入设备之一,通过用手指按压键盘按钮——通常按钮上附有对应文字标签,向计算机发送文字信号等。

键盘的开关主要有膜合开关、机械开关、电容无接点方式,其中,膜合开关和机械开关是完全数字的开关,只有触点关闭或触点打开两种状态。

本系统键盘电路共由8个按键按钮组成,并根据4×2的格式进行布局焊接。

按下键帽时,内置的电路成为闭路,电流流动,作为电信号被编码器读取并作为数字信号输入到单片机系统中。

本次系统所采用的是电磁式蜂鸣器,是利用电磁线圈对蜂鸣片的作用而发声,相对于压电式蜂鸣器,其运作时所需要的电压较低。

 

发光二极管是二极管的一种,与荧光灯、白炽灯泡等许多其他光源不同,LED会产生偏向特定波长的光。因此,有时由于不包含亮度所需要的波长的光,所以不能得到充分的效果。但LED结构简单,可以大量生产,从而价格相对白炽灯、荧光灯较为低廉,在当今市场上被广泛应用[5]。虽然LED对高温缺乏耐受性,其半导体的材质有可能因电路产生问题而发生故障,但其由于不使用灯丝,重量轻且耐冲击性强,由此可知寿命比白炽灯长。并且与需要稳定器的荧光灯相比,LED的电路比较简单。

发光二极管与其他一般二极管一样具有极性,在阳极上加正电压用于阴极,即电源正极与发光二极管的正极相连,阴极同理,此时将该电路中的电压称为“正向下降电压”。与一般将硅用作主原料的二极管相比,发光二极管的正向下降电压高。

发光二极管连接图

 

 时钟模块

单片机中,具有处理时间和一定周期等形式的时间相关功能的是定时/计时器。本次设计采用的是DS1302时钟芯片作为系统的定时/计时器,通过传送多个字节的时钟信号或RAM数据,对年月日期及时分秒进行计时。

时钟信号是指在电子基板和半导体芯片等内部,为了使多个电子电路发送接收信号的定时一致,有规则地被刻上的电信号。通过这样的信号使各电路的动作同步的方式称为时钟同步设计。信号的形式有几种,但最简单的时钟信号每隔一定的时间切换高电压和低电压,将电压从上升到下一个上升的时间(或从下降到下一个下降的时间)称为“时钟周期”,每单位时间的周期数 “时钟频率”。时钟频率越高,越能高速处理和收发数据。

时钟信号是由内置水晶和陶瓷振子的时钟振荡电路发出的,通过专用的信号线提供给各电路。虽然基板上的芯片或电路根据单个时钟进行操作,但是也可以仅在诸如CPU之类的特定芯片内以来自外部的信号的数倍的时钟信号高速工作。

时钟芯片原理图

 蓝牙模块

无线通信主要是利用电波进行的电子通信,而使用电缆等作为传输线的通信称为有线通信。蓝牙是无线通信技术之一。使用超短波2.4GHz带宽,无线连接近距离的数字设备[7]。

蓝牙是一种只有小基础和电池的小型轻量装置,与Wi-Fi等无线LAN相比,价格与功耗较低,并且对于开发者来说具有较为容易理解的数据模型,在此基础上可以自由扩展功能,应用于各种服务。

 

系统软件设计

系统主要模块软件设计结构

 系统主程序

当本系统主程序运行在不同阶段时,在系统逐步完成各个功能模块的初始化之后,将进入程序的循环状态,即此时系统正在运行扫描程序。之后根据所需,按下键盘模块上的按钮,向系统输入信息,于是系统内置的程序存储库中将信息命令判断并执行,这些操作完成之后LCD1602液晶显示屏将实时显示输入信息,同理可实现定时提醒、设定三种药物的剂量。

主程序流程

 按键函数

系统中的八个按键分别具有不同的职能,以下主要介绍设置键k1、功能键兼调节键k2、k3、调节键k7、k8:

(1)设置键,当屏幕显示实时时间时,按下即进入设置状态,同理可退出设置状态。

(2)在屏幕时间设置状态下,k2作为调节键,起到时间增加1的作用;相反,未进入时间设置状态时,k2作为功能键,按下即进入药量显示状态,此时可对三种药物的用量进行设置。同理,k3作为调节键时起到时间减少1的作用,作为功能键时可切换时间的显示。

(3)调节键k7为药量增加1,则k8为药量减少1。

 中断服务函数

在正常程序运行中,中断处理作为CPU的硬件功能实现,强制中断正常程序的执行。例如,从LED发光二极管闪烁这样简单的处理到在多任务操作系统中,有时必须停止程序的长时间运行。而在本系统时钟模块中,这种情况出现时将利用定时器中的中断子函数进行处理。

 

作品展示 

电路焊接完成得到单片机成品之后,经过对软件程序的设置并烧入,硬件成品上的键盘模块便可实现按键输入功能,对LCD1602屏幕上的时间进行设置与时间的定时,以及对屏幕时间显示内容进行切换显示为三种药品的用量界面,进行用量设置。完成以上步骤之后退出设置状态,系统便会按照设定的数值进行工作,然后在运行时判断是否启动报警程序。

LCD1602液晶屏幕时间显示界面如图25所示,在当前显示界面图中,第一行为日期,其中THU为英文Thursday的缩写,表示2022年4月13日为星期四;第二行为实时时间显示,采用24小时制,其显示分别为小时、分钟、秒.

时间显示
药量显示

 

 

蓝牙连接后的效果图

 测试药定时提醒功能

单片机实物上的键盘模块按钮按从左至右,先第一行后第二行的顺序命名为k1、k2、k3、k4、k5、k6、k7、k8。

如图28所示,按下k1或手机屏幕显示上的“按键①”,进入设置状态,,在此将单片机实时显示时间设定为16:59:54(24小时制)

LCD屏实时时间显示

         再次按下如上相同位置的按键,直至进入定时时间设置状态,“SET TIME1”即第一次定时时间,在此将其设定为17:00。

 最后按下如上相同位置按键,直至退出时间设置状态,此时按下k2或“按键②”后LCD1602屏幕显示DRU1、DRU2、DRU3即三种药物的用量。而后用同上的按键进入设置状态。手机软件显示界面中, “药量加”即k7、“药量减”即k8。默认状态下三种药物用量均为零,需手动设置。到达定时时间时,用量不为一的情况下,声光报警系统发出提醒警报。如图30所示,将药物一用量设定为3,药物二用量为2,药物三用量为1。最后退出设置状态。

 定时时间到,根据设定,如图31所示单片机上三盏LED灯闪烁同时伴随蜂鸣器警报响起。同理,若设定需服用药物种类用量仅为两种或一种,则LED闪烁对应两盏灯或一盏灯。

 按下k2切换LCD屏幕显示药物种类及用量;或如图33所示,按下手机显示屏幕上名为“按键②”的按钮也能达到此目的。

手机“蓝牙串口”软件切换显示药量

 

 完整代码

  1. #include "common.h"
  2. #include "DS1302.h"
  3. #include "lcd1602.h"
  4. #include "uart.h"
  5. #define UART_RX_BUF RX1_Buffer
  6. sbit LED1 = P3^2;
  7. sbit LED2 = P3^3;
  8. sbit LED3 = P3^4;
  9. sbit BEEP = P2^0;
  10. uchar sec, min, hour, day, month, week, year;
  11. sbit p_r=0;
  12. bit displayMode=0;
  13. uchar setn=0;
  14. unsigned char bobao = 0;
  15. unsigned char Dosage1=0;
  16. unsigned char Dosage2=0;
  17. unsigned char Dosage3=0;
  18. uchar tx1_shi = 8,tx1_fen = 0;
  19. uchar tx2_shi = 12,tx2_fen = 0;
  20. uchar tx3_shi = 19,tx3_fen = 0;
  21. uchar REMINDFLAG = 0x00;
  22. void Timer0Init(void)
  23. {
  24. TMOD |= 0x01;
  25. TL0 = 0x00;
  26. TH0 = 0x4C;
  27. ET0 = 1;
  28. TR0 = 1;
  29. EA = 1;
  30. };
  31. void write_week(uchar week)
  32. {
  33. lcd_write_com(0x80+12);
  34. switch(week)
  35. {
  36. case 1:lcd_write_data('M');lcd_write_data('O');lcd_write_data('N');break;
  37. case 2:lcd_write_data('T');lcd_write_data('U');lcd_write_data('E');break;
  38. case 3:lcd_write_data('W');lcd_write_data('E');lcd_write_data('D');break;
  39. case 4:lcd_write_data('T');lcd_write_data('H');lcd_write_data('U');break;
  40. case 5:lcd_write_data('F');lcd_write_data('R');lcd_write_data('I');break;
  41. case 6:lcd_write_data('S'); lcd_write_data('T');lcd_write_data('A');break;
  42. case 7:lcd_write_data('S');lcd_write_data('U');lcd_write_data('N');break;}
  43. lcd_write_data(' ');
  44. }
  45. void displayTime()
  46. {
  47. lcd_write_com(0x80);
  48. lcd_write_data(' ');
  49. lcd_write_data('2');
  50. lcd_write_data('0');
  51. lcd_write_data(year/10+0x30);
  52. lcd_write_data(year%10+0x30);
  53. lcd_write_data('-');
  54. lcd_write_data(month/10+0x30);
  55. lcd_write_data(month%10+0x30);
  56. lcd_write_data('-');
  57. lcd_write_data(day/10+0x30);
  58. lcd_write_data(day%10+0x30);
  59. lcd_write_data(' ');
  60. write_week(week);
  61. lcd_write_com(0x80+0x40+4);
  62. lcd_write_data(hour/10+0x30);
  63. lcd_write_data(hour%10+0x30);
  64. lcd_write_data(':');
  65. lcd_write_data(min/10+0x30);
  66. lcd_write_data(min%10+0x30);
  67. lcd_write_data(':');
  68. lcd_write_data(sec/10+0x30);
  69. lcd_write_data(sec%10+0x30);
  70. }
  71. void Run_DS1302(void)
  72. {
  73. v_W1302(0x8f, 0);
  74. sec = bcdtodec(uc_R1302(0x81));
  75. v_W1302(0x8f, 0);
  76. min = bcdtodec(uc_R1302(0x83));
  77. v_W1302(0x8f, 0);
  78. hour = bcdtodec(uc_R1302(0x85));
  79. v_W1302(0x8f, 0);
  80. day = bcdtodec(uc_R1302(0x87));
  81. v_W1302(0x8f, 0);
  82. month = bcdtodec(uc_R1302(0x89));
  83. v_W1302(0x8f, 0);
  84. week = bcdtodec(uc_R1302(0x8b));
  85. v_W1302(0x8f, 0);
  86. year = bcdtodec(uc_R1302(0x8d));
  87. if(!displayMode)
  88. displayTime();
  89. }
  90. void displayDosage()
  91. {
  92. if(Dosage1==0)
  93. {lcd_write_char(1,1,'-');
  94. lcd_write_char(2,1,'-');}
  95. else{
  96. lcd_write_char(1,1,Dosage1/10+'0');
  97. lcd_write_char(2,1,Dosage1%10+'0');
  98. }
  99. if(Dosage2==0)
  100. {
  101. lcd_write_char(7,1,'-');
  102. lcd_write_char(8,1,'-');}
  103. else{
  104. lcd_write_char(7,1,Dosage2/10+'0');
  105. lcd_write_char(8,1,Dosage2%10+'0');}
  106. if(Dosage3==0)
  107. {
  108. lcd_write_char(13,1,'-');
  109. lcd_write_char(14,1,'-');
  110. }
  111. else
  112. {
  113. lcd_write_char(13,1,Dosage3/10+'0');
  114. lcd_write_char(14,1,Dosage3%10+'0');
  115. }
  116. }
  117. //灯状态
  118. void LedState()
  119. {
  120. if(REMINDFLAG&0x01)
  121. LED1=0;
  122. else
  123. LED1=1;
  124. if(REMINDFLAG&0x02)
  125. LED2=0;
  126. else
  127. LED2=1;
  128. if(REMINDFLAG&0x04)
  129. LED3=0;
  130. else LED3=1;
  131. }
  132. //按键扫描
  133. void keyscan()
  134. {
  135. uint nian_temp;
  136. if(P1==0xFE || strstr(UART_RX_BUF,"k1")!=NULL)
  137. {
  138. delay_ms(30);
  139. if(P1==0xFE || strstr(UART_RX_BUF,"k1")!=NULL)
  140. {
  141. memset(UART_RX_BUF, 0, COM_RX1_Lenth);
  142. RX1_RxCounter = 0;
  143. bobao = 0;
  144. setn++;
  145. if(!displayMode
  146. {
  147. if(setn > 13){setn = 0;
  148. lcd_write_com(0x0c);
  149. lcd_clear();}
  150. if(setn == 1)
  151. {
  152. bobao = 0;
  153. displayTime();
  154. lcd_write_com(0x80+4);
  155. lcd_write_com(0x0f);}
  156. if(setn == 2)
  157. {
  158. lcd_write_com(0x80+7);
  159. lcd_write_com(0x0f);
  160. }
  161. if(setn == 3)
  162. {
  163. lcd_write_com(0x80+10);
  164. lcd_write_com(0x0f);
  165. }
  166. if(setn == 4)
  167. {
  168. lcd_write_com(0x80+14);
  169. lcd_write_com(0x0f);
  170. }
  171. if(setn == 5)
  172. {
  173. lcd_write_com(0x80+0x40+5);
  174. lcd_write_com(0x0f);
  175. }
  176. if(setn == 6)
  177. {
  178. lcd_write_com(0x80+0x40+8);
  179. lcd_write_com(0x0f);
  180. }
  181. if(setn == 7)
  182. {
  183. lcd_write_com(0x80+0x40+11);
  184. lcd_write_com(0x0f);
  185. }
  186. if(setn == 8)
  187. {
  188. lcd_write_str(0,0," SET TIME 1 ");
  189. lcd_write_str(0,1," 00:00 ");
  190. lcd_write_com(0x80+0x40+6);
  191. lcd_write_data(tx1_shi/10 + 0x30);
  192. lcd_write_data(tx1_shi%10 + 0x30);
  193. lcd_write_data(':');
  194. lcd_write_data(tx1_fen/10 + 0x30);
  195. lcd_write_data(tx1_fen%10 + 0x30);
  196. lcd_write_com(0x80+0x40+7);
  197. lcd_write_com(0x0F);
  198. }
  199. if(setn == 9)
  200. {
  201. lcd_write_com(0x80+0x40+10);
  202. lcd_write_com(0x0F);
  203. }
  204. if(setn == 10)
  205. {
  206. lcd_write_str(0,0," SET TIME 2 ");
  207. lcd_write_str(0,1," 00:00 ");
  208. lcd_write_com(0x80+0x40+6);
  209. lcd_write_data(tx2_shi/10 + 0x30);
  210. lcd_write_data(tx2_shi%10 + 0x30);
  211. lcd_write_data(':');
  212. lcd_write_data(tx2_fen/10 + 0x30);
  213. lcd_write_data(tx2_fen%10 + 0x30);
  214. lcd_write_com(0x80+0x40+7);
  215. lcd_write_com(0x0F);
  216. }
  217. if(setn == 11)
  218. {
  219. lcd_write_com(0x80+0x40+10);
  220. lcd_write_com(0x0F);
  221. }
  222. if(setn == 12)
  223. {
  224. lcd_write_str(0,0," SET TIME 3 ");
  225. lcd_write_str(0,1," 00:00 ");
  226. lcd_write_com(0x80+0x40+6);
  227. lcd_write_data(tx3_shi/10 + 0x30);
  228. lcd_write_data(tx3_shi%10 + 0x30);
  229. lcd_write_data(':');
  230. lcd_write_data(tx3_fen/10 + 0x30);
  231. lcd_write_data(tx3_fen%10 + 0x30);
  232. lcd_write_com(0x80+0x40+7);
  233. lcd_write_com(0x0F);
  234. }
  235. if(setn == 13)
  236. {
  237. lcd_write_com(0x80+0x40+10);
  238. lcd_write_com(0x0F);
  239. }
  240. }
  241. else{if(setn > 3)
  242. {
  243. setn = 0;
  244. lcd_write_com(0x0c);
  245. }
  246. if(setn == 1) {lcd_write_com(0x80+0x40+2); lcd_write_com(0x0f); }
  247. if(setn == 2) {lcd_write_com(0x80+0x40+8); lcd_write_com(0x0f);}
  248. if(setn == 3) {lcd_write_com(0x80+0x40+14);lcd_write_com(0x0f);}}while(P1==0xFE);}
  249. }
  250. if(P1==0xFD || strstr(UART_RX_BUF,"k2")!=NULL){delay_ms(20);
  251. if(P1==0xFD || strstr(UART_RX_BUF,"k2")!=NULL){ memset(UART_RX_BUF, 0, COM_RX1_Lenth);
  252. RX1_RxCounter = 0;
  253. if(setn == 0)
  254. {
  255. displayMode=1;
  256. lcd_clear();
  257. if(displayMode)
  258. {
  259. lcd_write_str(0,0,"DRU1| DRU2 |DRU3");
  260. lcd_write_str(0,1," | | ");
  261. displayDosage();
  262. }
  263. }
  264. if(!displayMode){
  265. if(setn == 1){
  266. year++;if(year == 100)year = 0;
  267. Write_DS1302Init(year,month,day,week,hour,min,sec);
  268. nian_temp=2000+year;
  269. if((nian_temp%400==0)||((nian_temp%100!=0)&&(nian_temp%4==0)))p_r=1;
  270. elsep_r=0;
  271. displayTime();
  272. lcd_write_com(0x80+4);
  273. lcd_write_com(0x0f);
  274. }
  275. else if(setn == 2)
  276. {
  277. month++;
  278. if(month==13) month=1;
  279. if((month==4)||(month==6)||(month==9)||(month==11))
  280. {
  281. if(day>30)day=1;
  282. }
  283. else{if(month==2) {if(p_r==1) {if(day>29) day=1; }else{if(day>28) day=1; }}}
  284. Write_DS1302Init(year,month,day,week,hour,min,sec); displayTime();
  285. lcd_write_com(0x80+7); lcd_write_com(0x0f);} else if(setn == 3)
  286. { day++;if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12)) {if(day==32) day=1;}
  287. else{if(month==2){if(p_r==1){if(day==30) day=1;}else{if(day==29)day=1;}}
  288. else{if(day==31)day=1; }}Write_DS1302Init(year,month,day,week,hour,min,sec);displayTime();lcd_write_com(0x80+10);

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/article/detail/39053
推荐阅读
相关标签
  

闽ICP备14008679号