功能:
0.本系统采用单片机STC89C52作为系统的主控芯片
1.持续监测老人体温和姿态
2.超过设定温度阈值或姿态异常持续时间较长,蜂鸣器报警提醒,并向目标手机号发送短信
3.发送*SET#可配置接收短信号码
4.开机过程按下按键直到蜂鸣器提示,可清空接收短信号码
5.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#include <math.h> //Keil library
#include "delay.h"
#include "18b20.h"
#include "adxl345.h"
#include "uart.h"
#include "gsm_at.h"
#include "eeprom52.h"
#include "data_unit.h"
sbit BUZZER = P2^2; //定义接口
sbit KEY = P3^2;
sbit LED_RED = P3^5;
#define BUZZER_ON (BUZZER = 0)
#define BUZZER_OFF (BUZZER = 1)
#define LED_RED_ON (LED_RED = 0)
#define LED_RED_OFF (LED_RED = 1)
unsigned char fallFlag = 0; //发送消息标志
unsigned char readADXFlag = 0; //读取标志
unsigned char fallDelaySec = 0; //摔倒计时
bit readTemFlag = 0; //读取温度
int tempBuf = 0;
unsigned char hotDelaySec = 0; //温度过高计时
unsigned char hotFlag = 0; //温度过高标志
unsigned char i;
unsigned char x;
unsigned char err_num = 0;
unsigned char dis[10];
void Init_Timer0(void); //函数声明
void main(void)
{
static unsigned char ErrorNum = 0; //adxl345数据判断结果计数
static unsigned char CheckNum = 0;
float temperature = 0.0;
Init_Timer0(); //定时器0初始化
UART_Init();
DS18B20_Start();
DS18B20_GetTemp(&tempBuf); //读取温度
temperature = (float)tempBuf * 0.0625;
DelayS(5);
err_num = GSM_Init(); //GSM初始化
DelayMs(10);
if (gsm_init_flag) //初始化完成
{
err_num = GSM_Text_Mode(); //GSM 设置Text模式
}
DelayMs(10);
if (gsm_config_flag)
{
err_num = GSM_Delete_Sms("1"); //删除短信1
}
DelayMs(10);
if (!(gsm_init_flag || gsm_config_flag || gsm_delete_flag)) // AT命令报错,蜂鸣器响5声
{
unsigned char i = 0;
for (i = 0; i < 5; i++)
{
BUZZER_ON;
LED_RED_ON;
DelayMs(250);
BUZZER_OFF;
LED_RED_OFF;
DelayMs(250);
}
}
else //GSM初始化完成蜂鸣器响一声
{
BUZZER_ON;
LED_RED_ON;
DelayS(1);
BUZZER_OFF;
LED_RED_OFF;
}
DelayS(1);
if (!KEY) //开机过程中按键,初始化电话号码为xxxxxxxxxxx
{
DelayMs(20);
if (!KEY)
{
unsigned char i = 0;
for (i = 1; i < 12; i++)
{
phone1[i] = 'x';
}
Phone_Num_Write(); //保存数据
BUZZER_ON;
LED_RED_ON;
DelayS(1);
BUZZER_OFF;
LED_RED_OFF;
UART_Send_Str(phone1, 15);
}
}
DS18B20_Start();
DS18B20_GetTemp(&tempBuf); //读取温度
temperature = (float)tempBuf * 0.0625;
DelayS(3);
Init_ADXL345(); //初始化ADXL345
Single_Read_ADXL345(0X00); //读出的数据为0XE5,表示正确
EEPROM52_Init();
UART_Send_Str(phone1, 15);
BUZZER = 1;
while (1) //主循环
{
gsm_receive_process(); //gsm接收处理
if (readTemFlag == 1) //定时读取温度标志
{
readTemFlag = 0;
GSM_Delete_Sms("1"); // 定时删除短信1
DS18B20_Start();
DS18B20_GetTemp(&tempBuf); //读取温度
temperature = (float)tempBuf * 0.0625;
sprintf(dis, "%5.1f\r\n", temperature);
UART_Send_Str(dis, 7); //串口发送温度
if (temperature >= 38.0) //温度过高
{
hotFlag = 1;
} //温度过高标志
else
{
hotFlag = 0;
} //清除温度过高标志
if (hotFlag == 1)
hotDelaySec++; //温度过高计时 1s处理一次
else
hotDelaySec = 0; //否则清零
if (fallFlag == 1)
fallDelaySec++; //温度过高计时 1s处理一次
else
fallDelaySec = 0; //否则清零
}
if (readADXFlag == 1)
{
readADXFlag = 0;
ReadData_XYZ();
CheckNum++;
sprintf(dis, "%5.1f\r\n", temp_X);
UART_Send_Str(dis, 7); //串口发送温度
sprintf(dis, "%5.1f\r\n", (float)(abs(temp_Y)));
UART_Send_Str(dis, 7); //串口发送温度
if ((temp_X < 450) || (abs(temp_Y) > 750)) //方位值判断 查看错误次数
{
ErrorNum++;
}
if (CheckNum >= 5) //进行5次处理
{
if (ErrorNum > 3) //3次以上错误情况 进行上报
{
fallFlag = 1;
} //摔倒标志
else
{
fallFlag = 0;
} //清除 摔倒标志
ErrorNum = 0; //清空滤波计数
CheckNum = 0; //清除总计数
}
}
if ((hotFlag == 0) && (fallFlag == 0))
{
BUZZER_OFF; //关闭蜂鸣器
LED_RED_OFF;
}
if ((hotDelaySec >= 15) || (fallDelaySec >= 15)) //15S 上报
{
BUZZER_ON;
LED_RED_ON;
if (hotDelaySec >= 15)
{
if(GSM_Send_Sms(phone1, "Have a fever!!") == 7)
{ //发送失败则报警,可能没有设定初始号码
for (i = 0; i < 5; i++)
{
BUZZER_ON;
LED_RED_ON;
DelayMs(250);
BUZZER_OFF;
LED_RED_OFF;
DelayMs(250);
}
}
if (gsm_send_flag == 1) //发送成功,蜂鸣器响一声
{
BUZZER_ON;
LED_RED_ON;
DelayS(1);
BUZZER_OFF;
LED_RED_OFF;
}
hotDelaySec = 0; //清除计数
}
if (fallDelaySec >= 15)
{
if(GSM_Send_Sms(phone1, "Help me!!") == 7)
{ //发送失败则报警,可能没有设定初始号码
for (i = 0; i < 5; i++)
{
BUZZER_ON;
LED_RED_ON;
DelayMs(250);
BUZZER_OFF;
LED_RED_OFF;
DelayMs(250);
}
}
if (gsm_send_flag == 1) //发送成功,蜂鸣器响一声
{
BUZZER_ON;
LED_RED_ON;
DelayS(1);
BUZZER_OFF;
LED_RED_OFF;
}
fallDelaySec = 0; //清除计数
}
DelayS(2);
}
if (KEY == 0)
{
DelayMs(20);
if (KEY == 0)
{
hotFlag = 0; //上报过热标志清零
fallFlag = 0; //摔倒标志 清零
BUZZER_OFF; //关闭蜂鸣器
}
}
}
}
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0 = (65536 - 18432) / 256; //重新赋值 20ms
TL0 = (65536 - 18432) % 256;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}
void Timer0_isr(void) interrupt 1
{
static unsigned char times_20ms = 0; //定时20ms计时
TH0 = (65536 - 18432) / 256; //重新赋值 20ms
TL0 = (65536 - 18432) % 256;
times_20ms++;
if (times_20ms > 50)
{
times_20ms = 0;
readTemFlag = 1; //温度读取
}
if (times_20ms % 10 == 0) //定时200ms
{
readADXFlag = 1; //读取标志置位
}
}