Opinions

I want to make a coil winder decremental counter after setting the number on a four digit seven segment display. Use of an ISR is made to refresh the SSDs.
I have from the various searches on google collected code for two sketches that display the number on the SSDs.
One uses a switch case of 9, the second sketch uses an array for the masks for the segments A to G. decimal point is not used.
In the second sketch the ISR has for delays without which the display does not work. How to modify this ISR in the scond sketch so that there are no delays in it.
First sketch:

//Atmega8 @16MHZ
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay_basic.h>


#define SEVEN_SEGMENT_PORT PORTD
#define SEVEN_SEGMENT_DDR  DDRD

volatile uint8_t digits[4];


void sevenSegment(uint8_t n)
{
  /*
    This function writes a digits given by n to the display
    the decimal point is displayed if dp=1

    Note:

    n must be less than 9
  */
  if (n < 10)
  {
    switch (n)
    {
      case 0:
        //.gfedcba
        SEVEN_SEGMENT_PORT = 0b10111111;
        break;

      case 1:
        //.gfedcba
        SEVEN_SEGMENT_PORT = 0b10000110;
        break;

      case 2:
        //.gfedcba
        SEVEN_SEGMENT_PORT = 0b11011011;
        break;

      case 3:
        //.gfedcba
        SEVEN_SEGMENT_PORT = 0b11001111;
        break;

      case 4:
        //.gfedcba
        SEVEN_SEGMENT_PORT = 0b11100110;
        break;

      case 5:
        //.gfedcba
        SEVEN_SEGMENT_PORT = 0b11101101;
        break;

      case 6:
        //.gfedcba
        SEVEN_SEGMENT_PORT = 0b11111101;
        break;

      case 7:
        //.gfedcba
        SEVEN_SEGMENT_PORT = 0b10000111;
        break;

      case 8:
        //.gfedcba
        SEVEN_SEGMENT_PORT = 0b11111111;
        break;

      case 9:
        //.gfedcba
        SEVEN_SEGMENT_PORT = 0b11101111;
        break;
    }

  }

}

void Wait()
{
  uint8_t i;
  for (i = 0; i < 10; i++)
  {
    _delay_loop_2(0);
  }
}

void Print(uint16_t num)
{
  /*
    This function separates a given integer into  digits
    and writes them to the four SSDs.

  */
  uint8_t i = 0;
  uint8_t j;

  if (num > 9999) return; // display all zeroes for number that is >9999


  while (num)
  {
    digits[i] = num % 10;
    i++;

    num = num / 10;
  }
  for (j = i; j < 4; j++) digits[j] = 0;  // show 0 on SSD that is 0
}


int main(void)
{
  uint16_t i;

  // Prescaler = FCPU/256
  TCCR0 |= (1 << CS02);

  //Enable Overflow Interrupt Enable
  TIMSK |= (1 << TOIE0);

  //Initialize Counter

  TCNT0 = 0;

  //Port B[3,2,1,0] as out put
  DDRB |= ((1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB0));

  PORTB = 0b00000000;

  //Port D
  SEVEN_SEGMENT_DDR = 0XFF;

  //Turn off all segments
  SEVEN_SEGMENT_PORT = 0X00;

  //Enable Global Interrupts
  sei();

  while (1)
  {
    Print(9045);
    Wait();
  }

}

ISR(TIMER0_OVF_vect)
{
  /*

    This interrupt service routine (ISR)
    Updates the SSDs

  */
  static uint8_t i = 0;

  if (i == 3)
  {
    //If on 1st SSD go to 4th SSD
    i = 0;
  }
  else
  {
    //Goto Next SSD
    i++;
  }

  //Activate the SSD display according to i
  PORTB &= (0b11110000);
  PORTB |= (1 << i);

  //Write the digit[i] in the ith SSD.
  sevenSegment(digits[i]);

}

Second Sketch:

//   ATmega8@16MHz_7seg_4digit
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>

#define LED_Directions DDRD      /* define LED Direction */
#define LED_Direction DDRB      /* define LED Direction */
#define LED_PORT1 PORTD       /* define LED port */
#define LED_PORT2 PORTB       /* define LED port */

volatile uint8_t digits[4];
volatile uint8_t segments[] = {0b10111111, 0b10000110, 0b11011011, 0b11001111, 0b11100110, 0b11101101, 0b11111101, 0b10000111, 0b11111111, 0b11101111};

int k, j, i, h;
int brightvalue = 0;


void set_brightness()
{
  int brightness = brightvalue;
  while (0 < brightness)
  {
    _delay_us(1);
    --brightness;
  }
}

ISR(TIMER0_OVF_vect)
{
  PORTB = (1 << PB0);
  PORTD = segments[k];
  set_brightness();

  PORTB = (1 << PB1);
  PORTD = segments[j];
  set_brightness();

  PORTB = (1 << PB2);
  PORTD = segments[i];
  set_brightness();

  PORTB = (1 << PB3);
  PORTD = segments[h];
  set_brightness();

}

void SevenSeg_SetNumber(int num)
{


  k = num % 10;
  num = num / 10;

  j = num % 10;
  num = num / 10;

  i = num % 10;
  num = num / 10;

  h = num % 10;
  num = num / 10;
}



int main(void)
{
  sei();
  DDRD = 0xff;    /* define port direction is output */
  DDRB = 0xff;   /* define port direction is output */
  PORTD = 0x00;
  PORTB = 0x00;
  TIMSK = (1 << TOIE0); /* Enable Timer0 overflow interrupts */
  TCNT0 = 0;  /* load TCNT0, count for 10ms*/
  TCCR0 = (1 << CS02); /* start timer0 with /256 prescaler*/

  brightvalue = 1000; /* set brightness level of 7 segment display */

  while (1)
  {

    SevenSeg_SetNumber(9045);/* set value to display */

  }
}

I am using an Atmega *@16MHz as target using MCUDUDES minicore with arduino ide 1.8.11

most multi digit 7-seg displays rapidly change the segment values and enable each digit for a short period of time. presumably set_brightness() is delaying that period of time. it could be replaced by simply calling _delay_us(brightness)

but i don't believe an ISR is needed. i believe all digits can be displayed in a simply sub-function and any additional processing performed between display updates

Set the ISR to repeat four times as often and then use:

ISR(TIMER0_OVF_vect)
{
  static byte digit = 0;
  switch (digit)
  {
    case 0:
      PORTB = (1 << PB0);
      PORTD = segments[k];
      break;

    case 1:
      PORTB = (1 << PB1);
      PORTD = segments[j];
      break;

    case 2:
      PORTB = (1 << PB2);
      PORTD = segments[i];
      break;

    case 3:
      PORTB = (1 << PB3);
      PORTD = segments[h];
      break;
  }
  digit++;
  if (digit > 3)
    digit = 0;
}

johnwasser:
Set the ISR to repeat four times as often and then use:

ISR(TIMER0_OVF_vect)

{
  static byte digit = 0;
  switch (digit)
  {
    case 0:
      PORTB = (1 << PB0);
      PORTD = segments[k];
      break;

case 1:
      PORTB = (1 << PB1);
      PORTD = segments[j];
      break;

case 2:
      PORTB = (1 << PB2);
      PORTD = segments[i];
      break;

case 3:
      PORTB = (1 << PB3);
      PORTD = segments[h];
      break;
  }
  digit++;
  if (digit > 3)
    digit = 0;
}

I am sorry to respond late as these past days was trying to grapple state machine as a debounce method and avoiding use of delay().
I tried your code as suggested and it worked. However did not pre load the TCNT0 counter to speed up refresh as no flicker is perceptible.

BTW where is the number displayed stored in the memory.
I ask this as I now intend to use num-- by button change occurrence.

kssoin:
BTW where is the number displayed stored in the memory.
I ask this as I now intend to use num-- by button change occurrence.

Right now it appears to be a constant:

    SevenSeg_SetNumber(9045);/* set value to display */

You can store the number in a variable and pass the variable to SevenSeg_SetNumber(); to display it.