一、系統方案
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 或者 Swrite_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 或者 Wwrite_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仿真軟件就很好的解決這個問題,我們在設計之初,就使用該軟件進行模擬仿真,測試,選擇滿足我們設計的最優方案。最后根據測試沒問題的仿真圖紙,焊接實物,調試,最終完成本設計的作品。