Here is the code:
#include <stdio.h>
#include <TimerOne.h>Â
// Each segment is defined as a single bit value of '1' in a byte. Bit positions are mapped to pin numbers,
// Bit 7 represents pin 11 running down to bit 0 representing pin 4.
const byte SegG = B10000000; // G = pin 11
const byte SegF = B01000000; // F = pin 10
const byte SegA = B00100000; // A = pin 09
const byte SegB = B00010000; // B = pin 08
const byte SegE = B00001000; // E = pin 07
const byte SegD = B00000100; // D = pin 06
const byte SegC = B00000010; // C = pin 05
const byte SegDP =B00000001; // DP = pin 04
// Individual segment definitions are 'OR'ed to make up the digit definitions. These are then negated so that a '1' means off and
// '0' means on. This is so that when a '0' is written to a pin output, i.e. a particular segment needs to be turned on,
// the pin acts like a sink and draws current to drive the individual LED. This is particular to the display used, which uses a common anode
// where LED current needs to be sunk.
const byte Digit0 = ~( SegA | SegB | SegC | SegD | SegE | SegF);
const byte Digit1 = ~( SegB | SegC);
const byte Digit2 = ~( SegA | SegB | SegD | SegE | SegG );
const byte Digit3 = ~( SegA | SegB | SegC | SegD | SegG );
const byte Digit4 = ~( SegB | SegC | SegF | SegG );
const byte Digit5 = ~( SegA | SegC | SegD | SegF | SegG );
const byte Digit6 = ~( SegA | SegC | SegD | SegE | SegF | SegG );
const byte Digit7 = ~( SegA | SegB | SegC );
const byte Digit8 = ~( SegA | SegB | SegC | SegD | SegE | SegF | SegG );
const byte Digit9 = ~( SegA | SegB | SegC | SegD | SegF | SegG );
byte Digits[]={Digit0,Digit1,Digit2,Digit3,Digit4,Digit5,Digit6,Digit7,Digit8,Digit9};
// Definitions for interrupt pins
#define BUTT_STEP 3 // Stepper start/stop switch interrupt pin
#define ESTOP 2 // Emergency stop interrupt. e.g. safety door opened.
// Definitions for Analog port pins
#define ENC_A 14Â Â Â // Encoder input A
#define ENC_B 15Â Â Â // Encoder input B
#define BUTT_LED 16Â // Power for button LED
#define SWCH_DIR 17Â // Switch input for direction
#define DIR 18Â Â Â Â // Output for direction input to microstepping drive
#define PUL 19Â Â Â Â // Output for frequency input to microstepping drive
#define ENC_PORT PINC // Analog port
void setup()
{
Â
//Â Serial.begin(115200);
//Â Serial.println("Start");
Â
Â
 // Set display pins for sinking current.
 for( byte n=4;n<=11;n++)
 {
  pinMode(n, OUTPUT);Â
  digitalWrite(n,HIGH);
 }
Â
 // Setup stepper start/stop button
 pinMode(BUTT_STEP, INPUT);
 digitalWrite(BUTT_STEP, HIGH);
 attachInterrupt(1, StartStopPressed, FALLING);
 // Setup emergency stop interrupt
 pinMode(ESTOP, INPUT);
 digitalWrite(ESTOP, HIGH);
 attachInterrupt(0, EmergencyStop, FALLING);
Â
 // Setup encoder pins as inputs
 pinMode(ENC_A, INPUT);
 digitalWrite(ENC_A, HIGH);
 pinMode(ENC_B, INPUT);
 digitalWrite(ENC_B, HIGH);
 //Setup button LED power pin
 pinMode(BUTT_LED, OUTPUT);
 digitalWrite(BUTT_LED, LOW);
Â
 //Setup direction switch pin
 pinMode(SWCH_DIR, INPUT);
 digitalWrite(SWCH_DIR, HIGH);
 //Setup direction output pin
 pinMode(DIR, OUTPUT);
 digitalWrite(DIR, LOW);
 //Setup frequency output pin
 pinMode(PUL, OUTPUT);
 digitalWrite(PUL, LOW);
Â
 //Display initial splash screen on startup
 Splash();
Â
 PrintDigit(0);
}
int Digit = 0;
volatile boolean MotorRun = false;
// The code in the loop() funtion constantly polls a rotary encoder and displays a user selected
// number on a 7 segment display until an interrupt occurs on the motor start/stop pin.
void loop()
{
Â
// The following is code to read a rotary encoder ( slighty modified to suit ) and is borrowed from here:
// http://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino
static int enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
static int tmpdata;
static int counter = 0;Â Â Â //this variable will be changed by encoder input
static uint8_t old_AB = 0;
 if(!MotorRun) // Allow user to change speed only when motor is stopped.
 {
  old_AB <<= 2;         //remember previous state
  old_AB |= ( ENC_PORT & 0x03 ); //add current state
  tmpdata = enc_states[( old_AB & 0x0f )];
  if( tmpdata )
   counter += tmpdata ;
// End borrowed code....
 if( counter == 4 ) // Counter has rotated one 'notch' clockwise
 {
  counter=0;
  if( Digit <9 )
  {
   Digit++;
   PrintDigit(Digit);
  }
 }
 if( counter == -4 ) // Counter has rotated one 'notch' anti-clockwise
 {
  counter=0;
  if( Digit >0 )
  {
   Digit--;
   PrintDigit(Digit);
  }
 }
 }
Â
}
// Display start up animation
void Splash()
{
const byte x = 60;
 for( int n=0;n<=1;n++)
 {
 PrintBits(SegA);
 delay(x);
 PrintBits(SegA | SegB );
 delay(x);
 PrintBits(SegA | SegB | SegC );
 delay(x);
 PrintBits(SegA | SegB | SegC | SegD );
 delay(x);
 PrintBits(SegA | SegB | SegC | SegD | SegE );
 delay(x);Â
 PrintBits(SegA | SegB | SegC | SegD | SegE | SegF);
 delay(x);
 PrintBits(SegB | SegC | SegD | SegE | SegF);
 delay(x);
 PrintBits(SegC | SegD | SegE | SegF);
 delay(x);
 PrintBits(SegD | SegE | SegF);
 delay(x);
 PrintBits(SegE | SegF);
 delay(x);
 PrintBits(SegF);
 delay(x);Â
 }Â
Â
 PrintBits(B00000000);
 delay(50);
}
//Display an arbitrary pattern
void PrintBits( byte Bits )
{
 Bits=~Bits;
 for( int n=7;n>=0;n--)
 {
 digitalWrite(n+4,bitRead(Bits,n));
 }
}
// Display a digit
void PrintDigit( byte digit )
{
 for( int n=7;n>=0;n--)
 {
 digitalWrite(n+4,bitRead(Digits[digit],n));
 }
}
// Interrupt routine called when stop/start button is pressed
void StartStopPressed()
{
 // Insert debounce handler here...... //
Â
 if ( !MotorRun )
 {
  MotorRun = true;
  digitalWrite(BUTT_LED, HIGH);      // Turn on button LED
  digitalWrite(DIR,digitalRead(SWCH_DIR)); // Set motor direction to selected direction
  Timer1.initialize(2200/(Digit+1));    // Set Timer for 1/2 desired frequency. Here it is set for around 900Hz on display speed setting '0'
  Timer1.attachInterrupt(Pulse);      // Start motor
 }
 else
 {
  Timer1.detachInterrupt();  // Stop motor
  digitalWrite(PUL, LOW);
  digitalWrite(BUTT_LED, LOW); // Turn off button LEDÂ
  MotorRun = false; Â
 }
}Â
//Timer1 interrupt routine. Each call toggles the designated frequency output pin. Minimum practical half cycle for stepper motor = around 10uS.
void Pulse()
{
 PORTC = PINC ^ B00100000 | B00001011; // Toggle frequency output pin using XOR preserving the pullup status of the rotary encoder and direction input pins.
}
void EmergencyStop()
{
  Timer1.detachInterrupt();  // Stop motor
  digitalWrite(PUL, LOW);
  digitalWrite(BUTT_LED, LOW); // Turn off button LED
  MotorRun = false;
}
A brief explanation of the program: The user selects a stepper speed from 0-9 using a rotary encoder and selects direction with a toggle switch. The main loop is dedicated to polling the encoder and updating the single digit seven segment display. I wanted to use interrupts for the button because I wanted to ensure that polling the encoder was a fast as it could be so that user input wasn't missed. I haven't tried a debounce routine alongside the polling routine for this reason. Maybe it would work fine, I just had it in my head that using interrupts would be tidier...