본문 바로가기

PIC/CCS-C

적외선 센서를 이용한 심박수 카운트 소스코드

상업적 이용을 금지 합니다.

ADC 값 3개를 을 받아서 가운데 값이 가장 클(작을)때를 최대(최소)피크점으로 잡고

피크를 잡으면  일정 값 이하(이상)으로 올라가야 다음 최소(최대)피크점으로 잡는다.


나머지는 소스 분석해 보세요


#include <18F452.h>

#fuses NOWDT,HS

#device *=16, ADC=10

#use delay(clock=20000000)

#use RS232(baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7)


#define ENABLE_PIN D0

#define RS_PIN D1

#define RW_PIN D2

#define Data4 D4

#define Data5 D5

#define Data6 D6

#define Data7 D7

#include "lcd.c"


#byte TRISC = 0xF94

#byte PORTC = 0xF82

#bit PC0 = PORTC.0

#bit TC0 = TRISC.0

#byte ADCON1 = 0xFC1

#byte ADCON0 = 0xFC2

#byte T1CON = 0xFCD

#byte TMR1L = 0xFCE

#byte TMR1H = 0xFCF

#byte INTCON = 0xFF2

#byte PIR1 = 0xF9E

#byte PIE1 = 0xF9D 


int16 ADC_value[3];               // ADC로부터 측정된 값을 저장                          

int start;                //시작을 알리는 변수

int heart;                //심박수 

int count;

int sec_count;

int low_flag = 0;


#int_timer1

void timer1_isr() {

   TMR1H = 0x3C;

   TMR1L = 0xB0;

   count++;

   if(count==50) {

      count=0;

      sec_count++;

      lcd_gotoxy(2,2);

      lcd_putc("Sec : 0");

      lcd_putc((sec_count/10)+48);

      lcd_putc((sec_count%10)+48);

      lcd_putc(" sec      ");

      printf("Sec : %d\n", sec_count);

   }

}


#int_EXT

void  EXT_isr(void) 

{

   start = 1;

   lcd_gotoxy(2,1);

   lcd_putc ("Measurement Start");

   printf("Measurement Start\n");

   lcd_gotoxy(2,3);

   lcd_putc("heart count : 000");;

   enable_interrupts(INT_TIMER1); //타이머 시작

   PORTC = 0x01;

}



void stop_chack() {

   if(sec_count >= 60) {

      start = 0;

      lcd_gotoxy(2,1);

      lcd_putc("Measurement End     ");

      printf("Measurement END\n");

      PORTC = 0x00;

   }

}


void get_data()            //ADC로 부터 값을 받아들이는 함수

{

   delay_us(2);

   ADC_value[0] = ADC_value[1];

   ADC_value[1] = ADC_value[2];

   ADC_value[2] = read_adc();;  //PORTD 로부터 값을 받아 저장.(우리거) //P2 & 0xff;    //PORT2로 부터 값을 받아들여 저장

   lcd_gotoxy(2,4);

   lcd_putc("ADC Value : ");

   lcd_putc((ADC_value[2]/100)+48);

   lcd_putc(((ADC_value[2]%100)/10)+48);

   lcd_putc((ADC_value[2]%10)+48);

   printf("ADC = %lu\n", ADC_value[2]);

}


void compare_value()            //측정되고 저장된 값들을 비교

{

   if((ADC_value[0] > ADC_value[1]) & (ADC_value[2] > ADC_value[1]) & (ADC_value[1] < 500)) {

      low_flag = 1;

   }

   if((ADC_value[0] < ADC_value[1]) & (ADC_value[2] < ADC_value[1]) & (ADC_value[1] > 800) & (low_flag)) {

      heart++;

      low_flag = 0;

      lcd_gotoxy(2,3);

      lcd_putc("heart count : ");

      lcd_putc((heart/100)+48);

      lcd_putc(((heart%100)/10)+48);

      lcd_putc((heart%10)+48);

      printf("heart count : %d\n", heart);

      

   }

}


void init() {

   

   heart = 0;

   ADC_value[0] = 0;

   ADC_value[1] = 0;

   ADC_value[2] = 0;

   count=0;

   sec_count=0;

   low_flag = 0;

}




void main(void) {

   TRISC = 0x00;

   PORTC = 0x00;

   lcd_init();

   count = 0;

   sec_count = 0;

   T1CON = 0b10000100;

   PIR1 = 0b00000000;

   PIE1 = 0b00000001;

   INTCON = 0b11000000;

   ADCON1 = 0b11000000; //16bit, channel1, 

   ADCON0 = 0b01001001;

   

   ext_int_edge(L_TO_H); 

   enable_interrupts(INT_EXT);

   enable_interrupts(GLOBAL);

   

   start = 0;

   lcd_gotoxy(2,2);

   lcd_putc("Please press");

   lcd_gotoxy(6,3);

   lcd_putc("the switch");

   

   printf("Please press the switch\n");

   

   while(TRUE) {

      while(!start) {

         init();              //변수 초기화

      }

      

      T1CON = 0b10000101; 

      

      get_data();             //ADC값 받음

      

      compare_value();        //심박수 카운트

      

      delay_ms(10);

      

      stop_chack();

   }

}



'PIC > CCS-C' 카테고리의 다른 글

[CCS-C]4Line LCD  (0) 2012.10.18