Rotary Encoder and 4 digits seven segment display

I have taken ths code from a very old thread on AVR Freaks.
Compiled it for Atmega 32.
I want to make a coil winding , decremental counter starting from the number set on the four digits of seven segment display. (this is the first step to the final requirement.)
The display can be set to the desired number, but to set a number in thousands the spins on the encoder are plenty!
Can the button on the encoder be used to select a digit with every press to set the number on that digit.
Encoder is connected to PD2 and PD0. Switch not used
Seven Segment are connected to PB0…PB6. DP not used.
PC4…PC7 select the ones,tens,hundreds and thousands digit.

//Code for Atmega32 @ 16 MHz
/Code taken from url

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <math.h>
#include <util/delay.h>

#define CHECKBIT(x,y) (x & (y)) /* Check bit y in byte x*/
#define SETBIT(x,y) (x |= (y)) /* Set bit y in byte x*/
#define CLEARBIT(x,y) (x &= (~y)) /* Clear bit y in byte x*/

//lookup table ascii char to 7 segment common anode type with pullup resistors
//static const uint8_t PROGMEM sevsegascii_table[] = {
//  0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xbf // 0 1 2 3 4 5 6 7 8 9 -

//lookup table ascii char to 7 segment common anode type without pullup resistors
static const uint8_t PROGMEM sevsegascii_table[] = {
  0x3F, 0x6, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x7, 0x7F, 0x6F, 0x40 // 0 1 2 3 4 5 6 7 8 9 -
void displayNumber(int number);
void printNumber(int number);
volatile int num;
volatile int ones;
volatile int tens;
volatile int hundreds;
volatile int thousands;

int main(void)
  DDRB = 0xff;  // sets port b as output
  PORTB = 0x00; // sets all bis on port B low
  DDRD = 0x00;   //input port
  PORTD = 0xFF;  //enable pull up resistor
  DDRC = 0xff;
  PORTC = 0x10;
  TCCR0 |= (1<< CS02);  //256 PRESCALER
  TCCR0 |= (1<< WGM01); //CTC MODE
  OCR0 = 130;  //8ms. setting how fast to refresh the display

  MCUCR = 0x01;     //int0 interrupt on level change
  //MCUCR |= (1<<ISC00); // int0 interrupt on level change

  GICR = 0x40;// enable int0 interrupt. This uses 2 bytes less 
              //as compard to next commented statement
  //GICR  |= 1<<INT0;     //enable the int0 interrupt.
  TIMSK |= (1<<OCIE0);  //enable the timer0 compare interrupt
  sei();          //enable global interrupts

  num = 10; //initializing the "counter"

  return 0;
void printNumber(int number)
  int temp = 0;
  //splitting the number into separate numbers
  //to display on the 4 digit 7-segment display
  thousands = floor(number / 1000);
  temp = number % 1000;
  hundreds = floor(temp/100);
  temp = number % 100;
  tens = floor(temp/10);
  ones = temp % 10;
//displaying the number on the 7 segment display
void displayNumber(int number)
  if (number<0) {
  PORTB = pgm_read_byte(&sevsegascii_table[number]);


  //selecting which digit to display
  //timing controlled by Timer0
    case 0x80:
      PORTC = 0x40;
    case 0x40:
      PORTC = 0x20;
    case 0x20:
      PORTC = 0x10;
    case 0x10:
      PORTC = 0x80;



/* this works for MCUCR=0x01 i.e. interrupt on level change */

  // A raising edge
  if ((PIND & (1<<PD2))) {
    if ((PIND & (1<<PD0))) num++; // B rising edge
    else num--;           // B falling edge
  // A raising edge   
  else {
    if ((PIND & (1<<PD0))) num--; // B rising edge
    else num++;           // B falling edge

Will be greatful for inputs toward this endeavour.

use the Encoder library from Library Manager

Juraj: use the Encoder library from Library Manager

Juraj, your pointer leads me neither there nor here, I am nonplussed really.

A simpler way may be to use an accelerated value for the encoder spinning like I described in this blog post a while back.

marco_c: A simpler way may be to use an accelerated value for the encoder spinning like I described in this blog post a while back.

Thanks marco, did go through your blog and the library referred. Let me see if I can adapt your blogs' intent to my code.