月月月熊~ 2024-04-19 15:32 采纳率: 75%
浏览 15

pulse sensor 在51单片机上无输出

购买pulse sensor脉搏心率传感器后,用的是开源程序,能检测到脉搏信号(指示灯在闪烁),但没有输出(串口助手没有显示,processing软件没有显示)
代码用的是51的12C,我的是89C,但是查询资料后说是完全兼容
请问大家问题出现在哪里了呀
是硬件连接还是软件编程上啊

//******************************²ÎÊý˵Ã÷*********************************//
//MCU:STC12C5A60S2
//ADC PIN:P1.0
//SYSTEM CLOCK:11.0592MHz
//Baudrate:115200
//UART:P3.0 P3.1
//**********************************************************************//
#include <STC12C5A60S2.h>
#include "stdio.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            //ADC POWER CONTROL BIT
#define ADC_FLAG 0x10            //ADC COMPLETE FLAG
#define ADC_START 0x08;            //ADC START CONTROL BIT
#define ADC_SPEEDLLca 0x00        //540 CLOCKS
#define ADC_SPEEDL 0x20            //360 CLOCKS
#define ADC_SPEEDH 0x40            //180 CLOCKS
#define ADC_SPEEDHH 0x60        //90 CLOCKS
#define ADC_MASK 0x01

//ÊýÂë¹Ü¶ÎÂëÏÔʾ£º0~f,²»ÁÁ
unsigned char code LED_Disp[] = {0xC0,0xF9,0xA4,0xB0,
                        0x99,0x92,0x82,0xF8,
                        0x80,0x90,0x88,0x83,
                        0xC6,0xA1,0x86,0x8E};

sfr LedPort = 0x80;     //¶ÎÑ¡¶ÎP0
sfr LedCtrl = 0xa0;     //λѡ¶ÎP2
unsigned char DisBuff[3];

void UART_init(void); 
void LED_Disp_Seg7(void);
void ADC_init(unsigned char channel);
void T0_init(void);
void sendDataToProcessing(char symbol, int dat);
void delay(unsigned int n);
void UART_send(char dat);
//void UART_Routine(void) interrupt4;

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


// 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;

void sys_init()
{
  //pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!
  //pinMode(fadePin,OUTPUT);          // pin that will fade to your heartbeat!
  UART_init();             // we agree to talk fast!
    ADC_init(PulsePin);
  T0_init();                 // sets up to read Pulse Sensor signal every 2mS  
}

void main(void)
{
  sys_init();
    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    
             }
  
  //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;  //Æô¶¯²¨ÌØÂʲúÉú
}
/*void UART_send(char dat)//´®¿Ú·¢ËÍÒ»¸ö×Ö½ÚÊý¾Ý
{
    SBUF=Byte;//¼ì²âÊÇ·ñÍê³É
    while(TI==0);
    TI=0;//TI¸´Î»
}
void UART_Routine() interrupt4
{
    if(RI==1){
        P1=SBUF;//ÏÔʾLED
        UART_send(SBUF);//½«Êý¾Ý·¢»ØµçÄÔ
        RI=0//¸´Î»
    }
}*/
 char putchar(unsigned char dat)
{
    TI=0;
    SBUF=dat;
    while(!TI);
    TI=0;
    
    return SBUF;
}
void delay(unsigned int n)
{
    unsigned int i,j;
    for(i=0;i<n;i++)
        for(j=0;j<100;j++);
}
void LED_Disp_Seg7(void)
{

  LedCtrl = LedCtrl | 0xf0;
    switch(order)
    {
        case 0:
            LedPort = LED_Disp[DisBuff[0]];
            LedCtrl = LedCtrl & 0x7f;
            break;
        case 1:
            LedPort = LED_Disp[DisBuff[1]];
            LedCtrl = LedCtrl & 0xbf;
            break;
        case 2:
            if(DisBuff[2]==0)
                LedCtrl = LedCtrl | 0xf0;
            else
            {
                LedPort = LED_Disp[DisBuff[2]];
                LedCtrl = LedCtrl & 0xdf;
            }
            break;
        default:
            LedCtrl = LedCtrl | 0xf0;
    }
   if(++order>2)
            order=0;
}




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
    LED_Disp_Seg7();


    //  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[i] = 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[i] = rate[i+1];                  // and drop the oldest IBI value 
        runningTotal += rate[i];              // 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[0]   = BPM%10;//È¡¸öλÊý
            DisBuff[1]   = BPM%100/10; //ȡʮλÊý
            DisBuff[2]   = BPM/100;       //°ÙλÊý
      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){                           // if 2.5 seconds go by without a beat
    thresh = 512;                          // set thresh default
    Peak = 512;                               // set P default
    Trough = 512;                               // set T default
    lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date        
    firstBeat = true;                      // set these to avoid noise
    secondBeat = false;                    // when we get the heartbeat back
  }

  EA=1;                                   // enable interrupts when youre done!
}// end isr


img

img

img


(串口通信这边需不需要RS232接线到上位机上啊,我觉得需要,客服说不需要)
谢谢大家

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-19 15:32
    关注

    引自免费微信小程序:皆我百晓生

    看起来你在尝试将一个基于Arduino的脉搏传感器程序移植到STC12C5A60S2单片机上。根据你提供的信息,代码中的大部分功能应该已经实现了,包括串口通信、ADC读取以及心跳检测等。

    首先,我们需要确认几个关键点:

    1. 硬件连接:确保脉搏传感器正确地连接到了你的单片机上,并且与Arduino上的连接方式一致。
    2. 时钟设置:你的系统时钟设置为11.0592MHz,这是正确的,因为Arduino Uno的时钟也是这个频率。这应该不会影响代码的运行。
    3. 串口配置:你已经在UART_init()函数中设置了波特率为115200,与Arduino程序中的设置相同。如果你在Processing中也配置了相同的波特率,那么串口通信应该可以正常工作。
    4. 脉冲检测:你的中断服务例程(ISR)Timer0_rountine()正在处理脉搏信号并计算心率。检查一下你的脉搏传感器是否真的在每个心跳周期产生可检测的信号变化。有些传感器可能需要特定的驱动电路才能正确工作。

    针对以上分析,我有以下几个建议来帮助你排查问题:

    步骤1: 验证脉搏传感器信号是否可用

    • 连接示波器或逻辑分析仪查看脉搏传感器输出信号。你应该能看到脉冲信号的上升沿和下降沿,它们对应于心脏跳动。
    • 如果你没有测试设备,可以在Timer0_rountine()函数中加入简单的打印语句,比如printf("Signal: %d\n", Signal);,这样可以在串口助手看到每次中断时的脉冲信号值。观察这些值是否有规律的变化。

    步骤2: 检查串口通信

    • 尝试发送一些固定的数据,例如sendDataToProcessing('X', 123);,看串口助手能否接收到。这可以帮助你确定串口通信是否正常工作。
    • 如果串口通信有问题,检查单片机的引脚分配,确保P3.0(RXD)和P3.1(TXD)被正确配置为串口输入和输出。

    步骤3: 查看中断设置

    • 确保中断管理部分设置正确。在你的代码中,已经启用了定时器0中断(INT0)。你需要确保单片机的中断总开关(EA)已经被打开,并且定时器0中断允许位(ET0)也被设置。
    • main()函数中添加EA=1;确保全局中断开启,这应该在sys_init()函数之外进行设置,以确保在整个程序运行期间都启用中断。

    步骤4: 逐步调试

    • 使用断点或者简单的打印语句,逐步检查程序执行过程,看看哪一步开始出现问题。
    • 特别关注sendDataToProcessing()函数,确认它是否成功发送数据到串口。

    如果以上步骤都无法找到问题,那么可能是单片机硬件问题或者是脉搏传感器的问题。在这种情况下,你可能需要借助专业的开发工具(如示波器、逻辑分析仪)或者找一位熟悉STC12C5A60S2单片机的开发者协助诊断。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月19日

悬赏问题

  • ¥15 单纯型python实现编译报错
  • ¥15 c++2013读写oracle
  • ¥15 c++ gmssl sm2验签demo
  • ¥15 关于模的完全剩余系(关键词-数学方法)
  • ¥15 有没有人懂这个博图程序怎么写,还要跟SFB连接,真的不会,求帮助
  • ¥15 PVE8.2.7无法成功使用a5000的vGPU,什么原因
  • ¥15 is not in the mmseg::model registry。报错,模型注册表找不到自定义模块。
  • ¥15 安装quartus II18.1时弹出此error,怎么解决?
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音