Acasa | Introducere | Diagrama | C. Analogic | Hardware-ul | Software-ul | Referinte

Click dreapta si save target as... <<aici>> pentru a downloada varianta .txt a codului sursa

Codul sursa:
#include <Mega32.h>
#include <delay.h>

#asm
.equ __lcd_port = 0x15
#endasm

#include <math.h>
#include <lcd.h>
#include <stdio.h>
#include <stdlib.h>

 

//define states for Measure control
#define Sys_Measure 6
#define Sys_Cal 7
#define Rate_Measure 8
#define dias_Measure 9
#define dias_Cal 10

#define LCDwidth 16

void initialize(void);

//declare all functions for measuring control
void pressuremeasure(void);
void sysmeasure(void);
void syscal(void);
void ratemeasure(void);
void diasmeasure(void);
void diascal(void);

//declare variable for measuring and calculating value
float DC_gain;
unsigned char meas_state;
unsigned int timing, timerate, timerun_dias, timecount, timedeflate, timedisplay;
float maxpressure, pressure,accum_data, press_data;
unsigned char count, stop_count;

//ADC data variabls
float Vref;
unsigned char data;
float adc_data, former;

//define counter
unsigned char sys_count,count_average, countpulse;

//declare rate measure variable
float time_pulse,pulse_period, total_pulse_period, pulse_per_min;

//declare systolic and diastolic variable
float systolic, diastolic;

//declare all the threshold values
float TH_sys, TH_rate, TH_dias;


//***********************************************
//timer 0 compare ISR
interrupt [TIM0_COMP] void timer0_compare(void)
{
if(~PINB & 0x01) timepress0++;
if(~PINB & 0x02) timepress1++;
if(~PINB & 0x04) timepress2++;
timecount++;
timedeflate++;
//Decrement each time tast if they are not already zero

//timing for sampling data at every 40 msec
if(timing>0) --timing;
//-----------------------------------------------------
//run time for different tasks

//run timerate for measuring heart rate
if(timerate<6000) ++timerate;

//run timerun_dias
if(timerun_dias<2000) ++timerun_dias;

//if(countlcd) timelcd++;

//run time for the display
if(timedisplay<2000) ++timedisplay;
}

//***********************************************
// ADC Interrupt
//**********************************************************

interrupt [ADC_INT] void adc_complete(void)
{
data = ADCH;
//then calculate adc_data into float;
adc_data = (float)(((float)data)/256*Vref);


//if signal is above threshold, go to calculate systolic pressure
if(meas_state ==Sys_Measure)
{

if(former<=TH_sys && adc_data>TH_sys)
sys_count++;

former = adc_data;



}
//-----------------------------------------------------------
else if(meas_state==Sys_Cal)
{

if(count<4)
{
accum_data=accum_data+adc_data;
count++;
}
if(count==4)
{
press_data=accum_data/4;
systolic = (press_data/DC_gain)*9375;//calculate from adc_data
meas_state = Rate_Measure;
countpulse=0;
former = 2.4; //set the initial point for rate measuring
count_average=0;
}
}
//----------------------------------------------------------

else if(meas_state==Rate_Measure)
{
if(count_average<5)
{

if(former<TH_rate && adc_data>TH_rate && countpulse==0)
{
timerate=0;
countpulse=1;
former=adc_data;
}

if(former<TH_rate && adc_data>TH_rate && countpulse==1)
{
total_pulse_period=total_pulse_period+timerate;
timerate=0;
count_average++; //finish reading one period
}

}//count_average

former=adc_data;

}// else if(meas_state=Rate_Measure)
//-------------------------------------------------------------
else if(meas_state==dias_Measure)
{
if(timerun_dias<2000)
{
if(adc_data>TH_dias)
{ timerun_dias=0; //reset time if the signal
//is still greater than threshold (so it will never reach 1999)
//if it doesn't reset,the time will stuck at 1999
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Dias measure");
}
}
if(timerun_dias>=2000)
{
meas_state = dias_Cal;//if done go back to Sys_Measure to be ready for next opt
}

}
//-------------------------------------------------------------
else if(meas_state==dias_Cal)
{
diastolic = (adc_data/DC_gain)*9375;//calculate from adc_data
meas_state = Sys_Measure;
currentState = displayState;
//open valve
PORTD=0;

}

timing = 40;//set time for another conversion

}// end of ADC interrupt
//***********************************************************

//**********************************************
void start_state(void)
{ sys_count=0;
pressure = 0;
accum_data=0;
press_data=0;
count=0;
stop_count=0;

maxpressure = 200;
meas_state = Sys_Measure;
former=TH_sys-0.01;

timerun_dias=0;
time_pulse=0;
timerate=0;

timing=50;

total_pulse_period=0;
systolic=0;
diastolic=0;
pulse_per_min=0;

sys_count=0;
count_average=0;
countpulse=0;

if((~PINB & 0x01) && (timepress0 > 30)) Maybe0 = 1;
if(Maybe0 && (PINB == 0xff))
{
countlcd = 1;
timelcd = 0;
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Inflating");
currentState = inflate1State;
Maybe0 = 0;
timepress0 = 0;
timecount=0;
//turn on motor and close the valve
PORTD=0x03;
//activate ADC
}
}
//***********************************************

//***********************************************
// Function to measure everything
//------------------------------------------------
void pressuremeasure(void)
{
switch (meas_state)
{
case Sys_Measure:
if(timing==0) sysmeasure(); //sampling signal at 40msec
break;

case Sys_Cal:
if(timing==0) syscal();
break;

case Rate_Measure:
if(timing==0) ratemeasure();
break;

case dias_Measure:
diasmeasure();
break;

case dias_Cal:
diascal();
break;

} //switch

}//pressuremeasure
//*********************************************************
void sysmeasure(void)
{
if(timing==0)
{ADMUX = 0b00100000; //choose ADC0 for reading AC

//enable ADC and set prescaler to 1/128*16MHz=125,000
//and set interupt enable
//and start a conversion
ADCSR = 0b11001111;

}
if(sys_count>=6)
{
meas_state = Sys_Cal;
timecount=0;
}

if(timecount>=200)
{
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Measuring");
timecount=0;
}
}

//***********************************************************
//this function is to calculate systolic pressure
void syscal(void)
{

ADMUX=0b00100001;//choose ADC1 for reading DC

//enable ADC and set prescaler to 1/128*16MHz=125,000
//and set interupt enable
//and start a conversion
ADCSR = 0b11001111;

if(timecount>=200)
{
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Sys Cal");
timecount=0;
}


}//syscal

//************************************************************
void ratemeasure(void)
{

ADMUX=0b00100000; //choose ADC0 for reading AC

//enable ADC and set prescaler to 1/128*16MHz=125,000
//and set interupt enable
//and start a conversion
ADCSR = 0b11001111;
//calculate the mean of pulse rate
if(count_average==5)
{
pulse_period = total_pulse_period/5000;
pulse_per_min= 60/pulse_period;

lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Pulse Rate");
sprintf(lcd_output,"%-i",(int)pulse_per_min);
lcd_gotoxy(0,1);
lcd_puts(lcd_output);

meas_state = dias_Measure;
//then set timerun_dias=0
//also reset count_average for the next operation
count_average=0;
timerun_dias=0;
}
}
//************************************************************
void diasmeasure(void)
{
ADMUX=0b00100000;//choose ADC1 for reading AC

//enable ADC and set prescaler to 1/128*16MHz=125,000
//and set interupt enable
//and start a conversion
ADCSR = 0b11001111;





}//dias measure
//*************************************************************

void diascal(void)
{
ADMUX=0b00100001;//choose ADC1 for reading DC

//enable ADC and set prescaler to 1/128*16MHz=125,000
//and set interupt enable
//and start a conversion
ADCSR = 0b11001111;

if(timecount>=200)
{
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Dias_Cal");
timecount=0;
}

}

void initialize(void)
{


//Initialize LCD
timecount=0;
lcd_init(LCDwidth);
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("White: Start");
lcd_gotoxy(0,1);
lcd_putsf("Grey: Stop");

//set up timer0
TIMSK =2; //turn on timer 0 comp match
OCR0 = 250; //set the compare register to 250

//prescaler to 64 and turn on clear-on-match
TCCR0 = 0b00001011;
timepress0 = 0;
timepress1 = 0;



DDRB=0x00; //PORT B is an input(2 buttons)
DDRD=0xff; //PORT D is an output(motor control);
PORTD=0x00;
PORTB=0xff;
PORTA=0x00;

maxpressure = 160;
meas_state = Sys_Measure;
former=TH_sys-0.01;

TH_sys=4.0;
TH_rate = 2.5;
TH_dias = 4.8;
timerun_dias=0;
time_pulse=0;
timerate=0;

timing=40;
timedisplay=0;

total_pulse_period=0;
systolic=0;
diastolic=0;
pulse_per_min=0;
Vref=5.0;

sys_count=0;
count_average=0;
countpulse=0;

DC_gain=213;

accum_data=0;
press_data=0;
count=0;

#asm
sei
#endasm
}

Top of the page