一、系统方案
1、本设计采用这51单片机作为主控器。
2、MPU6050角度值送到液晶1602显示。
3、红外传感器检测心率。
4、跌倒远程GSM报警。
二、硬件设计
原理图如下:
三、单片机软件设计
1、首先是系统初始化
void LCD_Init() //初始化液晶时间显示
{
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80+0x10);
}
void LCD_Clear(void)
{
write_com(0x01);
}
2、液晶显示程序
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x–)
for(y=110;y>0;y–);
}
void write_com(uchar com)
{
w=0;
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_dat(uchar date)
{
w=0;
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_char(uchar x,uchar y,uchar dat)
{
if (x == 0)
{
write_com(0x80 + y);
}
else
{
write_com(0xC0 + y);
}
write_dat(dat);
}
void write_string(uchar x,uchar y,uchar *s) //显示字符串
{
if(x==0)
write_com(0x80+y);
else
write_com(0xc0+y);
while(*s)
{
write_dat(*s);
s++;
}
}
void shownum(uchar x,uchar y,int dat,uchar n) //x=行 y=列 dat 数据位
{
if(n5)
{
if(x0)
{
write_com(0x80+y); //显示湿度值
write_dat(dat%100000/10000+0x30);
write_dat(dat%10000/1000+0x30);
write_dat(dat%1000/100+0x30);
write_dat(dat%100/10+0x30);
write_dat(dat%10+0x30);
}
if(x==1)
{
write_com(0xc0+y); //显示湿度值
write_dat(dat%100000/10000+0x30);
write_dat(dat%10000/1000+0x30);
write_dat(dat%1000/100+0x30);
write_dat(dat%100/10+0x30);
write_dat(dat%10+0x30);
}
}
if(n==4)
{
if(x==0)
{
write_com(0x80+y); //显示湿度值
write_dat(dat%10000/1000+0x30);
write_dat(dat%1000/100+0x30);
write_dat(dat%100/10+0x30);
write_dat(dat%10+0x30);
}
if(x==1)
{
write_com(0xc0+y); //显示湿度值
write_dat(dat%10000/1000+0x30);
write_dat(dat%1000/100+0x30);
write_dat(dat%100/10+0x30);
write_dat(dat%10+0x30);
}
}
if(n==3)
{
if(x==0)
{
write_com(0x80+y);
write_dat(dat%1000/100+0x30);
write_dat(dat%100/10+0x30);
write_dat(dat%10+0x30);
}
if(x==1)
{
write_com(0xc0+y);
write_dat(dat%1000/100+0x30);
write_dat(dat%100/10+0x30);
write_dat(dat%10+0x30);
}
}
if(n==2)
{
if(x==0)
{
write_com(0x80+y);
write_dat(dat%100/10+0x30);
write_dat(dat%10+0x30);
}
if(x==1)
{
write_com(0xc0+y);
write_dat(dat%100/10+0x30);
write_dat(dat%10+0x30);
}
}
}
3、MPU6050程序
void show_x()
{
int i;
float t;
i=GetData(ACCEL_XOUT_H); //X ,16位
i/=64; //转换为10位数据
if(i<0)
{
i=-i;
// DisplayOneChar(2,1,‘-’);
write_com(0xC0+8);
write_dat(0x2D);
}
else
{
write_com(0xC0+8);
write_dat(0x2B);
}
t=(float)i*3.9;
if(t>800)
{
beep1();
}
else
beep=1;
write_dat((uint)t/1000+0x30);
write_dat(0x2e);
write_dat((uint)t%1000/100+0x30);
}
void show_y()
{
int i;
float t;
i=GetData(ACCEL_YOUT_H); //X ,16位
i/=64; //转换为10位数据 1024
if(i<0)
{
i=-i;
// DisplayOneChar(2,1,‘-’);
write_com(0xC0+8);
write_dat(0x2D);
}
else
{
write_com(0xC0+8);
write_dat(0x2B);
}
t=(float)i*3.9;
write_dat((uint)t/1000+0x30);
write_dat(0x2e);
write_dat((uint)t%1000/100+0x30);
}
void show_z()
{
int i;
float t;
i=GetData(ACCEL_ZOUT_H); //X ,16位
i/=64; //转换为10位数据
if(i<0)
{
i=-i;
// DisplayOneChar(2,1,‘-’);
write_com(0x80+2);
write_dat(0x2D);
}
else
{
write_com(0x80+2);
write_dat(0x2B); //+
}
t=(float)i*31; //转化为90度
angle=(uint)t/100+(uint)t%1000/100;
// shownum(0,8,angle,4);
write_dat((uint)t/1000+0x30);
write_dat(0x2e);
write_dat((uint)t%1000/100+0x30);
}
void show_sx()
{
int i;
float t;
i=GetData(GYRO_XOUT_H); //X ,16位
i/=64; //转换为10位数据
if(i<0)
{
i=-i;
flag=0;
angle=i;
// DisplayOneChar(2,1,‘-’);
write_com(0xC0+8);
write_dat(0x2D); //-
}
else
{
flag=1;
angle=i;
write_com(0xC0+8);
write_dat(0x2B); //+
}
if(i>10)
beep2();
else
beep=1;
write_dat(i/1000+0x30);
write_dat(i%100/10+0x30);
write_dat(i%10+0x30);
}
void show_sy()
{
int i;
float t;
i=GetData(GYRO_YOUT_H); //X ,16位
i/=64; //转换为10位数据
if(i<0)
{
// DisplayOneChar(2,1,‘-’);
i=-i;
flag=0;
angle=i;
write_com(0xC0+8);
write_dat(0x2D);
}
else
{
flag=1;
angle=i;
write_com(0xC0+8);
write_dat(0x2B);
}
write_dat(i/1000+0x30);
write_dat(i%100/10+0x30);
write_dat(i%10+0x30);
}
void show_sz()
{
int i;
float t;
i=GetData(GYRO_ZOUT_H); //X ,16位
i/=64; //转换为10位数据
if(i<0)
{
i=-i;
flag=0;
angle=i;
// DisplayOneChar(2,1,‘-’);
write_com(0xC0+8);
write_dat(0x2D);
}
else
{
flag=1;
angle=i;
write_com(0xC0+8);
write_dat(0x2B);
}
write_dat(i/100+0x30);
write_dat(i%100/10+0x30);
write_dat(i%10+0x30);
}
4、核心算法程序
void main()
{
LCD_Init() ;
InitMPU6050(); //
init_uart();
// Time0_init();
write_string(0,0," Please “);
write_string(1,0,” Wait ");
delayms(1000);
LCD_Clear() ;
delayms(500);
write_string(0,0,“A:”);
write_char(0,5,0xdf) ;
while(1)
{
show_z();
Alarm(angle);
if(displayOK==0)//如果显示关
{
rate = 0;
}
else//如果显示开
{
rate=60000/(time[1]/5+time[2]/5+time[3]/5+time[4]/5+time[5]/5); //计算脉搏次数
}
write_com(0x80+7);
write_dat(rate/100+0x30);
write_dat(rate%100/10+0x30);
write_dat(rate%10+0x30);
write_dat('/');
write_dat('m');
write_dat('i');
write_dat('n');
if(Flag_GPS_OK == 1 && RX_Buffer[4] == 'G' && RX_Buffer[6] == ',' && RX_Buffer[13] == '.') //确定是否收到"GPGGA"这一帧数据
{
for( i = 0; i < 68 ; i++)
{
Display_GPGGA_Buffer[i] = RX_Buffer[i];
}
Flag_Calc_GPGGA_OK = 1;
}
if(Flag_Calc_GPGGA_OK == 1)
{
Flag_Calc_GPGGA_OK = 0;
write_com(0x80+0x40); //设置指针
write_dat(Display_GPGGA_Buffer[28]); //N 或者 S
write_dat(Display_GPGGA_Buffer[17]); //纬度
write_dat(Display_GPGGA_Buffer[18]); //纬度
write_dat('.'); //.
write_dat(Display_GPGGA_Buffer[19]); //纬度
write_dat(Display_GPGGA_Buffer[20]); //纬度
write_dat(' ');
write_dat(Display_GPGGA_Buffer[42]); //E 或者 W
write_dat(Display_GPGGA_Buffer[30]); //经度
write_dat(Display_GPGGA_Buffer[31]);
write_dat(Display_GPGGA_Buffer[32]);
write_dat('.'); //.
write_dat(Display_GPGGA_Buffer[33]);
write_dat(Display_GPGGA_Buffer[34]);
}
}
}
四、 proteus仿真设计
Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。