⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 code.c

📁 这是关于上臂袖带式电子血压计的单片机处理程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 motor control
#define startState 0
#define inflate1State 1
#define inflate2State 2
#define deflateState 3
#define displayState 4
#define resetState 5


//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 functions for motor control            
void start_state(void);
void inflate1_state(void);
void inflate2_state(void);
void deflatestate(void);
void display_state(void);
void reset_state(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 motor controls
unsigned char Maybe0,Maybe1,Maybe2,countlcd;
unsigned char currentState;
unsigned int timepress0, timepress1, timepress2, timelcd;      
char lcd_output[17];

//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 main(void)
{
	initialize();
	while(1)
	{	
		switch(currentState)
		{	
			case startState:
				 start_state();
				 break;
			case inflate1State:
				 inflate1_state();
				 break;
			case inflate2State:
				 inflate2_state();
				 break;
			case deflateState:
				 deflatestate();
				 break;
			case displayState:
				 display_state();
				 break;
			case resetState:
				 reset_state();
				 break;
		
		}
	}
	
}
//***********************************************
void start_state(void)
{   sys_count=0;              
    pressure = 0;
    accum_data=0; 
	press_data=0; 
    count=0;
    stop_count=0; 
     
    maxpressure = 160; 
    meas_state = Sys_Measure; 
    former=TH_sys-0.01;

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

	timing=40;

	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
	} 
}
//***********************************************

void inflate1_state(void)
{         
	if(timecount>=200)
	{
	timecount=0;                       
	sprintf(lcd_output,"%-i",(int)pressure);
	lcd_gotoxy(0,1);
	lcd_puts(lcd_output);
	}
	
	if((~PINB & 0x02) && (timepress1 > 30)) Maybe1 = 1;
	if(Maybe1 && (PINB == 0xff))
	{
		lcd_clear();
		lcd_gotoxy(0,0);
		lcd_putsf("Emergency Stop");             
		sprintf(lcd_output,"%-i",(int)pressure);
	    lcd_gotoxy(0,1);
	    lcd_puts(lcd_output);
		//turn off motor and open the valve
		PORTD=0;
		currentState = resetState;
		Maybe1 = 0;
		timepress1 = 0;
		countlcd = 0;
	}
	else
	{
		currentState = inflate2State;
	} 
		
}
//***********************************************
void inflate2_state(void)
{   
     ADMUX=0b00100001;//choose ADC1 for reading DC
		
    //enable ADC and set prescaler to 1/128*16MHz=125,000
    //and uncheck interupt enable
    //and start a conversion
    ADCSR = 0b11000111;  
    data= ADCH;
    adc_data = (float)(((float)data)/256*Vref);
    pressure= (adc_data/DC_gain)*9375;  
  
    if(pressure>=maxpressure) stop_count++;   
    else stop_count = 0;
    
    if(stop_count>=5)
	{
		lcd_clear();
		lcd_gotoxy(0,0);
		lcd_putsf("Deflating");        
		sprintf(lcd_output,"%-i",(int)pressure);
	    lcd_gotoxy(0,1);
	    lcd_puts(lcd_output);
		//turn off motor but keep the valve
		PORTD = 0x02;
		delay_ms(1000);
		currentState = deflateState;   
		timedeflate = 0;    
		sprintf(lcd_output,"%-i",(int)pressure);
	    lcd_gotoxy(0,1);
	    lcd_puts(lcd_output);
	}
	else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -