单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:8045|回复:4

pulsesensor心率计的51单片机源程序

 [复制链接]
ID:455993发表于 2018-12-26 23:25|显示全部楼层
芯片stc12c5a
采用清翔电子出品的QX-mini51开发板来配合pulsesensor心率传感器完成脉搏采集和心率计算。
文件中一共有三个程序,分别为:
1.pulsesensor_STC12C5A:仅使用电脑显示心率值
2.pulsesensor_STC12C5A_LCD1602:使用LCD1602和电脑显示心率值
3.pulsesensor_STC12C5A _LCD12864:使用LCD12864和电脑显示心率值
注意:使用前务必将短路块J1,J5,J6拿掉,不然会严重影响信号从而导致心率值不准!
可以保留短路块J2,此时LED1会跟随心跳闪烁。
0.png

单片机源程序如下:
  1. //******************************参数说明*********************************//
  2. //MCU:STC12C5A60S2
  3. //ADC PIN:P1.0
  4. //SYSTEM CLOCK:11.0592MHz
  5. //Baudrate:115200
  6. //UART:P3.0 P3.1
  7. //**********************************************************************//
  8. //******************************使用说明*********************************//
  9. //注意:使用前务必将短路块J1,J5,J6拿掉,不然会严重影响信号!
  10. //可以保留短路块J2,此时LED1会跟随心跳闪烁
  11. //**********************************************************************//
  12. #include< STC12C5A60S2.h>
  13. #include "stdio.h"
  14. #include< LCD12864.h>

  15. #define false 0
  16. #define true 1
  17. #define FOSC 11059200L         //系统时钟
  18. #define BAUD 115200                 //波特率
  19. #define T0MS (65536-FOSC/12/500)         //500HZ in 12T MODE

  20. #define ADC_POWER 0x80             //ADC POWER CONTROL BIT
  21. #define ADC_FLAG 0x10             //ADC COMPLETE FLAG
  22. #define ADC_START 0x08;             //ADC START CONTROL BIT
  23. #define ADC_SPEEDLL 0x00         //540 CLOCKS
  24. #define ADC_SPEEDL 0x20             //360 CLOCKS
  25. #define ADC_SPEEDH 0x40             //180 CLOCKS
  26. #define ADC_SPEEDHH 0x60         //90 CLOCKS
  27. #define ADC_MASK 0x01

  28. void UART_init(void);
  29. void ADC_init(unsigned char channel);
  30. void T0_init(void);
  31. void sendDataToProcessing(char symbol, int dat);
  32. void UART_send(char dat);


  33. unsigned char PulsePin = 0;     // Pulse Sensor purple wire connected to analog pin 0(P1.0为AD口)
  34. //sbit blinkPin = P2^0;           // pin to blink led at each beat
  35. //sbit fadePin = P2^3;             // pin to do fancy classy fading blink at each beat
  36. //sbit led1 = P2^1;
  37. //sbit led2 = P2^2;
  38. int fadeRate = 0;             // used to fade LED on with PWM on fadePin


  39. // these variables are volatile because they are used during the interrupt service routine!
  40. volatile unsigned int BPM;             // used to hold the pulse rate
  41. volatile unsigned int Signal;           // holds the incoming raw data
  42. volatile unsigned int IBI = 600;         // holds the time between beats, must be seeded!
  43. volatile bit Pulse = false;     // true when pulse wave is high, false when it's low
  44. volatile bit QS = false;       // becomes true when Arduoino finds a beat.
  45. volatile int rate[10];               // array to hold last ten IBI values
  46. volatile unsigned long sampleCounter = 0;       // used to determine pulse timing
  47. volatile unsigned long lastBeatTime = 0;         // used to find IBI
  48. volatile int Peak =512;               // used to find peak in pulse wave, seeded
  49. volatile int Trough = 512;               // used to find trough in pulse wave, seeded
  50. volatile int thresh = 512;           // used to find instant moment of heart beat, seeded
  51. volatile int amp = 100;             // used to hold amplitude of pulse waveform, seeded
  52. volatile bit firstBeat = true;       // used to seed rate array so we startup with reasonable BPM
  53. volatile bit secondBeat = false;     // used to seed rate array so we startup with reasonable BPM
  54. static unsigned char order=0;
  55. unsigned char code ucStr1[]  =  "Pulsesensor test";         //显示信息1
  56. unsigned char code ucStr2[]  =  "           ";         //显示信息2
  57. unsigned char code ucStr3[]  =  "  BPM:       ";         //显示信息3
  58. unsigned char code ucStr4[]  =  "作者:anning86525";         //显示信息4
  59. unsigned char DisBuff[4]={0};

  60. void sys_init()
  61. {
  62.      LCD12864_Init();   //初始化液晶
  63.   UART_init();         // we agree to talk fast!
  64.      ADC_init(PulsePin);
  65.   T0_init();             // sets up to read Pulse Sensor signal every 2mS  
  66. }

  67. void main(void)
  68. {
  69.   sys_init();
  70.      LCD12864_DisplayOneLine(0x80,ucStr1);     //显示信息1
  71.      LCD12864_DisplayOneLine(0x90,ucStr2);     //显示信息2
  72.      LCD12864_DisplayOneLine(0x88,ucStr3);     //显示信息3
  73.      LCD12864_DisplayOneLine(0x98,ucStr4);     //显示信息4
  74.      while(1)
  75.      {
  76.          sendDataToProcessing('S', Signal);     // send Processing the raw Pulse Sensor data
  77.          if (QS == true){                 // Quantified Self flag is true when arduino finds a heartbeat
  78.                      fadeRate = 255;             // Set 'fadeRate' Variable to 255 to fade LED with pulse
  79.                      sendDataToProcessing('B',BPM);   // send heart rate with a 'B' prefix
  80.                      sendDataToProcessing('Q',IBI);   // send time between beats with a 'Q' prefix
  81.                      QS = false;               // reset the Quantified Self flag for next time
  82.                      LCD_disp_list_char(3,4,DisBuff);//在LCD12864上显示BPM
  83.                }
  84.   
  85.   //ledFadeToBeat();

  86.   delay(138);                     //  take a break 19.6ms

  87. }
  88. }


  89. //void ledFadeToBeat(){
  90. //   fadeRate -= 15;                 //  set LED fade value
  91. //   fadeRate = constrain(fadeRate,0,255);   //  keep LED fade value from going into negative numbers!
  92. //   analogWrite(fadePin,fadeRate);       //  fade LED
  93. //  }


  94. void sendDataToProcessing(char symbol, int dat ){
  95.    putchar(symbol);           // symbol prefix tells Processing what type of data is coming
  96.          printf("%d\r\n",dat);                         // the data to send culminating in a carriage return
  97.   }

  98. void UART_init(void)
  99. {
  100.        PCON& = 0x7f;  //波特率不倍速
  101.    SCON = 0x50;  //8位数据,可变波特率
  102.    BRT = 0xFD;   //独立波特率产生器初值
  103.    AUXR |= 0x04;  //时钟设置为1T模式
  104.    AUXR |= 0x01;  //选择独立波特率产生器
  105.    AUXR |= 0x10;  //启动波特率产生
  106. }
  107. char putchar(unsigned char dat)
  108. {
  109.      TI=0;
  110.      SBUF=dat;
  111.      while(!TI);
  112.      TI=0;
  113.     
  114.      return SBUF;
  115. }




  116. void T0_init(void){    
  117.   // Initializes Timer0 to throw an interrupt every 2mS.
  118.      TMOD |= 0x01;     //16bit TIMER
  119.      TL0=T0MS;
  120.      TH0=T0MS>>8;
  121.      TR0=1;         //start Timer 0
  122.      ET0=1;         //enable Timer Interrupt
  123.   EA=1;         // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED    
  124. }

  125. void ADC_init(unsigned char channel)
  126. {
  127.      P1ASF=ADC_MASK<<channel;     //enable PlusePin as ADC INPUT
  128.      ADC_RES=0;     //clear former ADC result
  129.      ADC_RESL=0;     //clear former ADC result
  130.      AUXR1 |= 0x04;     //adjust the format of ADC result
  131.      ADC_CONTR=channel|ADC_POWER|ADC_SPEEDLL|ADC_START;     //power on ADC and start conversion
  132. }

  133. unsigned int analogRead(unsigned char channel)
  134. {
  135.      unsigned int result;

  136.      ADC_CONTR& =!ADC_FLAG;     //clear ADC FLAG
  137.      result=ADC_RES;
  138.      result=result<<8;
  139.      result+=ADC_RESL;
  140.      ADC_CONTR|=channel|ADC_POWER|ADC_SPEEDLL|ADC_START;
  141.      return result;
  142. }
  143. // Timer 0中断子程序,每2MS中断一次,读取AD值,计算心率值
  144. void Timer0_rountine(void) interrupt 1
  145. {                
  146.   int N;
  147.      unsigned char i;
  148.      // keep a running total of the last 10 IBI values
  149.   unsigned int runningTotal = 0;             // clear the runningTotal variable  

  150.      EA=0;                           // disable interrupts while we do this
  151.      TL0=T0MS;
  152.      TH0=T0MS>>8;                 //reload 16 bit TIMER0
  153.   Signal = analogRead(PulsePin);           // read the Pulse Sensor
  154.   sampleCounter += 2;                 // keep track of the time in mS with this variable
  155.   N = sampleCounter - lastBeatTime;     // monitor the time since the last beat to avoid noise


  156.    //  find the peak and trough of the pulse wave
  157.   if(Signal< thresh&& N > (IBI/5)*3){     // avoid dichrotic noise by waiting 3/5 of last IBI
  158.    if (Signal< Trough){                 // T is the trough
  159.      Trough = Signal;                 // keep track of lowest point in pulse wave
  160.    }
  161.   }

  162.   if(Signal > thresh&& Signal > Peak){       // thresh condition helps avoid noise
  163.    Peak = Signal;                     // P is the peak
  164.   }                           // keep track of highest point in pulse wave

  165.   //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  166.   // signal surges up in value every time there is a pulse
  167.   if (N > 250){                         // avoid high frequency noise
  168.    if ( (Signal > thresh)&& (Pulse == false)&& (N > (IBI/5)*3) ){      
  169.      Pulse = true;                     // set the Pulse flag when we think there is a pulse
  170. //     blinkPin=0;           // turn on pin 13 LED
  171.      IBI = sampleCounter - lastBeatTime;       // measure time between beats in mS
  172.      lastBeatTime = sampleCounter;           // keep track of time for next pulse

  173.      if(secondBeat){                 // if this is the second beat, if secondBeat == TRUE
  174.        secondBeat = false;             // clear secondBeat flag
  175.        for(i=0; i<=9; i++){         // seed the running total to get a realisitic BPM at startup
  176.        rate[i] = IBI;              
  177.        }
  178.      }

  179.      if(firstBeat){                 // if it's the first time we found a beat, if firstBeat == TRUE
  180.        firstBeat = false;             // clear firstBeat flag
  181.        secondBeat = true;             // set the second beat flag
  182.        EA=1;                     // enable interrupts again
  183.        return;                     // IBI value is unreliable so discard it
  184.      }  



  185.      for(i=0; i<=8; i++){           // shift data in the rate array
  186.        rate[i] = rate[i+1];             // and drop the oldest IBI value
  187.        runningTotal += rate[i];           // add up the 9 oldest IBI values
  188.      }

  189.      rate[9] = IBI;                   // add the latest IBI to the rate array
  190.      runningTotal += rate[9];           // add the latest IBI to runningTotal
  191.      runningTotal /= 10;               // average the last 10 IBI values
  192.      BPM = 60000/runningTotal;           // how many beats can fit into a minute? that's BPM!
  193.              if(BPM>200)BPM=200;             //限制BPM最高显示值
  194.              if(BPM<30)BPM=30;                 //限制BPM最低显示值
  195.              DisBuff[2]   = BPM%10+48;//取个位数
  196. ……………………

  197. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
pulsesensor_STC12C5A.rar(803.8 KB, 下载次数: 202)


评分

黑币 +50
收起理由
+ 50
共享资料的黑币奖励!

查看全部评分

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

Powered by 单片机教程网