is there something wrong with the code?

Thread Starter

rayda

Joined Apr 23, 2011
3
is there something wrong with this code? This is for PIC16f886 where the project will work depending on the LDR and temperature sensor in the hardware part.
Rich (BB code):
#include <pic.h>

__CONFIG(INTIO & WDTDIS & PWRTDIS & MCLRDIS & UNPROTECT & DUNPROTECT & \
BORDIS & IESOEN & FCMDIS & LVPDIS & DEBUGEN);
__CONFIG(BORV21);

#define FOSC 8000000L

#define LDR_THRESHOLD 50
#define MAX_DCYCLE 255

const char SSEG[] = {
0b11000000,
0b11111001,
0b10100100,
0b10110000,
0b10011001,
0b10010010,
0b10000010,
0b11111000,
0b10000000,
0b10010000,
0b11000110,
0b10001110
};

unsigned char DispDigit[4];
unsigned char DigitCount;
unsigned char TempType;

static void interrupt isr(void)
{
	if(T0IF){
		PORTC = DispDigit[DigitCount];

		PORTB = ~(1 << DigitCount++);
		
		if(DigitCount >3)
			DigitCount = 0;

		TMR0 = 156;
		T0IF = 0;
	}
}

#define _delay_us(x) { unsigned char us; \
	  	       us = (x)/(12000000/FOSC)|1; \
		       while(--us != 0) continue; }


void _delay_ms(unsigned int ms)
{
	unsigned char i;
	do {
		i =4;
		do {
			_delay_us(164);
		}while(--i);
	}while(--ms);
}

void SSEG_putnum(float number)
{
	unsigned char iDigit, iDigit1, iDecimal;

	if(number > 99.9) return;
	
	GIE = 0;

	iDigit = number;
	iDecimal = (number - iDigit) *10;
	DispDigit[1] = SSEG[iDecimal];

	if(iDigit >= 10) {
		iDigit1 = iDigit / 10;
		DispDigit[3] = SSEG[iDigit1];
		iDigit = iDigit - (iDigit1 *10);
	} else {
		DispDigit[3] = SSEG[0];
	}
	DispDigit[2] = SSEG[iDigit] & 0x7F;
	
	GIE = 1;
}

void main (void)
{
	unsigned int iValue, iCTemp;
	unsigned char ldr_value;
	float CentTemp;

	OSCCON=0x70;         

  	TRISA = 0xFF;        
 	TRISB = 0x00;       
  	TRISC = 0x00;        
  	ANSEL = 0b00000011;  
  	ANSELH = 0b00000000; 

	PORTC=0xFF;
  	PORTB=0xFF;

	OPTION = 0b00000101; 
  	TMR0=156;            
  	T0IE = 1;	       
  	GIE = 1;	      

	CCP1CON=0b00001100;  
  	CCPR1L=MAX_DCYCLE;   
	
	
 	T2CON=0b00000101;    
  	PR2=0x65;            
  	TMR2=0;              
  	PSTRCON=0b00001000;  

	DigitCount=0;
 	TempType=0;               
  	DispDigit[0]=SSEG[10];     
  	DispDigit[1]=SSEG[0];      
  	DispDigit[2]=SSEG[0];      
  	DispDigit[3]=SSEG[0];      

	for(;;){
		ADCON0=0b11000001;       
    	ADCON1=0b10110000;       
    	GODONE=1;	             
    	while(GODONE) continue; 
 
		iValue=ADRESL;          
    	iValue += (ADRESH << 8); 
    	iCTemp = iValue;
    	_delay_ms(50);

		GODONE=1;	
    	while(GODONE) continue;

		iValue=ADRESL;           
    	iValue += (ADRESH << 8); 
    	iCTemp += iValue;
    	_delay_ms(50);

		GODONE=1;	
    	while(GODONE) continue;  
		
		iValue=ADRESL;          
    	iValue += (ADRESH << 8); 
    	iCTemp += iValue;

		CentTemp=(iCTemp/3.0)/ 10.24;
		
		ADCON0=0b11000101;       
    	ADCON1=0b00000000;       
    	GODONE=1;	             
    	while(GODONE) continue;

		ldr_value = ADRESH;  
		
		if (ldr_value > LDR_THRESHOLD)
     ldr_value = LDR_THRESHOLD;
		
		CCPR1L=MAX_DCYCLE - (5 * ldr_value); 

		if (RA4 == 0) {             
      		_delay_ms(1);
      		if (RA4 == 0) {            
        	TempType=~TempType;       
      		}
    	}

	if (TempType) {
      CentTemp=((9/5) * CentTemp) + 32;
      DispDigit[0]=SSEG[11];     // Fahrenheit Sign
    } else {
      DispDigit[0]=SSEG[10];     // Centigrade Sign
    }

	SSEG_putnum(CentTemp);
    _delay_ms(200);
  }
}
Please, anyone, please help me to look at it.
I would need to confirm that nothing wrong with the code.
Thank you.
 

AlexR

Joined Jan 16, 2008
732
One point that strike me is that you global variable DigitCount should be declared as "volatile unsigned char".
Any global variable that is used in an interrupt routine should be declared volatile to make sure that its value is read each time before it is used.
 
Top