久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2469|回復: 3
打印 上一主題 下一主題
收起左側

最近在做STC15W4K32S4采集心率的實驗,調試了三天沒調試出來,希望有高手指點指點

[復制鏈接]
跳轉到指定樓層
樓主
ID:689493 發表于 2020-4-2 17:45 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
   采用的是STC15W4K32S4單片機作為處理器,心率模塊用的是Pulse sensor,只需要得出心跳次數BPM就行,其中AD轉換我用了P1.3口,通信用的是串口2(P1.0/RxD2    P1.1/TxD2), 另外,心率數據處理部分我參照了那個寶賣家給的Pulse sensor資料,不知道問題出在哪里了,一直沒調試出來(不需要上位機顯示,只需要得到心率值就行),希望有高手幫忙指點一下,謝謝了。下面代碼中我簡單注釋了一下。    再次謝謝大家了

    //系統頻率為11.0592MHz
#include<stc15.h>
#define u8 unsigned char
#define u16 unsigned int
#define false 0
#define true 1       
       
char bdata bit_S2CON;         //定義它主要是為了進行位操作,我用的串口2
sbit TI_2 = bit_S2CON^1;               
sbit RI_2 = bit_S2CON^0;

u8 aa[3];            //定義它是為了存得出的心跳BPM(當成3位數來處理,主要是方便串口通信傳輸它)

//下面這些定義是用在T0中斷中心率的處理,資料上是這樣的
volatile unsigned int BPM;                  //每分鐘的心跳
volatile unsigned int Signal;                //脈沖
volatile unsigned int IBI = 600;             //IBI是相鄰兩次心跳的時間間隔,600的意思應該是0.6ms,我不太清楚
volatile bit Pulse = false;                  // 脈沖的標志
volatile bit QS = false;                   // 這個是得出計算出了心跳次數BPM時候的一個標志
volatile int rate[10];                    //定義成10位數組,主要是為了存10次心跳的間隔時間,然后為了求個平均值
volatile unsigned long sampleCounter = 0;         //上一次心跳的時間
volatile unsigned long lastBeatTime = 0;          //緊接著的下次心跳的時間,這兩個時間相減就是緊挨著的兩次心跳之間的時間
volatile int Peak =512;                    //脈沖峰值,這里資料上是512,我不清楚,是個脈沖中間值吧
volatile int Trough = 512;                 //脈沖的波谷
volatile int thresh = 512;               //波谷上升到波峰的那段的一個中間值,資料上意思是計算相鄰這樣的中間值來計算心跳準確點
volatile int amp = 100;                   //用在波谷到波峰中間值的一個量,初值為什么是100,資料是這樣寫的
volatile bit firstBeat = true;           
volatile bit secondBeat = false;      //跟上面那個一樣是個標志

void delay_ms(u16 z)                 //大概延時1ms的時間
{
        u8 x;
        for(; z > 0; z--)
                for(x = 110; x > 0; x--);
}

void Delay_6us()                //大概延時6us
{
        u8 i;
        i = 14;
        while (--i);
}

void ad_init()                            //ADC初始化 (STC15W4K32S4單片機)
{
        ADC_CONTR |= 0x80;       //開啟ADC的電源
        delay_ms(1);                  //第一次開電源需要延時1ms,書上這樣寫的
        P1ASF |= 0x08;                  //將P1.3口作為AD功能
        ADC_CONTR |= 0x40;      //ADC轉換速度,我選擇額的是180個時鐘周期轉換一次,可以達10位精度
        Delay_6us();                 //每次執行ADC_CONTR寄存器賦值時,要延時一下,書上這樣介紹的
        CLK_DIV |= 0x20;      //這里我設置成轉換結果的高兩位存在ADC_RSE[1:0],轉換結果的低八位存在ADC_RESL[7:0]
}

u16 ad_work()                    //進行AD轉換函數,有返回值,需要對返回的結果進行計算處理,得出心跳次數BPM
{
        u16 result;                    //定義它來存結果
        ADC_CONTR |= 0x03;        //選擇P1.3作為A/D輸入來用
        Delay_6us();
        ADC_CONTR |= 0x08;       //將開始轉換位ADC_START置1,開始進行A/D轉換
        Delay_6us();
        while(!(ADC_CONTR & 0x10));    //判斷標志位ADC_FLAG是否為1了,也就是是否A/D轉換完了
        ADC_CONTR &= 0xE7;           //轉換結束后將標志ADC_FLAG和開始轉換位ADC_START置0;
        Delay_6us();
        result = ADC_RES;            
        result = result << 8;
        result = result + ADC_RESL;  //上面這幾行就是將結果存在result中
        return result;                 //返回值
}

void uart_init()              //串口2的初始化
{
        AUXR |= 0x04;                //采用定時器2,不分頻,它是固定為16位自動重裝
        T2L = 0xFD;               
        T2H = 0x1F;                //裝初值設置波特率為9600
        AUXR |= 0x10;             //將TR2置1
        S2CON = 0x50;        //串口工作在方式2 , 8位數據
        EA = 1;

}

void uart_sendchar(u8 dat)            //發送單個字符
{
        S2BUF = dat;
        while(!(S2CON & 0x02));       //因為S2CON不能被位尋址,所以這里用了前面定義的可以被位尋址的bit_S2CON
        bit_S2CON = S2CON;
        TI_2 = 0;
        S2CON = bit_S2CON;
}

void uart_sendstring(u8 *astring, u16 stringlength)        //發送數組,發送前面定義的aa[3],
{
        u8 i;
        for ( i = 0; i < stringlength; i++ )
        {
                uart_sendchar( astring[i] );
        }
}

void T0_init()                //定時器T0的初始化
{
        TMOD = 0x01;    //工作方式1,16位定時器
        TH0 = 0xF8;
        TL0 = 0xFC;       //定時2ms
        TR0 = 1;
        ET0 = 1;
        EA = 1;
}

void main()
{
        ad_init();
        uart_init();
        T0_init();
        while(1)                        //主函數里就只做將得到的心跳值BPM存在aa數組里,然后發送,,這兩件事情
        {
                if(QS == true)
                {
                        QS = false;
                        aa[0] = BPM/100;
                        aa[1] = BPM%100/10;
                        aa[2] = BPM%100%10;
                        uart_sendstring(aa,3);
                }
        }
}

void Timer0_rountine(void) interrupt 1            //這個T0中斷里下面就是對AD轉換后的值做處理和運算了,得到想要的心跳數BPM,那個寶老板給的資料
{                                                                //這資料里的就是這樣處理的,,不知道它程序邏輯有沒有問題,反正意思清楚,基本上沒怎么改動它
       int N;
        unsigned char i;
       unsigned int runningTotal = 0;                     

        EA=0;                                      
        TH0 = 0xF8;
        TL0 = 0xFC;
  Signal = ad_work();                      //這個地方換成我自己的AD轉換后的結果,然后付給了初始信號Signal
  sampleCounter += 2;                        
  N = sampleCounter - lastBeatTime;      

  if(Signal < thresh && N > (IBI/5)*3){      
    if (Signal < Trough){                        
      Trough = Signal;                       
    }
  }

  if(Signal > thresh && Signal > Peak){         
    Peak = Signal;                           
  }                                      

  if (N > 250){                                 
    if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ){        
      Pulse = true;                              
      IBI = sampleCounter - lastBeatTime;        
      lastBeatTime = sampleCounter;            

      if(secondBeat){                     
        secondBeat = false;               
        for(i=0; i<=9; i++){            
          rate[i] = IBI;                     
        }
      }

      if(firstBeat){                        
        firstBeat = false;                  
        secondBeat = true;               
        EA=1;                             
        return;                          
      }   

      for(i=0; i<=8; i++){               
        rate[i] = rate[i+1];                 
        runningTotal += rate[i];           
      }

      rate[9] = IBI;                        
      runningTotal += rate[9];               
      runningTotal /= 10;                  
      BPM = 60000/runningTotal;            
                        if(BPM>200)BPM=200;                       
                        if(BPM<30)BPM=30;                               
      QS = true;                                                //這里這個QS就是得出心跳次數BPM后的標志
    }                       
  }

  if (Signal < thresh && Pulse == true){   
    Pulse = false;                     
    amp = Peak - Trough;                        
    thresh = amp/2 + Trough;                 
    Peak = thresh;                          
    Trough = thresh;
  }

  if (N > 2500){                           
    thresh = 512;                        
    Peak = 512;                             
    Trough = 512;                           
    lastBeatTime = sampleCounter;               
    firstBeat = true;                     
    secondBeat = false;                    
  }

  EA=1;                                 
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:721191 發表于 2020-4-2 19:04 | 只看該作者
程序代碼看看有沒有報錯,如果沒報錯,在protues上你試試運行一下
回復

使用道具 舉報

板凳
ID:689493 發表于 2020-4-3 08:46 | 只看該作者
岸鞍 發表于 2020-4-2 19:04
程序代碼看看有沒有報錯,如果沒報錯,在protues上你試試運行一下

沒有報錯的,代碼中我已經簡化了,只需要得到計算出來的BPM,通過串口把他發送出去就行,通過上位機Processing顯示波形我都省去了
回復

使用道具 舉報

地板
ID:689493 發表于 2020-4-3 08:52 | 只看該作者
岸鞍 發表于 2020-4-2 19:04
程序代碼看看有沒有報錯,如果沒報錯,在protues上你試試運行一下

沒有報錯的,其他什么傳送上位機processing顯示波形我都省去了,只需要通過串口傳輸計算出的心跳次數BPM就行,還是沒有結果,我單獨測試了AD功能,串口一直會收到'00 00 00 00 00'數據(是按照我預先設定時間運行的)
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 九九视频在线观看视频6 | 久久综合入口 | 99在线国产 | 国产一区二区三区视频在线观看 | 精品乱码一区二区三四区视频 | 91网站在线观看视频 | 美日韩中文字幕 | 久久精品亚洲欧美日韩精品中文字幕 | 国产视频福利一区 | 欧美成人久久 | 日韩一区二区三区视频 | 自拍视频一区二区三区 | 精品国产黄a∨片高清在线 www.一级片 国产欧美日韩综合精品一区二区 | 卡通动漫第一页 | 91资源在线观看 | 免费黄色特级片 | 日本手机在线 | 午夜影院污 | 久久福利电影 | 亚洲一区免费 | 一级片在线观看 | 一级中国毛片 | 99视频免费 | 久久久久久99| 操久久 | 97国产精品视频人人做人人爱 | 亚洲国产欧美在线 | 亚洲精品在线视频 | 亚洲激情一区二区 | 91精品国产综合久久婷婷香蕉 | 久久久久国产 | 人人人人干| 99国产视频 | 黄色三级毛片 | 做a的各种视频 | 久久精品国产亚洲 | 精品欧美一区二区精品久久 | 色黄视频在线 | 99久久精品国产一区二区三区 | 亚洲一区二区三区在线视频 | 亚洲欧美中文日韩在线v日本 |