Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ATMEL Mega32 and Pic16f877a

Status
Not open for further replies.

Santoshhh

Newbie level 6
Joined
Jul 5, 2012
Messages
13
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,401
Hi all,
First of all, I let you know that I am a beginner in PIC programming. I am designing a Digital Blood Pressure Monitor and a Digital thermometer and also the wireless transmission of its output using a GSM MODEM. For the case of software part I am using MPLAB IDE and HITEC C compiler. I am writng the code in C language. After getting some problems during coding, I started surfing for help. I got a link to Cornell University's Project. I also found a code there. They have used ATMEL MEGA32 microcontroller. I am totally blank about how to code in that microcontroller. So, I could not understand some parts of the code, especially the Interrupt and the ADC thing and some of the registers. I am posting the code below. I would be so grateful if somebody changes the code to make it compatible to use with the PIC16F877A microcontroller. I know I am asking a lot to do but please I need it.

The link to the code is:
https://people.ece.cornell.edu/land...ects/s2005/ww56_ws62/Final Project Web/code.c

If link not available, the code is:

Code:
#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
	{
		currentState = inflate1State; 	
	} 
	
}
//***********************************************
void deflatestate(void)
{                                         
    /*if(timedeflate >= 1900)
    {   
         PORTD = 0;
         if(timedeflate >= 2000)
         {
         	PORTD = 0x02;
         	timedeflate = 0;
         }
    }*/
	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;                            
    }
	//if(done) --> Display state
	if(currentState==deflateState) pressuremeasure(); //if still deflating, measure everything
}

//***********************************************
void display_state(void)
{   
     
if(timedisplay<=1000)
{
    if(timecount>=200)
	{
	lcd_clear();
    timecount=0;
	lcd_gotoxy(0,0);
	lcd_putsf("Sys"); 
	lcd_gotoxy(7,0);
	lcd_putsf("Dias");
	lcd_gotoxy(15,0);
	lcd_putsf("HR");                     
	sprintf(lcd_output,"%-i",(int)systolic);
	lcd_gotoxy(0,1);
	lcd_puts(lcd_output);  
	
	sprintf(lcd_output,"%-i",(int)diastolic);
	lcd_gotoxy(7,1);
	lcd_puts(lcd_output); 
	
	sprintf(lcd_output,"%-i",(int)pulse_per_min);
	lcd_gotoxy(14,1);
	lcd_puts(lcd_output);  
	} 
}

else if (timedisplay>1000&&timedisplay<2000)
{	
	if(timecount>=200)
	{	lcd_clear();
        timecount=0;
        
		lcd_gotoxy(0,0);
		lcd_putsf("Black: Resume"); 
	
	}  
}

else
{
    timedisplay=0;
}	
	if((~PINB & 0x04) && (timepress2 > 30)) Maybe2 = 1;
	if(Maybe2 && (PINB == 0xff))
	{
		lcd_clear();       
		lcd_gotoxy(0,0);
		lcd_putsf("White: Start");
		lcd_gotoxy(0,1);
		lcd_putsf("Grey: Stop");
		currentState = startState;
		timepress2 = 0;         
		Maybe2=0; 
		systolic=0;
		diastolic=0;
		pulse_per_min=0;
	
	} 
	   
}
//***********************************************
void reset_state(void)
{   
if(timedisplay<=1000)
{
    if(timecount>=200)
	{   timecount=0;
     	lcd_clear();
		lcd_gotoxy(0,0);
		lcd_putsf("Emergency Stop"); 
	} 
}

else if (timedisplay>1000&&timedisplay<2000)
{	
	if(timecount>=200)
	{	lcd_clear();
        timecount=0;
        
		lcd_gotoxy(0,0);
		lcd_putsf("Black: Resume"); 
	
	}  
}

else
{
    timedisplay=0;
}	          
	if((~PINB & 0x04) && (timepress2 > 30)) Maybe2 = 1;
	if(Maybe2 && (PINB == 0xff))
	{
		lcd_clear();       
		lcd_gotoxy(0,0);
		lcd_putsf("White: Start");
		lcd_gotoxy(0,1);
		lcd_putsf("Grey: Stop");
		currentState = startState;
		timepress2 = 0;
		Maybe2=0; 
	}
	
}
//***********************************************
// 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
}
 
Last edited by a moderator:

Do you have a huge amount of money to spend?

Nobody will put this much work into providing what you want without payment.

..... and have you checked to see if PIC16F877A (low spec PIC) has equivalent processing power to ATMEL Mega 32?

Maybe what you are asking for is impossible, as well as expensive

EDIT: I apologise. I was in grumpy mood last night. Now I see what I wrote, I am embarrassed :oops:
 
Last edited:

Do you have a huge amount of money to spend?

Nobody will put this much work into providing what you want without payment.

..... and have you checked to see if PIC16F877A (low spec PIC) has equivalent processing power to ATMEL Mega 32?

Maybe what you are asking for is impossible, as well as expensive

Thank you for your suggestion.
 

I think you should consider using mega32 for your project.
The provided code is written in codevisionAVR
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top