[PIC] LCD display slows down processing in proteus.experts opinion required

Status
Not open for further replies.

mugheesnawaz

Member level 1
Joined
May 1, 2013
Messages
39
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Visit site
Activity points
1,605
problem in displaying on lcd is that it slows down decrementing my duty.

Code:
unsigned int adc_data[4];
unsigned char analog_selected = 0;
unsigned char str[50];
unsigned short duty1=255;
float form1;
// LCD Module connections
sbit LCD_RS at RD0_bit;
sbit LCD_EN at RD1_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D5 at RD3_bit;
sbit LCD_D4 at RD2_bit;
// End LCD module connections

// LCD Pin direction
sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISD1_bit;
sbit LCD_D7_Direction at TRISD7_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D5_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD2_bit;
// End of LCD Pin direction
void interrupt(){
  if (PIR1.ADIF) {
    PIR1.ADIF=0; // clear AD interrupt flag
    switch (analog_selected){
      case 0:
        adc_data[0] = (ADRESH << 8) | ADRESL; // read dadta from channel 0
        analog_selected++; // increase channel index
        ADCON0 = 0b11001001; // select channel 1
        break;
      case 1:
        adc_data[1] = (ADRESH << 8) | ADRESL; // read dadta from channel 1
        analog_selected++; // increase channel index
        ADCON0 = 0b11010001; // select channel 2;
        break;
      case 2:
        adc_data[2] = (ADRESH << 8) | ADRESL; // read dadta from channel 2
        analog_selected++; // increase channel index
        ADCON0 = 0b11011001; // select channel 3;
        break;
      case 3:
        adc_data[3] = (ADRESH << 8) | ADRESL; // read dadta from channel 3
        analog_selected = 0; // return channel 0
        ADCON0 = 0b11000001; // select channel 0;
        break;
    }
    Delay_Cyc(3); //wait acquisition time
    ADCON0.F2=1; //start conversion again
  }
}
                              // Loop variable

void main(){
  unsigned int i=0;
  float temp;
  CMCON = 7; //Disable ADC  Comparators
  TRISA=0xFF;
  TRISB=0;
  TRISC=0;
  TRISD=0;
  TRISE=0;
  ADCON1 = 0x82; // AN0->AN4 selected as analog input  1/FRC 0010 for AN0 to AN4
  ADCON0 = 0b11000001; // Configue analog mode
  INTCON.GIE = 1; //Enable global interrupt
  INTCON.PEIE = 1; //Enable peripheral interrupt
  PIE1.ADIE = 1; //Enable ADC interrupt
  Delay_us(20); //wait for acquisition time
  ADCON0.F2 = 1; //start conversion
   //PORTE.F0=0;
  //PORTE.F1=1;
  CCP2CON=  0x0B;       //wait for AD conversion and reset timer
  Lcd_Init();
  Lcd_Cmd(_LCD_CURSOR_OFF);
  PWM2_Init(25000); // Initialize PWM1 for 25Khz
               PWM2_Start(); // start PWM1
               PWM2_Set_Duty(duty1); // Set current duty for PWM1
                while(1)
               {

    temp = adc_data[i]; // read data from channel i
    //Delay_us(20); //wait for acquisition time
      i=0;
      form1=((temp*5)/1023) ;
    //PORTD = form1; // Send lower 8 bits to PORTD
    //PORTC = temp >> 2; // Send 2 most significant bits to RB7, RB6
   //form1=((temp*5*10)/(1023));  //i divided buck output by 10 and gave it to AN0
   FloattoStr(form1,str);
    Lcd_Cmd(_LCD_CLEAR);
    Lcd_Out(1, 1, "Battery Voltage=");
    Lcd_Out(2, 1, str);
    //Delay_ms(10);
    duty1-=2.55;
   PWM2_Set_Duty(duty1);
   }
}
 

Attachments

  • Recent Most.rar
    27.6 KB · Views: 86

Hi,

maybe you are running into lack of processing power.

25kHz means an interrupt repeat every 40us.
Mind the overhead needed to save and restore all variables.

Delay_Cyc(3);
hopefully means 3 clock cycles...


A display update rate of 3 times per second is enough.

Try to avoid float calculations to speed up.
form1=((temp*5)/1023) ;
Mathematically correct you should divide by 1024. This could be done by shifitng 10 bits right.. but then you loose the fractional part.

****
An alternative way is to calculate with mV (integer).

then you should perform 16 bit (ADC, left aligned) x 16 bit( 5000mV) integer multiplication.
The result should be 32bits. Use the upper 16 bits and get the result (0...5000 minus one LSB) in mV.

****
Timing:
Your interrupt runs every 40us. In main loop you wait 20 us (i see it´s marked out) ... this means you never can calculate every incoming ADC value.

I´d reduce ADC sampling rate. the wait 10ms (also marked out) seems to be your desired update rate.
So setup the ADC to perform every 10ms a new conversion (=100Hz).
In Interrupt set a flag when conversion is finished.

in main loop wait for the flag to be set (every 10 ms by interrupt) and do your calculations. Clear the flag. Every 32 calculations additinally do your display setup.
This synchronizes calculations to ADC sampling rate and saves a lot of processing power (I estimate the sayving to be about 95% or more)


Klaus
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…