7-segment display driver – improvements

As you could see in the video I of my 7-segment driver with serial input, the left most digit was flickering heavily. I decided to spend some time to improve the code. I did several variations of the program and finally settled on the following one.

In this new version I eliminated Timer0 and changed the timing of actions in the main loop. The flickering didn’t disappear completely but it became much much better.

Here is the new application.

unsigned char digits[] = {
0b01000000, // 0
0b01111001, // 1
0b00100100, // 2
0b00110000, // 3
0b00011001, // 4
0b00010010, // 5
0b00000010, // 6
0b01111000, // 7
0b00000000, // 8
0b00011000 // 9
};

/****************************************
*
****************************************/
void interrupt ISR()
{
  if (PIR1bits.RCIF == 1) {
    if (FERR == 0)
      adcvalue = RCREG;
    if (OERR == 1) {
      overrun = 1;
    }
    PIR1bits.RCIF = 0;
  }
}

/****************************************
*
****************************************/
void show_overrun_error()
{
  LATC0 = 0;
  LATC1 = 1;
  LATC2 = 1;
  LATC3 = 1;
  LATC4 = 1;
  LATC5 = 1;
  LATA4 = 1;
}

/****************************************
*
****************************************/
void show_number(unsigned char number)
{
  LATC0 = ((number & 0x1) > 0) ? 1 : 0;
  LATC1 = ((number & 0x2) > 0) ? 1 : 0;
  LATC2 = ((number & 0x4) > 0) ? 1 : 0;
  LATC3 = ((number & 0x8) > 0) ? 1 : 0;
  LATC4 = ((number & 0x10) > 0) ? 1 : 0;
  LATC5 = ((number & 0x20) > 0) ? 1 : 0;
  LATA4 = ((number & 0x40) > 0) ? 1 : 0;
}

/****************************************
*
****************************************/
void calculate_digits()
{
  static unsigned int value = 0;
  int remainder;

  if (value == adcvalue)
  return;

  if (adcvalue > 999)
    adcvalue = 999;
    digit1index = adcvalue / 100;
    remainder = adcvalue % 100;
    digit2index = remainder / 10;
    digit3index = remainder % 10;
    value = adcvalue;
}

/****************************************
*
****************************************/
void main()
{
  OSCCON = 0xF0; // set internal osc to 32Mhz
  OPTION_REG = 0x08; // Prescaler not assigned to timer 0

  TRISC0 = 0;
  TRISC1 = 0;
  TRISC2 = 0;
  TRISC3 = 0;
  TRISC4 = 0;
  TRISC5 = 0;
  TRISA4 = 0;
  TRISA5 = 0;
  TRISA2 = 0;
  TRISA0 = 0;
  TRISA1 = 1;

  // configure the RX pin on A1
  RXDTSEL = 1;

  // configure EUSART BAUD rate: Fosc / 64(n+1)
  BRG16 = 0;
  BRGH = 0;

  // configure the EUSART receiver
  CREN = 1;
  SYNC = 0;
  SPEN = 1;

  // The analog bit must be cleared for RX to function
  ANSELAbits.ANSA1 = 0;

  state = 0;
  adcvalue = 0;

  // enabling EUSART rx interrupt
  PIE1bits.RCIE = 1;
  INTCONbits.PEIE = 1;
  INTCONbits.GIE = 1;

  while(1) {
    switch (state) {
      case 0 * INTERVAL:
        LATA0 = 0;
        LATA2 = 1;
        LATA5 = 0;
        if (overrun == 1)
          show_overrun_error();
        else
          show_number(digits[digit2index]);
        break;
      case 1 * INTERVAL:
        LATA0 = 1;
        LATA2 = 0;
        LATA5 = 0;
        if (overrun == 1)
          show_overrun_error();
        else
           show_number(digits[digit3index]);
        break;
      case 2 * INTERVAL:
        LATA5 = 1;
        LATA2 = 0;
        LATA0 = 0;
        if (overrun == 1)
          show_overrun_error();
        else
          show_number(digits[digit1index]);
        break;
      case 3 * INTERVAL:
        calculate_digits();
        break;
     }
     if (state >= 3 * INTERVAL)
       state = 0;
     else
       state++;
  };
}

I found something strange while working on this code. My main development computer is a MAC mini but it does not recognise my fake PICKIT3. Therefore I normally develop on a virtual Windows machine that runs under VirtualBox on my MAC. This time I decided to run the IDE on the MAC and run only the IPE (the programmer) on the Windows. When I compiled the code above on the MAC and downloaded it with Windows, the application behaved very strangely. It would suddenly crash, or come to a halt at random points in time. Other variations of this program caused a read overflow very quickly. It was very strange and nothing I did fixed the problem. So I went back to my normal environment and ran exactly the same code on the Windows machine and it just worked.

I will be very glad if anyone could explain why this happens. I did compare all the compiler settings, especially the optimisation settings, between the two computers and they are identical.

 

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s