功能:
0.本项目采用STM32F103C8T6作为单片机系统的控制MCU
1.该设计具备四个功能按键可设置时钟和用药时间
2.系统具备三组用药时间,可通过按键设置某时间对应多少药片
3.一旦时间达到,系统会驱动继电器打开药盒,本设计采用的是5V的电磁铁来模拟演示药盒打开的过程
4.采用DC002作为电源接口可直接输入5V给整个系统供电
5.本系统同时具备了WiFi模块,可通过手机端监测该系统的运行情况
原理图:
PCB :
主程序:
#define __MIAN_C
#include "main.h"
// 局部变量,用于保存转换计算后的电压值
CreatByte Flag;
enum _MODE_DF_ dispMode;
char dis[16];
volatile u8 setIndex = 0;
volatile u8 dosage[3][3] = {{1,1,1},{2,2,2},{3,3,3}}; //用药量
volatile u8 timeLimit[3][2] = {{9,0},{12,0},{18,0}};
volatile u8 medicineFlag = 0;
int main(void)
{
relayFlag1 = 0; //开锁标志1
relayFlag2 = 0; //开锁标志2
// 使用HSI,SYSCLK = 4M * RCC_PLLMul_x, x:[2,3,...16],最高是64MH
HSI_SetSysClock(RCC_PLLMul_2); //使用内部8MHz晶振,并设置PLL输出为8MHz
// 端口初始化
GPIO_Config();
GENERAL_TIM_Init();
USART1_Config();
USART3_Config();
DelayMs(1000);
Usart_SendString(DEBUG_USART3, "AT+CIPMUX=1\r\n");//打开多连接
DelayMs(1000);
Usart_SendString(DEBUG_USART3, "AT+CIPSERVER=1,8080\r\n");//建立服务 端口号为8080
DelayMs(1000);
Key_GPIO_Config();
DelayMs(200);
DS1302_Init();
DelayMs(200);
LCD_GPIO_Init();
LCD12864_Init();
LCD12864_Clear();
DelayMs(200);
while (1)
{
if (refreshFlag == 1)
{
refreshFlag = 0;
if (dispMode == NORMAL)
{
DS1302_ReadTime();
RelayCtrl();
DispNormal(medicineFlag);
}
}
KeyProcess();
}
}
void RelayCtrl(void)
{
if ((timeBufDec[4] == timeLimit[0][0]) && (timeBufDec[5] == timeLimit[0][1]) && timeBufDec[6] == 0) //用药时间0到
{
relayFlag1 = 1;
medicineFlag = 1;
}
else if ((timeBufDec[4] == timeLimit[1][0]) && (timeBufDec[5] == timeLimit[1][1]) && timeBufDec[6] == 0) //用药时间1到
{
relayFlag1 = 1;
medicineFlag = 2;
}
else if ((timeBufDec[4] == timeLimit[2][0]) && (timeBufDec[5] == timeLimit[2][1]) && timeBufDec[6] == 0) //用药时间2到
{
relayFlag1 = 1;
medicineFlag = 3;
}
// else
// {
// // relayFlag1 = 0;
// medicineFlag = 0;
// }
if (relayFlag1 == 1 || relayFlag2 == 1) // relay打开
{
RELAY_ON;
relayFlag1 = 0;
relayFlag2 = 0;
}
else
{
RELAY_OFF;
}
}
void DispNormal(u8 i)
{
static unsigned int cnt = 0;
if (i != 0) //吃药时间到
{
LCD12864_DrawHz(0, 0, "该吃药了! ");
LCD12864_DrawHz(0, 1, "药物一: ");
sprintf(dis, "%2d", dosage[i-1][0]);
LCD12864_DrawNum(4, 1, dis);
LCD12864_DrawHz(5, 1, "片 ");
LCD12864_DrawHz(0, 2, "药物二: ");
sprintf(dis, "%2d", dosage[i-1][1]);
LCD12864_DrawNum(4, 2, dis);
LCD12864_DrawHz(5, 2, "片 ");
LCD12864_DrawHz(0, 3, "药物三: ");
sprintf(dis, "%2d", dosage[i-1][2]);
LCD12864_DrawNum(4, 3, dis);
LCD12864_DrawHz(5, 3, "片 ");
cnt++;
if (cnt > 60)
{
medicineFlag = 0;
cnt = 0;
}
else if (cnt == 1 || cnt == 20 || cnt == 40)
{
printf("该吃药了 药物一 %d 片 药物二 %d 片 药物三 %d 片", dosage[i-1][0], dosage[i-1][1], dosage[i-1][2]); //语言播报
}
}
else
{
LCD12864_DrawHz(0, 0, " 当前时间 ");
sprintf(dis, " 20%02d/ %02d/ %02d ", timeBufDec[1], timeBufDec[2], timeBufDec[3]);
LCD12864_DrawNum(0, 1, dis);
sprintf(dis, " %02d: %02d: %02d ", timeBufDec[4], timeBufDec[5], timeBufDec[6]);
LCD12864_DrawNum(0, 2, dis);
LCD12864_DrawHz(0, 3, " ");
}
}
void DispSetRealTime(u8 setIndex)
{
LCD12864_DrawHz(0, 0, " 更改时间 ");
sprintf(dis, " 20%02d/ %02d/ %02d ", timeBufDec[1], timeBufDec[2], timeBufDec[3]);
LCD12864_DrawNum(0, 1, dis);
sprintf(dis, " %02d: %02d: %02d ", timeBufDec[4], timeBufDec[5], timeBufDec[6]);
LCD12864_DrawNum(0, 2, dis);
LCD12864_DrawHz(0, 3, " ");
if (setIndex == 0)
{
LCD12864_Cursor(0);
}
else
{
LCD12864_Cursor(1);
}
switch (setIndex)
{
case 1: LCD12864_SetXY(2, 1); break;
case 2: LCD12864_SetXY(4, 1); break;
case 3: LCD12864_SetXY(6, 1); break;
case 4: LCD12864_SetXY(2, 2); break;
case 5: LCD12864_SetXY(4, 2); break;
case 6: LCD12864_SetXY(6, 2); break;
default: ;
}
}
void DispSetMedicationTime(u8 i, u8 setIndex)
{
LCD12864_DrawHz(0, 0, "用药时间:");
sprintf(dis, "%02d: %02d", timeLimit[i-1][0], timeLimit[i-1][1]);
LCD12864_DrawNum(5, 0, dis);
LCD12864_DrawHz(0, 1, "药物一: ");
sprintf(dis, "%2d", dosage[i-1][0]);
LCD12864_DrawNum(4, 1, dis);
LCD12864_DrawHz(5, 1, "片");
LCD12864_DrawHz(0, 2, "药物二: ");
sprintf(dis, "%2d", dosage[i-1][1]);
LCD12864_DrawNum(4, 2, dis);
LCD12864_DrawHz(5, 2, "片");
LCD12864_DrawHz(0, 3, "药物三: ");
sprintf(dis, "%2d", dosage[i-1][2]);
LCD12864_DrawNum(4, 3, dis);
LCD12864_DrawHz(5, 3, "片");
if (setIndex == 0)
{
LCD12864_Cursor(0);
}
else
{
LCD12864_Cursor(1);
}
switch (setIndex)
{
case 1: LCD12864_SetXY(5 , 0); break;
case 2: LCD12864_SetXY(7 , 0); break;
case 3: LCD12864_SetXY(4 , 1); break;
case 4: LCD12864_SetXY(4, 2); break;
case 5: LCD12864_SetXY(4 , 3); break;
default: ;
}
}
/*********************************************END OF FILE**********************/