Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Optimizing ISR code PIC18

Status
Not open for further replies.

lloydi12345

Member
Hi ETO, I would like to ask help about optimizing the speed of my software. The objective is to display characters on two dual 7segment temperature reading. The temperature reading happens every second. The problem is I could notice this flickering on display whenever the microcontroller does an ADC conversion from a thermistor.

Here's my software:

C:
void isr_high(void){
   PIR1bits.TMR1IF =0;   //clear Timer1 interrupt flag
   isr_timer_segment++;
   if(isr_timer_segment >8){
      PIE1bits.TMR1IE =0;
      INTCONbits.GIE =0;
      isr_timer_segment =0;
      disp_flag =1;
      }
   TMR1H =0xFF;
   TMR1L =0x00;
}
.
.
.
void main(){
//Initializations of PORTS, modules, etc.
   while(1){
      [while(state ==0){
      if(disp_flag ==1){
//////////////////////////////////////////////////This Segment
      LATC = disp_holder;
      LATD =0x00;
      LATD = ds_data_holder[char_disp_num];
      disp_holder = disp_holder <<1;
      char_disp_num++;
      if(char_disp_num >3){
         char_disp_num =0;
         disp_holder =0x10;
         }
//////////////////////////////////////////////////to be placed in ISR
      PIE1bits.TMR1IE =1;
      INTCONbits.GIE =1;
      disp_flag =0;                 
      }  
      else{
         get_temp_counter++;
         if(get_temp_counter >5000){
            get_temp_counter =0;
            get_temperature();//get ADC reading, Average the reading to have a stable analog      voltage reading
            display_category = cat_temp;
            choose_disp(display_category);
            }
         }
         temp_holder = check_button();  
      }
   }
}


I tried changing my 4Mhz XT Oscillator to 8Mhz then 16Mhz it helped a bit though but didn't solve the problem. Also tried changing TMR1L to 0xFE for it to overflow quickly but still there is a flicker.

I could solve the problem by moving the code lines highlighted with "This segment to be placed in ISR" inside the ISR routine replacing the disp_flag that gets triggered when the interrupt occurs. I would like to optimize this since interrupt service routine should only contain flags to avoid future issues.

Thanks :)
 
Last edited by a moderator:
When running a LED in an interrupt you have to maintain a decent "on time..." How are the two displays configured? Are you running the side by side or each digit separately? I can't see where your T1CON settings are.. you'll need to pre-scale the timer so you can change you ratio's...

Nigel's tutorial's in ASM and mine in C have a driver for dual 7 segment using timer 1.
 
Hi! These are the settings I used.

Code:
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    LATC = 0x00;
    LATE = 0x00;
   
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    PORTE = 0x00;

    TRISA = 0x01;    //default-0x01 make port0 as input for analog reading, make pin ra2 and ra3 inputs also
    TRISB = 0x0F;    //make port0-3 as input for button pressing
    TRISC = 0x00;
    TRISD = 0x00;
    TRISE = 0x00;   

    //Analog settings
    ADCON0 = 0x00; //choose analog0
    ADCON1 = 0x3B; //default-0x0E RA0, RA2 & RA3 is analog and rest are digital, changed vref- and vref+
    ADCON2 = 0xA9; //12 TAD Fosc/8

    // configure Timer1
    T1CONbits.RD16 = 1;     // 16-bit read/write 
    T1CONbits.T1CKPS0 = 1;  // 1:8 prescale
    T1CONbits.T1CKPS1 = 1;
    T1CONbits.T1OSCEN = 0;  // not using external osc, so disable driver 
    T1CONbits.TMR1CS = 0;   // internal clock

    TMR1H = 0xDD;
    TMR1L = 0xAA;

    // enable Timer1
    T1CONbits.TMR1ON = 1;   // turn on timer1

    // other Timer1 settings
    RCONbits.IPEN = 1;            // IPEN = 1
    IPR1bits.TMR1IP = 1;        // Timer1 high priority int
    INTCON2bits.TMR0IP = 1;        // Timer0 high priority int
       
    PIE1bits.TMR1IE = 1;        // Enable timer1
   
   
   
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;

    // configure A/D convertor
    OpenADC(ADC_FOSC_64 & ADC_RIGHT_JUST 
            & ADC_12_TAD, ADC_CH0 & ADC_INT_OFF 
            & ADC_REF_VDD_VSS, ADC_1ANA);
 
The IRP isn't needed as you are running in normal mode... However! My apologies, our tutorials use timer2 as you can use the PR2 register as a comparator... Then you can fine tune the duty cycle of the LED's...

BTW... this isn't being simulated in ISIS is it??? as they do flicker...
 
Move the display multiplexing completely into the ISR and your problem will be fixed. Why do you think you shouldn't? As long as you keep your ISR short then all will be fine.

Mike.
 
The IRP isn't needed as you are running in normal mode... However! My apologies, our tutorials use timer2 as you can use the PR2 register as a comparator... Then you can fine tune the duty cycle of the LED's...

BTW... this isn't being simulated in ISIS is it??? as they do flicker...
It's okay Ian, Yeah I didn't simulate it. I tried it directly on the board.

Move the display multiplexing completely into the ISR and your problem will be fixed. Why do you think you shouldn't? As long as you keep your ISR short then all will be fine.

Mike.
Yeah, did this last resort.

Thanks everyone :)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top