说明:
智能体重秤主要由压力秤模块、MPU 模块和 App 模块构成,将智能体重秤放置在床边,每日清晨起床时站在秤上测量一下自己的体重,体重秤会通过数码管将体重显示出来,并与已知数据比较,系统会自动发出提示语音,然后通过内置在体重秤内的蓝牙模块将数据传送到手机App 客户端,将数据记录下来,坚持每日测量的话,系统会根据每日的测量数据绘制体重曲线,进而通过曲线分析人体健康状况,并给出合理建议。用户还可以随时查询之前的体重数据,通过对比来更好地把握自己的健康状况。
通过人体体重变化来监测人体健康情况已有相关文献研究,我们可以借鉴相关的一些研究成果来对人体健康状况进行分析。
模块划分:
①定时器模块:定时期间只记录一次数据,两次计数之间用定时器定时。
②HX711 数据采集模块:采集来自 HX711 的串行数据。
③串口模块:单片机与手机蓝牙串口助手交互功能。
④数码管模块:依据不同的工作模式显示不同的数据。
⑤按键功能模块:根据不同的按键,进入不同的工作模式。共包括:测量模式、记录模式、查询模式、清零模式
代码:
1 #include "io430.h" 2 #include "in430.h" 3 4 unsigned long int HX711_Read(); //HX711数据采集函数声明 5 void Segshow(int n,int a,int b,int c,int d); //数码管显示函数声明 6 void HC595SendData(unsigned char SendVal); //HC5955数据移入函数声明 7 void HC595ShowData(); //HC5955数据发送函数声明 8 void HX711_delay(); //HX711采集延迟函数声明 9 void USCIA0_init(); //蓝牙设置初始化函数声明 10 void HX711_init(); //HX711设置初始化函数声明 11 void TAO_init(); //定时器设置初始化函数声明 12 void GPIO_init(); //GPIO设置初始化函数声明 13 char int_char(int n); //数据格式转换函数声明 14 void delay(); //延时按键防抖函数声明 15 char buffer[32]; //蓝牙收发数据缓冲区 16 char advice1[50]="more exercise and less meat!”;//建议1字符串 17 char advice2[50]="good body and keep on!”; //建议2字符串 18 int weightdata[32]; //记录体重数据的数据串 19 unsigned int j=0; //计数变量i、j、k、l、p 20 unsigned int i=0; 21 unsigned int k=0; 22 unsigned int l=0; 23 unsigned int p=0; 24 int num1,num2,num3,num4,n; //数码管参数 25 int count1=0; //两次采集数据之间间隔计时 26 int flag1=0; //测量模式 27 int flag2=0; //记录模式 28 int flag3=0; //查询模式 29 int flag4=0; //建议1发送 30 int flag5=0; //建议2发送 31 32 int main( void ) 33 { 34 WDTCTL = WDTPW + WDTHOLD; //关闭看门狗 35 unsigned int m=0; //数码管选通计数变量 36 37 _EINT(); //中断总控位打开 38 USCIA0_init(); 39 HX711_init(); 40 GPIO_init(); 41 TAO_init(); 42 IE2|=UCA0RXIE; //接收中断位打开 43 44 //**************************************************** 45 //主循环:功能模式、数码管显示 46 //**************************************************** 47 while(1) 48 { 49 if(flag1==1)//测量模式 50 { 51 num4=(n)%10; 52 num3=(n%100)/10; 53 num2=n/100; 54 num1=0; 55 } 56 else if(flag2==1) //记录模式 57 { 58 num4=(weightdata[k-1])%10; 59 num3=(weightdata[k-1]%100)/10; 60 num2=weightdata[k-1]/100; 61 num1=0; 62 } 63 else if(flag3==1) //查询模式 64 { 65 num4=(weightdata[l])%10; 66 num3=(weightdata[l]%100)/10; 67 num2=weightdata[l]/100; 68 num1=0; 69 } 70 else //查询清零模式 71 { 72 num4=0; 73 num3=0; 74 num2=0; 75 num1=0; 76 } 77 Segshow(m,num1,num2,num3,num4); 78 m=m+1; 79 if(m==4) m=0; 80 } 81 } 82 83 //**************************************************** 84 //中断子函数 85 //**************************************************** 86 87 #pragma vector=TIMER0_A0_VECTOR //定时器中断 88 __interrupt void timer0_A0_ISR() 89 { 90 if(count1<30) 91 count1=count1+1; 92 if(count1==30) 93 { 94 n=(HX711_Read()-8529600)/1000;//采集数据 95 count1=0; 96 } 97 } 98 99 #pragma vector=USCIAB0RX_VECTOR //蓝牙接收中断 100 __interrupt void UCA0RX_isr() 101 { 102 buffer[j]=UCA0RXBUF; //读接收缓冲器保存一个字符 103 j++; 104 if(buffer[0]=='a') 105 { 106 j=0; 107 flag4=1; 108 flag5=0; 109 IE2|=UCA0TXIE; //打开发送中断位 110 } 111 else if(buffer[0]=='b') 112 { 113 j=0; 114 flag4=0; 115 flag5=1; 116 IE2|=UCA0TXIE; //打开发送中断位 117 } 118 } 119 120 #pragma vector=USCIAB0TX_VECTOR //蓝牙发送中断 121 __interrupt void UCA0TX_isr() 122 { 123 if(flag4==1) 124 { 125 buffer[0]=int_char(num1); 126 buffer[1]=int_char(num2); 127 buffer[2]=int_char(num3); 128 buffer[3]=int_char(num4); 129 if(i<4) 130 { 131 UCA0TXBUF= buffer[i]; //从发送缓冲器发送一个字符 132 } 133 i++; 134 if(i==4) 135 { 136 i=0; 137 IE2&=~UCA0TXIE; //关闭发送中断位 138 } 139 } 140 else if(flag5==1) 141 { 142 if(weightdata[k-1]<400) 143 { 144 P2OUT|=BIT7; 145 if(i<50) 146 { 147 UCA0TXBUF=advice2[i]; //从发送缓冲器发送一个字符 148 } 149 i++; 150 if(i==50) 151 { 152 i=0; 153 IE2&=~UCA0TXIE; //关闭发送中断位 154 } 155 } 156 else if(weightdata[k-1]>400) 157 { 158 P2OUT&=~BIT7; 159 if(i<50) 160 { 161 UCA0TXBUF=advice1[i]; //从发送缓冲器发送一个字符 162 } 163 i++; 164 if(i==50) 165 { 166 i=0; 167 IE2&=~UCA0TXIE; //关闭发送中断位 168 } 169 } 170 } 171 } 172 173 #pragma vector=PORT1_VECTOR //P1向量中断 174 __interrupt void port_ISR1() 175 { 176 delay(); 177 if((P1IFG&BIT7)!=0) //进入记录模式 178 { 179 P2OUT|=BIT7; 180 weightdata[k]=n; 181 if(k<5) 182 k++; 183 else if(k==5) 184 k=0; 185 flag1=0; 186 flag2=1; 187 flag3=0; 188 p=0; 189 P1IFG&=~BIT7; 190 } 191 if((P1IFG&BIT3)!=0) //进入测量模式 192 { 193 P2OUT|=BIT7; 194 flag1=1; 195 flag2=0; 196 flag3=0; 197 p=0; 198 P1IFG&=~BIT3; 199 } 200 } 201 202 #pragma vector=PORT2_VECTOR //P2向量中断 203 __interrupt void port_ISR2() 204 { 205 delay(); 206 if((P2IFG&BIT4)!=0) //进入查询模式 207 { 208 flag1=0; 209 flag2=0; 210 flag3=1; 211 p=0; 212 if(l<5) 213 l++; 214 else if(l==5) 215 l=0; 216 P2IFG&=~BIT4; 217 } 218 if((P2IFG&BIT6)!=0) //进入清零模式 219 { 220 P2OUT|=BIT7; 221 flag1=0; 222 flag2=0; 223 flag3=0; 224 while(p<32) //所有数据清零 225 { 226 weightdata[p]=0; 227 p++; 228 } 229 k=0; //从头计数 230 P2IFG&=~BIT6; 231 } 232 } 233 234 //**************************************************** 235 //子函数 236 //**************************************************** 237 238 void HC595SendData(unsigned char SendVal) //HC5955数据移入函数 239 { 240 int m; 241 for(m=0;m<8;m++) 242 { 243 if((SendVal<<m)&0x80) P1OUT_bit.P4=1; 244 else P1OUT_bit.P4=0; 245 P1OUT_bit.P5=0; //从SHCP产生一上升沿(移入数据) 246 P1OUT_bit.P5=1; 247 } 248 } 249 void HC595ShowData() //HC5955数据发送函数 250 { 251 P1OUT_bit.P6=0; //STCP产生一上升沿(输出数据) 252 P1OUT_bit.P6=1; 253 } 254 255 void HX711_delay() //HX711采集延迟函数 256 { 257 int m; 258 for(m=0;m<2;m++); 259 } 260 261 unsigned long int HX711_Read(int a,int b,int c,int d) //HX711数据采集函数 262 { 263 unsigned long int count; 264 unsigned int k; 265 HX711_delay(); 266 P1OUT_bit.P0=0; 267 count=0; 268 while(P2IN_bit.P5); 269 for(k=0;k<24;k++) //前24个脉冲下降沿存下数据到count中 270 { 271 P1OUT_bit.P0=1; 272 count=count<<1; 273 P1OUT_bit.P0=0; 274 if(P2IN_bit.P5) 275 count++; 276 } 277 P1OUT_bit.P0=1; 278 count=count^0x800000; //第25个脉冲下降沿来时,转换数据 279 HX711_delay(); 280 P1OUT_bit.P0=0; 281 return(count); 282 } 283 284 void Segshow(int n,int a,int b,int c,int d) //数码管显示函数 285 { 286 unsigned char Segdata[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; 287 switch(n) 288 { 289 case 0: 290 HC595SendData(Segdata[d]); //注意数据和选通的先后顺序 291 HC595ShowData(); 292 P2OUT&=~BIT3; 293 P2OUT|=BIT0; 294 break; 295 case 1: 296 HC595SendData(Segdata[c]); 297 HC595ShowData(); 298 P2OUT&=~BIT0; 299 P2OUT|=BIT1; 300 break; 301 case 2: 302 HC595SendData(Segdata[b]); 303 HC595ShowData(); 304 P2OUT&=~BIT1; 305 P2OUT|=BIT2; 306 break; 307 case 3: 308 HC595SendData(Segdata[a]); 309 HC595ShowData(); 310 P2OUT&=~BIT2; 311 P2OUT|=BIT3; 312 break; 313 } 314 } 315 316 void USCIA0_init() //蓝牙设置初始化函数 317 { 318 UCA0CTL1 |= UCSWRST; //swrst=1 319 P1SEL |= BIT1+BIT2; 320 P1SEL2 |= BIT1+BIT2; //P1.1和P1.2引脚功能设置 321 UCA0CTL1 |= UCSSEL_2+UCRXEIE; //时钟源选 SMCLK 默认约 1MHz 322 UCA0BR1 = 0; //高八位 0 323 UCA0BR0 = 104; //低八位为 104 324 UCA0MCTL = UCBRS_1; //由上述计算出 0.167*8 近似为 1 325 UCA0CTL1 &=~UCSWRST ; //swrst=0 326 } 327 328 void HX711_init() //HX711设置初始化函数 329 { 330 P2SEL&=~BIT5; //对应HX711的DOUT 331 P2DIR|=BIT5; 332 P2DIR&=~BIT5; 333 P2REN|=BIT5; 334 335 P1DIR|=BIT0; //对应HX711的SCK 336 P1SEL&=~BIT0; 337 P1SEL2&=~BIT0; 338 P1OUT&=~BIT0; 339 } 340 341 void TAO_init() //定时器设置初始化函数 342 { 343 TA0CTL|=TACLR+TASSEL_2+MC_1; //设置TA0计时,选用DCO时钟源1MHz 344 TA0CCR0=10000; 345 TA0CCTL0|=CCIE; //进入定时器中断 346 } 347 348 void GPIO_init() //GPIO设置初始化函数 349 { 350 P1DIR|=BIT4+BIT5+BIT6; //数码管显示设置 351 P1SEL&=~(BIT4+BIT5+BIT6); 352 P1SEL2&=~(BIT4+BIT5+BIT6); 353 P1OUT&=~(BIT4+BIT5+BIT6); 354 P2DIR|=BIT0+BIT1+BIT2+BIT3; 355 P2SEL&=~(BIT0+BIT1+BIT2+BIT3); 356 P2SEL2&=~(BIT0+BIT1+BIT2+BIT3); 357 P2OUT&=~(BIT0+BIT1+BIT2+BIT3); 358 359 P2SEL&=~(BIT4+BIT6); //设置2.4、2.6允许中断 360 P2SEL2&=~(BIT4+BIT6); 361 P2OUT|=(BIT4+BIT6); 362 P2REN|=(BIT4+BIT6); 363 P2DIR&=~(BIT4+BIT6); 364 P2IES|=(BIT4+BIT6); 365 P2IFG&=~(BIT4+BIT6); 366 P2IE|=(BIT4+BIT6); 367 368 P1SEL&=~(BIT3+BIT7); //设置1.3、1.7允许中断 369 P1SEL2&=~(BIT3+BIT7); 370 P1OUT|=(BIT3+BIT7); 371 P1REN|=(BIT3+BIT7); 372 P1DIR&=~(BIT3+BIT7); 373 P1IES|=(BIT3+BIT7); 374 P1IFG&=~(BIT3+BIT7); 375 P1IE|=(BIT3+BIT7); 376 377 P2DIR|=BIT7; //蜂鸣器设置 378 P2SEL&=~BIT7; 379 P2SEL2&=~BIT7; 380 P2OUT|=BIT7; 381 } 382 383 char int_char(int n) //数据格式转换函数 384 { 385 char m; 386 switch(n) 387 { 388 case(0): m='0';break; 389 case(1): m='1';break; 390 case(2): m='2';break; 391 case(3): m='3';break; 392 case(4): m='4';break; 393 case(5): m='5';break; 394 case(6): m='6';break; 395 case(7): m='7';break; 396 case(8): m='8';break; 397 case(9): m='9';break; 398 } 399 return m; 400 } 401 402 void delay() //延时按键防抖函数 403 { unsigned int o; 404 for (o=0;o<0x00ff;o++); 405 }
http://wiki.ocrobot.com/doku.php?id=learning arduino中文手册页面