一段程序,有点看不懂,麻烦大神帮忙解释一下。。
时间:10-02
整理:3721RD
点击:
做的是心跳脉搏测量,用的是pulsesensor 脉搏 心率传感器
程序是都是一样的,是从Arduino改过来的51程序,
现在问题是,测不出数据来,显示屏算不出心率。
麻烦大神帮忙看看谢谢了。
#include <STC12C5A60S2.h>
#include "stdio.h"
#include <LCD1602.h>
#define false 0
#define true 1
#define FOSC 11059200L //系统时钟
#define BAUD 115200 //波特率
#define T0MS (65536-FOSC/12/500) //500HZ in 12T MODE
#define ADC_POWER 0x80
#define ADC_FLAG 0x10
#define ADC_START 0x08;
#define ADC_SPEEDLL 0x00
#define ADC_SPEEDL 0x20
#define ADC_SPEEDH 0x40
#define ADC_SPEEDHH 0x60
#define ADC_MASK 0x01
void UART_init(void);
void ADC_init(unsigned char channel);
void T0_init(void);
void sendDataToProcessing(char symbol, int dat);
void UART_send(char dat);
unsigned char PulsePin = 0;
//sbit blinkPin = P1^7;
//sbit fadePin = P2^3;
//sbit led1 = P2^1;
//sbit led2 = P2^2;
int fadeRate = 0;
// these variables are volatile because they are used during the interrupt service routine!
volatile unsigned int BPM; // used to hold the pulse rate
volatile unsigned int Signal; // holds the incoming raw data
volatile unsigned int IBI = 600; // holds the time between beats, must be seeded!
volatile bit Pulse = false; // true when pulse wave is high, false when it's low
volatile bit QS = false; // becomes true when Arduoino finds a beat.
volatile int rate[10]; // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0; // used to determine pulse timing
volatile unsigned long lastBeatTime = 0; // used to find IBI
volatile int Peak =512; // used to find peak in pulse wave, seeded
volatile int Trough = 512; // used to find trough in pulse wave, seeded
volatile int thresh = 512; // used to find instant moment of heart beat, seeded
volatile int amp = 100; // used to hold amplitude of pulse waveform, seeded
volatile bit firstBeat = true; // used to seed rate array so we startup with reasonable BPM
volatile bit secondBeat = false; // used to seed rate array so we startup with reasonable BPM
static unsigned char order=0;
unsigned char code ucForum0[]="Pulsesensor test";
unsigned char code ucForum1[]=" BPM: ";
unsigned char DisBuff[4]={0};
void sys_init()
{
UART_init(); // we agree to talk fast!
ADC_init(PulsePin);
T0_init(); // sets up to read Pulse Sensor signal every 2mS
LCD1602_Init(); //液晶初始化
}
void main(void)
{
sys_init();
LCD1602_DisplayString(ucForum0); //显示的内容
LCD1602_MoveToPosition(1,0); //显示位置移动到指定位置
LCD1602_DisplayString(ucForum1); //显示的内容
while(1)
{
sendDataToProcessing('S', Signal); // send Processing the raw Pulse Sensor data
if (QS == true){ // Quantified Self flag is true when arduino finds a heartbeat
fadeRate = 255; // Set 'fadeRate' Variable to 255 to fade LED with pulse
sendDataToProcessing('B',BPM); // send heart rate with a 'B' prefix
sendDataToProcessing('Q',IBI); // send time between beats with a 'Q' prefix
QS = false; // reset the Quantified Self flag for next time
LCD1602_MoveToPosition(1,9);
LCD1602_DisplayString(DisBuff);
}
//ledFadeToBeat();
delay(138); // take a break 19.6ms
}
}
//void ledFadeToBeat(){
// fadeRate -= 15; // set LED fade value
// fadeRate = constrain(fadeRate,0,255); // keep LED fade value from going into negative numbers!
// analogWrite(fadePin,fadeRate); // fade LED
// }
void sendDataToProcessing(char symbol, int dat ){
putchar(symbol); // symbol prefix tells Processing what type of data is coming
printf("%d\r\n",dat); // the data to send culminating in a carriage return
}
void UART_init(void)
{
PCON &= 0x7f; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
BRT = 0xFD; //独立波特率产生器初值
AUXR |= 0x04; //时钟设置为1T模式
AUXR |= 0x01; //选择独立波特率产生器
AUXR |= 0x10; //启动波特率产生
}
char putchar(unsigned char dat)
{
TI=0;
SBUF=dat;
while(!TI);
TI=0;
return SBUF;
}
void T0_init(void){
// Initializes Timer0 to throw an interrupt every 2mS.
TMOD |= 0x01; //16bit TIMER
TL0=T0MS;
TH0=T0MS>>8;
TR0=1; //start Timer 0
ET0=1; //enable Timer Interrupt
EA=1; // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}
void ADC_init(unsigned char channel)
{
P1ASF=ADC_MASK<<channel; //enable PlusePin as ADC INPUT
ADC_RES=0; //clear former ADC result
ADC_RESL=0; //clear former ADC result
AUXR1 |= 0x04; //adjust the format of ADC result
ADC_CONTR=channel|ADC_POWER|ADC_SPEEDLL|ADC_START; //power on ADC and start conversion
}
unsigned int analogRead(unsigned char channel)
{
unsigned int result;
ADC_CONTR &=!ADC_FLAG; //clear ADC FLAG
result=ADC_RES;
result=result<<8;
result+=ADC_RESL;
ADC_CONTR|=channel|ADC_POWER|ADC_SPEEDLL|ADC_START;
return result;
}
// Timer 0中断子程序,每2MS中断一次,读取AD值,计算心率值
void Timer0_rountine(void) interrupt 1
{
int N;
unsigned char i;
// keep a running total of the last 10 IBI values
unsigned int runningTotal = 0; // clear the runningTotal variable
EA=0; // disable interrupts while we do this
TL0=T0MS;
TH0=T0MS>>8; //reload 16 bit TIMER0
Signal = analogRead(PulsePin); // read the Pulse Sensor
sampleCounter += 2; // keep track of the time in mS with this variable
N = sampleCounter - lastBeatTime; // monitor the time since the last beat to avoid noise
// find the peak and trough of the pulse wave
if(Signal < thresh && N > (IBI/5)*3){ // avoid dichrotic noise by waiting 3/5 of last IBI
if (Signal < Trough){ // T is the trough
Trough = Signal; // keep track of lowest point in pulse wave
}
}
if(Signal > thresh && Signal > Peak){ // thresh condition helps avoid noise
Peak = Signal; // P is the peak
} // keep track of highest point in pulse wave
// NOW IT'S TIME TO LOOK FOR THE HEART BEAT
// signal surges up in value every time there is a pulse
if (N > 250){ // avoid high frequency noise
if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ){
Pulse = true; // set the Pulse flag when we think there is a pulse
// blinkPin=0; // turn on pin 13 LED
IBI = sampleCounter - lastBeatTime; // measure time between beats in mS
lastBeatTime = sampleCounter; // keep track of time for next pulse
if(secondBeat){ // if this is the second beat, if secondBeat == TRUE
secondBeat = false; // clear secondBeat flag
for(i=0; i<=9; i++){ // seed the running total to get a realisitic BPM at startup
rate = IBI;
}
}
if(firstBeat){ // if it's the first time we found a beat, if firstBeat == TRUE
firstBeat = false; // clear firstBeat flag
secondBeat = true; // set the second beat flag
EA=1; // enable interrupts again
return; // IBI value is unreliable so discard it
}
for(i=0; i<=8; i++){ // shift data in the rate array
rate = rate[i+1]; // and drop the oldest IBI value
runningTotal += rate; // add up the 9 oldest IBI values
}
rate[9] = IBI; // add the latest IBI to the rate array
runningTotal += rate[9]; // add the latest IBI to runningTotal
runningTotal /= 10; // average the last 10 IBI values
BPM = 60000/runningTotal; // how many beats can fit into a minute? that's BPM!
if(BPM>200)BPM=200; //限制BPM最高显示值
if(BPM<30)BPM=30; //限制BPM最低显示值
DisBuff[2] = BPM%10+48;//取个位数
DisBuff[1] = BPM%100/10+48; //取十位数
DisBuff[0] = BPM/100+48; //百位数
if(DisBuff[0]==48)
DisBuff[0]=32;
QS = true; // set Quantified Self flag
// QS FLAG IS NOT CLEARED INSIDE THIS ISR
}
}
if (Signal < thresh && Pulse == true){ // when the values are going down, the beat is over
// blinkPin=1; // turn off pin 13 LED
Pulse = false; // reset the Pulse flag so we can do it again
amp = Peak - Trough; // get amplitude of the pulse wave
thresh = amp/2 + Trough; // set thresh at 50% of the amplitude
Peak = thresh; // reset these for next time
Trough = thresh;
}
if (N > 2500){
thresh = 512;
Peak = 512;
Trough = 512;
lastBeatTime = sampleCounter;
firstBeat = true;
secondBeat = false;
}
EA=1;
}// end isr
程序是都是一样的,是从Arduino改过来的51程序,
现在问题是,测不出数据来,显示屏算不出心率。
麻烦大神帮忙看看谢谢了。
#include <STC12C5A60S2.h>
#include "stdio.h"
#include <LCD1602.h>
#define false 0
#define true 1
#define FOSC 11059200L //系统时钟
#define BAUD 115200 //波特率
#define T0MS (65536-FOSC/12/500) //500HZ in 12T MODE
#define ADC_POWER 0x80
#define ADC_FLAG 0x10
#define ADC_START 0x08;
#define ADC_SPEEDLL 0x00
#define ADC_SPEEDL 0x20
#define ADC_SPEEDH 0x40
#define ADC_SPEEDHH 0x60
#define ADC_MASK 0x01
void UART_init(void);
void ADC_init(unsigned char channel);
void T0_init(void);
void sendDataToProcessing(char symbol, int dat);
void UART_send(char dat);
unsigned char PulsePin = 0;
//sbit blinkPin = P1^7;
//sbit fadePin = P2^3;
//sbit led1 = P2^1;
//sbit led2 = P2^2;
int fadeRate = 0;
// these variables are volatile because they are used during the interrupt service routine!
volatile unsigned int BPM; // used to hold the pulse rate
volatile unsigned int Signal; // holds the incoming raw data
volatile unsigned int IBI = 600; // holds the time between beats, must be seeded!
volatile bit Pulse = false; // true when pulse wave is high, false when it's low
volatile bit QS = false; // becomes true when Arduoino finds a beat.
volatile int rate[10]; // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0; // used to determine pulse timing
volatile unsigned long lastBeatTime = 0; // used to find IBI
volatile int Peak =512; // used to find peak in pulse wave, seeded
volatile int Trough = 512; // used to find trough in pulse wave, seeded
volatile int thresh = 512; // used to find instant moment of heart beat, seeded
volatile int amp = 100; // used to hold amplitude of pulse waveform, seeded
volatile bit firstBeat = true; // used to seed rate array so we startup with reasonable BPM
volatile bit secondBeat = false; // used to seed rate array so we startup with reasonable BPM
static unsigned char order=0;
unsigned char code ucForum0[]="Pulsesensor test";
unsigned char code ucForum1[]=" BPM: ";
unsigned char DisBuff[4]={0};
void sys_init()
{
UART_init(); // we agree to talk fast!
ADC_init(PulsePin);
T0_init(); // sets up to read Pulse Sensor signal every 2mS
LCD1602_Init(); //液晶初始化
}
void main(void)
{
sys_init();
LCD1602_DisplayString(ucForum0); //显示的内容
LCD1602_MoveToPosition(1,0); //显示位置移动到指定位置
LCD1602_DisplayString(ucForum1); //显示的内容
while(1)
{
sendDataToProcessing('S', Signal); // send Processing the raw Pulse Sensor data
if (QS == true){ // Quantified Self flag is true when arduino finds a heartbeat
fadeRate = 255; // Set 'fadeRate' Variable to 255 to fade LED with pulse
sendDataToProcessing('B',BPM); // send heart rate with a 'B' prefix
sendDataToProcessing('Q',IBI); // send time between beats with a 'Q' prefix
QS = false; // reset the Quantified Self flag for next time
LCD1602_MoveToPosition(1,9);
LCD1602_DisplayString(DisBuff);
}
//ledFadeToBeat();
delay(138); // take a break 19.6ms
}
}
//void ledFadeToBeat(){
// fadeRate -= 15; // set LED fade value
// fadeRate = constrain(fadeRate,0,255); // keep LED fade value from going into negative numbers!
// analogWrite(fadePin,fadeRate); // fade LED
// }
void sendDataToProcessing(char symbol, int dat ){
putchar(symbol); // symbol prefix tells Processing what type of data is coming
printf("%d\r\n",dat); // the data to send culminating in a carriage return
}
void UART_init(void)
{
PCON &= 0x7f; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
BRT = 0xFD; //独立波特率产生器初值
AUXR |= 0x04; //时钟设置为1T模式
AUXR |= 0x01; //选择独立波特率产生器
AUXR |= 0x10; //启动波特率产生
}
char putchar(unsigned char dat)
{
TI=0;
SBUF=dat;
while(!TI);
TI=0;
return SBUF;
}
void T0_init(void){
// Initializes Timer0 to throw an interrupt every 2mS.
TMOD |= 0x01; //16bit TIMER
TL0=T0MS;
TH0=T0MS>>8;
TR0=1; //start Timer 0
ET0=1; //enable Timer Interrupt
EA=1; // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}
void ADC_init(unsigned char channel)
{
P1ASF=ADC_MASK<<channel; //enable PlusePin as ADC INPUT
ADC_RES=0; //clear former ADC result
ADC_RESL=0; //clear former ADC result
AUXR1 |= 0x04; //adjust the format of ADC result
ADC_CONTR=channel|ADC_POWER|ADC_SPEEDLL|ADC_START; //power on ADC and start conversion
}
unsigned int analogRead(unsigned char channel)
{
unsigned int result;
ADC_CONTR &=!ADC_FLAG; //clear ADC FLAG
result=ADC_RES;
result=result<<8;
result+=ADC_RESL;
ADC_CONTR|=channel|ADC_POWER|ADC_SPEEDLL|ADC_START;
return result;
}
// Timer 0中断子程序,每2MS中断一次,读取AD值,计算心率值
void Timer0_rountine(void) interrupt 1
{
int N;
unsigned char i;
// keep a running total of the last 10 IBI values
unsigned int runningTotal = 0; // clear the runningTotal variable
EA=0; // disable interrupts while we do this
TL0=T0MS;
TH0=T0MS>>8; //reload 16 bit TIMER0
Signal = analogRead(PulsePin); // read the Pulse Sensor
sampleCounter += 2; // keep track of the time in mS with this variable
N = sampleCounter - lastBeatTime; // monitor the time since the last beat to avoid noise
// find the peak and trough of the pulse wave
if(Signal < thresh && N > (IBI/5)*3){ // avoid dichrotic noise by waiting 3/5 of last IBI
if (Signal < Trough){ // T is the trough
Trough = Signal; // keep track of lowest point in pulse wave
}
}
if(Signal > thresh && Signal > Peak){ // thresh condition helps avoid noise
Peak = Signal; // P is the peak
} // keep track of highest point in pulse wave
// NOW IT'S TIME TO LOOK FOR THE HEART BEAT
// signal surges up in value every time there is a pulse
if (N > 250){ // avoid high frequency noise
if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ){
Pulse = true; // set the Pulse flag when we think there is a pulse
// blinkPin=0; // turn on pin 13 LED
IBI = sampleCounter - lastBeatTime; // measure time between beats in mS
lastBeatTime = sampleCounter; // keep track of time for next pulse
if(secondBeat){ // if this is the second beat, if secondBeat == TRUE
secondBeat = false; // clear secondBeat flag
for(i=0; i<=9; i++){ // seed the running total to get a realisitic BPM at startup
rate = IBI;
}
}
if(firstBeat){ // if it's the first time we found a beat, if firstBeat == TRUE
firstBeat = false; // clear firstBeat flag
secondBeat = true; // set the second beat flag
EA=1; // enable interrupts again
return; // IBI value is unreliable so discard it
}
for(i=0; i<=8; i++){ // shift data in the rate array
rate = rate[i+1]; // and drop the oldest IBI value
runningTotal += rate; // add up the 9 oldest IBI values
}
rate[9] = IBI; // add the latest IBI to the rate array
runningTotal += rate[9]; // add the latest IBI to runningTotal
runningTotal /= 10; // average the last 10 IBI values
BPM = 60000/runningTotal; // how many beats can fit into a minute? that's BPM!
if(BPM>200)BPM=200; //限制BPM最高显示值
if(BPM<30)BPM=30; //限制BPM最低显示值
DisBuff[2] = BPM%10+48;//取个位数
DisBuff[1] = BPM%100/10+48; //取十位数
DisBuff[0] = BPM/100+48; //百位数
if(DisBuff[0]==48)
DisBuff[0]=32;
QS = true; // set Quantified Self flag
// QS FLAG IS NOT CLEARED INSIDE THIS ISR
}
}
if (Signal < thresh && Pulse == true){ // when the values are going down, the beat is over
// blinkPin=1; // turn off pin 13 LED
Pulse = false; // reset the Pulse flag so we can do it again
amp = Peak - Trough; // get amplitude of the pulse wave
thresh = amp/2 + Trough; // set thresh at 50% of the amplitude
Peak = thresh; // reset these for next time
Trough = thresh;
}
if (N > 2500){
thresh = 512;
Peak = 512;
Trough = 512;
lastBeatTime = sampleCounter;
firstBeat = true;
secondBeat = false;
}
EA=1;
}// end isr
已退回4积分