找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4166|回复: 0
打印 上一主题 下一主题
收起左侧

基于msp430单片机的体重计程序与实物设计

[复制链接]
跳转到指定楼层
楼主
智能体重秤主要由压力秤模块、MPU 模块和 App 模块构成,将智能体重秤放置在床边,每日清晨起床时站在秤上测量一下自己的体重,体重秤会通过数码管将体重显示出来,并与已知数据比较,系统会自动发出提示语音,然后通过内置在体重秤内的蓝牙模块将数据传送到手机App 客户端,将数据记录下来,坚持每日测量的话,系统会根据每日的测量数据绘制体重曲线,进而通过曲线分析人体健康状况,并给出合理建议。用户还可以随时查询之前的体重数据,通过对比来更好地把握自己的健康状况。
通过人体体重变化来监测人体健康情况已有相关文献研究,我们可以借鉴相关的一些研究成果来对人体健康状况进行分析。

模块划分:
①定时器模块:定时期间只记录一次数据,两次计数之间用定时器定时。
②HX711 数据采集模块:采集来自 HX711 的串行数据。
③串口模块:单片机与手机蓝牙串口助手交互功能。
④数码管模块:依据不同的工作模式显示不同的数据。

⑤按键功能模块:根据不同的按键,进入不同的工作模式。共包括:测量模式、记录模式、查询模式、清零模式。

制作出来的实物图如下:




单片机源程序如下:
  1. #include "io430.h"
  2. #include "in430.h"

  3. unsigned long int HX711_Read();                        //HX711数据采集函数声明
  4. void Segshow(int n,int a,int b,int c,int d);        //数码管显示函数声明
  5. void HC595SendData(unsigned char SendVal);        //HC5955数据移入函数声明
  6. void HC595ShowData();        //HC5955数据发送函数声明
  7. void HX711_delay();        //HX711采集延迟函数声明
  8. void USCIA0_init();        //蓝牙设置初始化函数声明
  9. void HX711_init();        //HX711设置初始化函数声明
  10. void TAO_init();        //定时器设置初始化函数声明
  11. void GPIO_init();        //GPIO设置初始化函数声明
  12. char int_char(int n);        //数据格式转换函数声明
  13. void delay();                //延时按键防抖函数声明
  14. char buffer[32];        //蓝牙收发数据缓冲区
  15. char advice1[50]="more exercise and less meat!”;//建议1字符串
  16. char advice2[50]="good body and keep on!”;        //建议2字符串
  17. int weightdata[32];             //记录体重数据的数据串
  18. unsigned int j=0;                //计数变量i、j、k、l、p
  19. unsigned int i=0;
  20. unsigned int k=0;
  21. unsigned int l=0;
  22. unsigned int p=0;
  23. int num1,num2,num3,num4,n;      //数码管参数
  24. int count1=0;                   //两次采集数据之间间隔计时
  25. int flag1=0;                    //测量模式
  26. int flag2=0;                    //记录模式
  27. int flag3=0;                    //查询模式
  28. int flag4=0;                        //建议1发送
  29. int flag5=0;                        //建议2发送

  30. int main( void )
  31. {
  32.   WDTCTL = WDTPW + WDTHOLD;     //关闭看门狗                           
  33.   unsigned int m=0;                //数码管选通计数变量

  34.   _EINT();                        //中断总控位打开
  35.   USCIA0_init();  
  36.   HX711_init();
  37.   GPIO_init();
  38.   TAO_init();
  39.   IE2|=UCA0RXIE;                //接收中断位打开

  40. //****************************************************
  41. //主循环:功能模式、数码管显示
  42. //****************************************************
  43.   while(1)
  44.   {   
  45.     if(flag1==1)//测量模式
  46.     {
  47.       num4=(n)%10;
  48.       num3=(n%100)/10;
  49.       num2=n/100;
  50.       num1=0;
  51.     }
  52.     else if(flag2==1) //记录模式
  53.     {
  54.       num4=(weightdata[k-1])%10;
  55.       num3=(weightdata[k-1]%100)/10;
  56.       num2=weightdata[k-1]/100;
  57.       num1=0;
  58.     }
  59.     else if(flag3==1) //查询模式
  60.     {
  61.       num4=(weightdata[l])%10;
  62.       num3=(weightdata[l]%100)/10;
  63.       num2=weightdata[l]/100;
  64.       num1=0;
  65.     }
  66.     else              //查询清零模式
  67.     {
  68.       num4=0;
  69.       num3=0;
  70.       num2=0;
  71.       num1=0;
  72.     }
  73.     Segshow(m,num1,num2,num3,num4);
  74.     m=m+1;
  75.     if(m==4) m=0;
  76.   }
  77. }

  78. //****************************************************
  79. //中断子函数
  80. //****************************************************

  81. #pragma vector=TIMER0_A0_VECTOR                 //定时器中断
  82. __interrupt void timer0_A0_ISR()
  83. {
  84.   if(count1<30)
  85.     count1=count1+1;
  86.   if(count1==30)                              
  87.   {      
  88.     n=(HX711_Read()-8529600)/1000;//采集数据
  89.     count1=0;
  90.   }
  91. }

  92. #pragma vector=USCIAB0RX_VECTOR                  //蓝牙接收中断
  93. __interrupt void UCA0RX_isr()
  94. {
  95.     buffer[j]=UCA0RXBUF;         //读接收缓冲器保存一个字符
  96.     j++;
  97.     if(buffer[0]=='a')
  98.     {
  99.       j=0;
  100.       flag4=1;
  101.       flag5=0;
  102.       IE2|=UCA0TXIE;             //打开发送中断位
  103.     }   
  104.     else if(buffer[0]=='b')
  105.     {  
  106.       j=0;
  107.       flag4=0;
  108.       flag5=1;
  109.       IE2|=UCA0TXIE;             //打开发送中断位
  110.     }
  111. }

  112. #pragma vector=USCIAB0TX_VECTOR                 //蓝牙发送中断
  113. __interrupt void UCA0TX_isr()
  114. {
  115.   if(flag4==1)
  116.   {
  117.     buffer[0]=int_char(num1);
  118.     buffer[1]=int_char(num2);
  119.     buffer[2]=int_char(num3);
  120.     buffer[3]=int_char(num4);
  121.     if(i<4)
  122.       {
  123.         UCA0TXBUF= buffer[i];        //从发送缓冲器发送一个字符
  124.       }
  125.       i++;
  126.     if(i==4)
  127.       {
  128.         i=0;
  129.         IE2&=~UCA0TXIE;                //关闭发送中断位
  130.       }
  131.   }
  132.   else if(flag5==1)
  133.   {
  134.     if(weightdata[k-1]<400)
  135.     {
  136.       P2OUT|=BIT7;
  137.       if(i<50)
  138.       {
  139.         UCA0TXBUF=advice2[i];        //从发送缓冲器发送一个字符
  140.       }
  141.       i++;
  142.       if(i==50)
  143.       {
  144.         i=0;
  145.         IE2&=~UCA0TXIE;                //关闭发送中断位
  146.       }
  147.     }
  148.     else if(weightdata[k-1]>400)
  149.     {
  150.       P2OUT&=~BIT7;
  151.       if(i<50)
  152.       {
  153.         UCA0TXBUF=advice1[i];        //从发送缓冲器发送一个字符
  154.       }
  155.       i++;
  156.       if(i==50)
  157.       {
  158.         i=0;
  159.         IE2&=~UCA0TXIE;                //关闭发送中断位
  160.       }
  161.     }
  162.   }
  163. }

  164. #pragma  vector=PORT1_VECTOR                          //P1向量中断       
  165. __interrupt  void port_ISR1()
  166. {
  167.   delay();
  168.   if((P1IFG&BIT7)!=0)                //进入记录模式
  169.    {
  170.      P2OUT|=BIT7;
  171.      weightdata[k]=n;
  172.      if(k<5)
  173.        k++;
  174.      else if(k==5)
  175.        k=0;
  176.      flag1=0;
  177.      flag2=1;
  178.      flag3=0;
  179.      p=0;
  180.      P1IFG&=~BIT7;
  181.    }
  182.   if((P1IFG&BIT3)!=0)                //进入测量模式
  183.    {
  184.      P2OUT|=BIT7;
  185.      flag1=1;
  186.      flag2=0;
  187.      flag3=0;
  188.      p=0;
  189.      P1IFG&=~BIT3;
  190.    }
  191. }

  192. #pragma  vector=PORT2_VECTOR                          //P2向量中断               
  193. __interrupt  void port_ISR2()
  194. {   
  195.   delay();
  196.   if((P2IFG&BIT4)!=0)                //进入查询模式
  197.    {
  198.      flag1=0;
  199.      flag2=0;
  200.      flag3=1;
  201.      p=0;
  202.      if(l<5)
  203.        l++;
  204.      else if(l==5)
  205.        l=0;
  206.      P2IFG&=~BIT4;
  207.    }
  208.   if((P2IFG&BIT6)!=0)                //进入清零模式
  209.   {
  210.     P2OUT|=BIT7;
  211.     flag1=0;
  212.     flag2=0;
  213.     flag3=0;
  214.     while(p<32)                       //所有数据清零
  215.     {
  216.       weightdata[p]=0;
  217.       p++;
  218.     }
  219.     k=0;                             //从头计数
  220.     P2IFG&=~BIT6;
  221.   }
  222. }

  223. //****************************************************
  224. //子函数
  225. //****************************************************

  226. void HC595SendData(unsigned char SendVal)                //HC5955数据移入函数       
  227. {  
  228.   int m;                     
  229.   for(m=0;m<8;m++)
  230.   {
  231.   if((SendVal<<m)&0x80) P1OUT_bit.P4=1;
  232.   else P1OUT_bit.P4=0;
  233.   P1OUT_bit.P5=0;                       //从SHCP产生一上升沿(移入数据)
  234.   P1OUT_bit.P5=1;
  235.    }
  236. }
  237. void HC595ShowData()                                     //HC5955数据发送函数
  238. {
  239.   P1OUT_bit.P6=0;                        //STCP产生一上升沿(输出数据)
  240.   P1OUT_bit.P6=1;
  241. }

  242. void HX711_delay()                                        //HX711采集延迟函数
  243. {
  244.   int m;
  245.   for(m=0;m<2;m++);       
  246. }

  247. unsigned long int HX711_Read(int a,int b,int c,int d)        //HX711数据采集函数
  248. {
  249.         unsigned long int count;
  250.         unsigned int k;  
  251.         HX711_delay();
  252.           P1OUT_bit.P0=0;
  253.           count=0;
  254.           while(P2IN_bit.P5);
  255.           for(k=0;k<24;k++)                //前24个脉冲下降沿存下数据到count中
  256.         {
  257.                   P1OUT_bit.P0=1;
  258.                   count=count<<1;
  259.                 P1OUT_bit.P0=0;
  260.                   if(P2IN_bit.P5)
  261.                         count++;
  262.         }
  263.         P1OUT_bit.P0=1;
  264.         count=count^0x800000;                //第25个脉冲下降沿来时,转换数据
  265.         HX711_delay();
  266.         P1OUT_bit.P0=0;  
  267.         return(count);
  268. }

  269. void Segshow(int n,int a,int b,int c,int d)                //数码管显示函数
  270. {
  271.   unsigned char Segdata[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  272.   switch(n)                                   
  273.     {
  274.     case 0:
  275.       HC595SendData(Segdata[d]);        //注意数据和选通的先后顺序
  276.       HC595ShowData();
  277.       P2OUT&=~BIT3;
  278.       P2OUT|=BIT0;
  279.       break;
  280.     case 1:
  281.       HC595SendData(Segdata[c]);
  282.       HC595ShowData();
  283.       P2OUT&=~BIT0;
  284.       P2OUT|=BIT1;
  285.       break;
  286.     case 2:
  287.       HC595SendData(Segdata[b]);
  288.       HC595ShowData();
  289.       P2OUT&=~BIT1;
  290.       P2OUT|=BIT2;
  291.       break;
  292.     case 3:
  293.       HC595SendData(Segdata[a]);
  294.       HC595ShowData();
  295.       P2OUT&=~BIT2;
  296.       P2OUT|=BIT3;
  297.       break;
  298.     }
  299. }

  300. void USCIA0_init()                                        //蓝牙设置初始化函数
  301. {
  302.   UCA0CTL1 |= UCSWRST;                         //swrst=1
  303.   P1SEL |= BIT1+BIT2;
  304.   P1SEL2 |= BIT1+BIT2;                         //P1.1和P1.2引脚功能设置
  305.   UCA0CTL1 |= UCSSEL_2+UCRXEIE;                //时钟源选 SMCLK 默认约 1MHz
  306.   UCA0BR1 = 0;                                //高八位 0
  307.   UCA0BR0 = 104;                        //低八位为 104
  308.   UCA0MCTL = UCBRS_1;                        //由上述计算出 0.167*8 近似为 1
  309.   UCA0CTL1 &=~UCSWRST ;                        //swrst=0
  310. }

  311. void HX711_init()                                        //HX711设置初始化函数
  312. {
  313.   P2SEL&=~BIT5;                                //对应HX711的DOUT
  314.   P2DIR|=BIT5;
  315.   P2DIR&=~BIT5;
  316.   P2REN|=BIT5;  
  317.   
  318.   P1DIR|=BIT0;                                 //对应HX711的SCK
  319.   P1SEL&=~BIT0;
  320.   P1SEL2&=~BIT0;
  321.   P1OUT&=~BIT0;
  322. }

  323. void TAO_init()                                                //定时器设置初始化函数
  324. {
  325.   TA0CTL|=TACLR+TASSEL_2+MC_1;          //设置TA0计时,选用DCO时钟源1MHz
  326.   TA0CCR0=10000;
  327.   TA0CCTL0|=CCIE;                        //进入定时器中断
  328. }

  329. void GPIO_init()                                        //GPIO设置初始化函数
  330. {
  331.   P1DIR|=BIT4+BIT5+BIT6;                 //数码管显示设置
  332.   P1SEL&=~(BIT4+BIT5+BIT6);
  333.   P1SEL2&=~(BIT4+BIT5+BIT6);
  334.   P1OUT&=~(BIT4+BIT5+BIT6);
  335.   P2DIR|=BIT0+BIT1+BIT2+BIT3;         
  336.   P2SEL&=~(BIT0+BIT1+BIT2+BIT3);
  337.   P2SEL2&=~(BIT0+BIT1+BIT2+BIT3);
  338.   P2OUT&=~(BIT0+BIT1+BIT2+BIT3);
  339.   
  340.   P2SEL&=~(BIT4+BIT6);                  //设置2.4、2.6允许中断
  341.   P2SEL2&=~(BIT4+BIT6);
  342.   P2OUT|=(BIT4+BIT6);
  343.   P2REN|=(BIT4+BIT6);
  344.   P2DIR&=~(BIT4+BIT6);
  345.   P2IES|=(BIT4+BIT6);
  346.   P2IFG&=~(BIT4+BIT6);
  347.   P2IE|=(BIT4+BIT6);
  348.   
  349.   P1SEL&=~(BIT3+BIT7);                  //设置1.3、1.7允许中断
  350.   P1SEL2&=~(BIT3+BIT7);
  351.   P1OUT|=(BIT3+BIT7);
  352.   P1REN|=(BIT3+BIT7);
  353.   P1DIR&=~(BIT3+BIT7);
  354.   P1IES|=(BIT3+BIT7);
  355.   P1IFG&=~(BIT3+BIT7);
  356.   P1IE|=(BIT3+BIT7);
  357.   
  358.   P2DIR|=BIT7;                          //蜂鸣器设置
  359.   P2SEL&=~BIT7;                  
  360.   P2SEL2&=~BIT7;              
  361.   P2OUT|=BIT7;
  362. }

  363. char int_char(int n)                                        //数据格式转换函数
  364. {
  365.   char m;
  366.   switch(n)
  367.   {
  368.     case(0): m='0';break;
  369.     case(1): m='1';break;
  370.     case(2): m='2';break;   
  371.     case(3): m='3';break;
  372.     case(4): m='4';break;
  373.     case(5): m='5';break;
  374.     case(6): m='6';break;
  375.     case(7): m='7';break;
  376.     case(8): m='8';break;
  377.     case(9): m='9';break;
  378.   }
  379.   return m;
  380. }

  381. void delay()                                                //延时按键防抖函数
  382. {   unsigned int o;
  383.     for (o=0;o<0x00ff;o++);                    
  384. }   
复制代码

所有资料51hei提供下载:
智能体重秤源程序.zip (2.91 KB, 下载次数: 20)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表