Search This Blog

Wednesday, March 31, 2010

Atmega16 code Timer example, using external oscilator, watchdog timer

/*****************************************************
Chip type               : ATmega16
Program type            : Application
AVR Core Clock frequency: 16.000000 MHz External Crystal
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include mega16.h
#include delay.h
#include stdio.h
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x15 ;PORTC
#endasm
#include lcd.h>
#define ADC_VREF_TYPE 0x20

// Read the 8 most significant bits of the AD conversion result
unsigned char read_adc(unsigned char adc_input)
{
    ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
    // Delay needed for the stabilization of the ADC input voltage
    delay_us(10);
    // Start the AD conversion
    ADCSRA|=0x40;
    // Wait for the AD conversion to complete
    while ((ADCSRA & 0x10)==0);
    ADCSRA|=0x10;
    return ADCH;
}

// global variables
//unsigned int freq_array[]={50,100,150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,1000} ;
//unsigned int no_of_pulses[]={2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40} ;
//unsigned int pc_array[]={1,2,5,10,20,50,100,200,500,1000} ;
void PC_OUTPUTS(void);
void DELAY(void);
void CODE(void);
void ADC_DELAY(unsigned int);

unsigned int actual_delay_time,volt;
unsigned int FREQ_COUNTER=2;
unsigned int PC_COUNTER=1;
unsigned int var=1;
unsigned int var2=1;
unsigned int BTN_0=0;      
unsigned int BTN_1=0;
unsigned int BTN_2=0;
unsigned int BTN_3=0;
unsigned int BTN_4=0;
unsigned int S_10=0;
unsigned int ON_OFF_FLAG=0;       //CAL ON/OFF flag

//EEPROM VARS
#pragma warn-
eeprom unsigned int EE_FREQ_COUNTER=2 ;
eeprom unsigned int EE_PC_COUNTER=1 ;
unsigned int eeprom *ptr_EE_FREQ_COUNTER;
unsigned int eeprom *ptr_EE_PC_COUNTER;
#pragma warn+
unsigned int  *ptr_FREQ_COUNTER,*ptr_PC_COUNTER;

//Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
        PORTD.7=~PORTD.7;                       //High-Low pulse
        TCNT1=actual_delay_time;
}

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
   var++;                    //Approx. 10 sec delay
   if (var > 10000)
   {    
      var=1; 
      S_10++;    
   }        
   if(S_10 == 10)
    {
      PORTD.2=0;                       //High-Low pulse
      S_10=0;
      TCCR0=0b00000000;
    }
   TCNT0=0xFF;
}

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
   var2++;         //Push buttons delay
   if (var2 > 54000)
   {  
        var2=1;
        BTN_0=0;      
        BTN_1=0;
        BTN_2=0;
        BTN_3=0;
        BTN_4=0;
   }
    TCNT2=0xFF;     
}

void main(void)
{
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0xFF;
DDRB=0x00;          //input   push buttons

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0xff;           //output         lcd

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0xff;           //output     led

DDRD.3=0;
PORTD.3=1;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0b00000000;                   //0b00000101;
TCNT0=0xFF;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
TCNT1=55535;
TCCR1A=0b00000000;
TCCR1B=0b00000010;   //SELECT CLOCK HRER CS
       
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
OCR2=0x00;
TCCR2=0b00000101;
TCNT2=0xFF;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

//Timer(s)/Counter(s) Interrupt(s) initialization
//TIMSK=0x00;
TIMSK=0b01000101;                  //6 bit timer2  0 bit tiemr0   2 bit timer1 
// Analog Comparator initialization
// Analog Comparator:
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0xA6;
SFIOR&=0x1F;

lcd_init(20);
lcd_clear();
lcd_putsf("ETM");

ptr_EE_FREQ_COUNTER=&EE_FREQ_COUNTER;
ptr_EE_PC_COUNTER=&EE_PC_COUNTER;
ptr_FREQ_COUNTER=&FREQ_COUNTER;
ptr_PC_COUNTER=&PC_COUNTER;
*ptr_FREQ_COUNTER=*ptr_EE_FREQ_COUNTER;
*ptr_PC_COUNTER=*ptr_EE_PC_COUNTER;

#asm("sei")
DELAY();
PC_OUTPUTS();

// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/256k
#pragma optsize-
WDTCR=0x1C;
WDTCR=0b00001111;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

PORTD.7=0;
TCCR1A=0b00000000;
TCCR1B=0b00000000;       //STOP TIMER
lcd_gotoxy(13,1);
lcd_putsf("OFF");
               
while (1)
      { 
         //read voltage from PORTA.0  0 - 255   
         WDTCR=0b00001111;
         volt=(unsigned int)read_adc(0);                                 //100 us 
         if (S_10==0)
         {     
             if(PIND.3==0)
             {
              PORTD.2=1;
              S_10=1;
              TCCR0=0b00000101;
             }
         }      
        DELAY();  
        WDTCR=0b00001111;          
        CODE(); 
        delay_ms(350);       
      };                                                        //END OF WHILE LOOP              
}                                                               //END OF MAIN

void CODE()
{
        //CAL ON OFF
        if (PINB.4 == 0 && BTN_4==0)
         {
            if (ON_OFF_FLAG==1) 
            {
                ON_OFF_FLAG=0;
                lcd_gotoxy(13,1);
                lcd_putsf("OFF");  
                PORTD.7=0;
                TCCR1A=0b00000000;
                TCCR1B=0b00000000;   //STOP TIMER 
            }   
            else
            {
                ON_OFF_FLAG=1; 
                lcd_gotoxy(13,1);
                lcd_putsf(" ON"); 
                PC_OUTPUTS();  
                TCCR1A=0b00000000;
                TCCR1B=0b00000010;   //START TIMER           prescaler=8 
                //PORTD.2=1;
                //TCCR0=0b00000101;
            }
            BTN_4=1;
         }
         if (PINB.4 == 1)
            BTN_4=0;              
                   
        //INCREASE NO OF PULSES PORTB 0 PIN       
        if (PINB.0 == 0 && BTN_0==0)
         {
            if (FREQ_COUNTER < 40)
             {
              FREQ_COUNTER=FREQ_COUNTER+2; 
              *ptr_EE_FREQ_COUNTER=*ptr_FREQ_COUNTER;
             }  
             else
             {
              FREQ_COUNTER=2;
              *ptr_EE_FREQ_COUNTER=*ptr_FREQ_COUNTER;
             }
             BTN_0=1; 
         }
        if (PINB.0 == 1)
            BTN_0=0;       
        
        //DECREASE NO OF PULSES PORTB 1 PIN     
        if (PINB.1 == 0 && BTN_1==0)
         {    
            if (FREQ_COUNTER > 2)
             {
                FREQ_COUNTER=FREQ_COUNTER - 2;  
               *ptr_EE_FREQ_COUNTER=*ptr_FREQ_COUNTER;
             }
             else
             {
               FREQ_COUNTER=40;  
               *ptr_EE_FREQ_COUNTER=*ptr_FREQ_COUNTER;
             }
             BTN_1=1; 
         } 
        if (PINB.1 == 1)
            BTN_1=0;       
             
        //INCREASE IN PC COUNT PORTB 2 PIN     
        if (PINB.3 == 0 && BTN_2==0)
         {
            if (PC_COUNTER < 10)
             {      
                PC_COUNTER++;
                PC_OUTPUTS();
               *ptr_EE_PC_COUNTER=*ptr_PC_COUNTER;
             }
             else
             {
                PC_COUNTER=1;
                PC_OUTPUTS();
               *ptr_EE_PC_COUNTER=*ptr_PC_COUNTER;            
             }
             BTN_2=1;
         }
        if (PINB.3 == 1)
            BTN_2=0;       
          
        //DECREAE IN PC COUNT PORTB 2 PIN     
        if (PINB.2 == 0 && BTN_3 == 0)
         {
            if (PC_COUNTER > 1)
             {
                PC_COUNTER--;
                PC_OUTPUTS();
                *ptr_EE_PC_COUNTER=*ptr_PC_COUNTER;
             }
             else
             {
                PC_COUNTER=10;
                PC_OUTPUTS();
                *ptr_EE_PC_COUNTER=*ptr_PC_COUNTER;
             }
             BTN_3=1;  
         }
        
        if (PINB.2 == 1)
            BTN_3=0;       
      
        //BATTERY INDICATION  PORTB 5 PIN - LO   6 - OK  7 - CH
        if (PINB.6 == 0)
         {
            lcd_gotoxy(10,0);
            lcd_putsf("BAT OK");
         }
         else if (PINB.7 == 0)
         {
            lcd_gotoxy(10,0);
            lcd_putsf("BAT CH");
         }  
         else if  (PINB.5 == 0)
         {
            lcd_gotoxy(10,0);
            lcd_putsf("BAT LO");
         }
         else
         { 
            lcd_gotoxy(10,0);
            lcd_putsf("      ");   
         }
}

/*------------------------------------------------------------------------------
 Procedure:    PC_OUTPUTS
 Inputs:        none
 Return:        none
 Description:    Vary the 5 PC signals
------------------------------------------------------------------------------*/

void PC_OUTPUTS(void)
{
       lcd_gotoxy(0,1);
       switch (PC_COUNTER)
       {
         case 1:      
             PORTD.0=0;
             PORTD.1=0;
             PORTD.4=1;  
             PORTD.5=0;
             PORTD.6=1;
             //lcd_gotoxy(0,1);
             lcd_putsf("CAL PC 1   ");
             break;  
         case 2: 
             PORTD.0=0;
             PORTD.1=1;
             PORTD.4=0;  
             PORTD.5=1;
             PORTD.6=0;
             //lcd_gotoxy(0,1);
               lcd_putsf("CAL PC 2  ");
             break;
         case 3:
             PORTD.0=1;
             PORTD.1=0;
             PORTD.4=1;  
             PORTD.5=1;
             PORTD.6=0;
             //lcd_gotoxy(0,1);
               lcd_putsf("CAL PC 5   ");
             break;
         case 4:
             PORTD.0=0;
             PORTD.1=0;
             PORTD.4=1;  
             PORTD.5=1;
             PORTD.6=0;
             //lcd_gotoxy(0,1);
               lcd_putsf("CAL PC 10  ");
             break;
         case 5:
             PORTD.0=0;
             PORTD.1=1;
             PORTD.4=1;  
             PORTD.5=0;
             PORTD.6=0;
             //lcd_gotoxy(0,1);
             lcd_putsf("CAL PC 20  ");
             break;   
          case 6:      
             PORTD.0=1;
             PORTD.1=0;
             PORTD.4=1;  
             PORTD.5=0;
             PORTD.6=0; 
             //lcd_gotoxy(0,1);
              lcd_putsf("CAL PC 50  ");
             break;  
         case 7: 
             PORTD.0=0;
             PORTD.1=0;
             PORTD.4=1;  
             PORTD.5=0;
             PORTD.6=0;
             //lcd_gotoxy(0,1);
              lcd_putsf("CAL PC 100 ");
             break;
         case 8:
             PORTD.0=0;
             PORTD.1=1;
             PORTD.4=0;  
             PORTD.5=0;
             PORTD.6=0;
             lcd_gotoxy(0,1);
             lcd_putsf("CAL PC 200 ");
             break;
         case 9:
             PORTD.0=1;
             PORTD.1=0;
             PORTD.4=0;  
             PORTD.5=0;
             PORTD.6=0;
             //lcd_gotoxy(0,1);
             lcd_putsf("CAL PC 500 ");
             break;
         case 10:
             PORTD.0=0;
             PORTD.1=0;
             PORTD.4=0;  
             PORTD.5=0;
             PORTD.6=0;
             lcd_gotoxy(0,1);
              lcd_putsf("CAL PC 1000");
             break; 
         default:
             PORTD.0=0;
             PORTD.1=0;
             PORTD.4=1;  
             PORTD.5=1;
             PORTD.6=0;
             //lcd_gotoxy(0,1);
             //sprintf(str_buffer,"ERROR PC - %u",PC_COUNTER) ;
             lcd_putsf("INC MAG");
             PC_COUNTER=1;

       };
}


/*------------------------------------------------------------------------------
 Procedure:    ADC_DELAY
 Inputs:        DELAY (STEP) TIME
 Return:        none
 Description:    DELAY +/- 2.5%
------------------------------------------------------------------------------*/
void ADC_DELAY(unsigned int delay_time)
{
    actual_delay_time=65535 - (delay_time*2-3);
    if ( volt < 128)
    {  
        actual_delay_time= 65535 -(( delay_time -  (delay_time  / 100) * (10 - (8 * volt  / 100  ) ) ) )*2-3; 
    }  
    if (volt > 128 && volt < 256)
    {
        actual_delay_time= 65535 -(( delay_time + (delay_time  / 100) * (8 * (volt - 128) / 100 ) ) )*2-3;
    }
      
    if (volt == 127 || volt == 128)
         actual_delay_time=65535 - (delay_time*2-3);     
        
   WDTCR=0b00001111;                             
}

/*------------------------------------------------------------------------------
 Procedure:    DELAY
 Inputs:        none
 Return:        none
 Description:    Vary the Delay of signal
------------------------------------------------------------------------------*/
void DELAY(void)
{
     lcd_gotoxy(0,0);       
     switch (FREQ_COUNTER)
       {
         case 2: 
             ADC_DELAY(10000);
             lcd_putsf("PUL NO 2 ");
             break;  
         case 4:                      
             ADC_DELAY(5000); 
             lcd_putsf("PUL NO 4 ");
             break;
         case 6:
             ADC_DELAY(3333);
             lcd_putsf("PUL NO 6 ");
             break;
         case 8:
             ADC_DELAY(2500);
             lcd_putsf("PUL NO 8 ");
             break;
         case 10:
             ADC_DELAY(2000);
             lcd_putsf("PUL NO 10");
             break;   
         case 12:
             ADC_DELAY(1667);      
             lcd_putsf("PUL NO 12");
             break;  
         case 14:
             ADC_DELAY(1428);
             lcd_putsf("PUL NO 14");
             break;
         case 16:
             ADC_DELAY(1250);
             lcd_putsf("PUL NO 16");
             break;
         case 18:
             ADC_DELAY(1111);
             lcd_putsf("PUL NO 18");
             break;
         case 20:
             ADC_DELAY(1000);
             lcd_putsf("PUL NO 20");
             break;   
         case 22:
             ADC_DELAY(909);     
             lcd_putsf("PUL NO 22");
             break;  
         case 24:  
             ADC_DELAY(833);
             lcd_putsf("PUL NO 24");
             break;
         case 26:
             ADC_DELAY(769);
             lcd_putsf("PUL NO 26");
             break;
         case 28:
             ADC_DELAY(714);
             lcd_putsf("PUL NO 28");
             break;
         case 30:
             ADC_DELAY(667);
             lcd_putsf("PUL NO 30");
             break;   
         case 32:    
             ADC_DELAY(625);
             lcd_putsf("PUL NO 32");
             break;  
         case 34:
             ADC_DELAY(588);
             lcd_putsf("PUL NO 34");
             break;
         case 36:  
             ADC_DELAY(556);
            lcd_putsf("PUL NO 36");
             break;
         case 38: 
             ADC_DELAY(526);
             lcd_putsf("PUL NO 38");
             break;
         case 40:   
             ADC_DELAY(500);
             lcd_putsf("PUL NO 40");
             break; 
         default:
             ADC_DELAY(500);
             //sprintf(str_buffer,"ERROR-%u",FREQ_COUNTER)  ;
             lcd_putsf("INC/DEC"); 
             FREQ_COUNTER=2;
       };     
      
}

No comments:

Post a Comment