Code

Home Hardware Software Contacts Pictures

Program Code for AT90S2313:

#include <io2313v.h>

#include <macros.h>



// Configuring the Interrupt vector table

 

//  I N T E R R U P T   H A N D L E R

#pragma interrupt_handler Hall_interrupt:2 

#pragma interrupt_handler Degree_interrupt:5 

#pragma interrupt_handler Timer_interrupt:7

// P R O T O T Y P E

void Hall_interrupt(void);

void Degree_interrupt(void);

void Time(unsigned char);

void Timer_interrupt(void);

void Display(void);

void Data(int Value);

void Dot(void);



//   G L O B A L   V A R I A B L E

int Position;

unsigned char Pos;

unsigned int Adder;



unsigned char Sec;

unsigned char Min;

unsigned char Hrs;

unsigned char TimeString[48];
unsigned char *TimeStringPtr;

unsigned char i;



//           C O N S T A N T

const unsigned char table[12][6] = { 

{ 0b00111110, 0b01000001, 0b01000001, 0b01000001, 0b00111110, 0b00000000  }, // 0

{ 0b00000000, 0b00100001, 0b00111111, 0b00000001, 0b00000000, 0b00000000  }, // 1

{ 0b00100001, 0b01000011, 0b01000101, 0b01001001, 0b00110001, 0b00000000  }, // 2 

{ 0b01000010, 0b01000001, 0b01010001, 0b01101001, 0b01000110, 0b00000000  }, // 3

{ 0b00001100, 0b00010100, 0b00100100, 0b01011111, 0b00000100, 0b00000000  }, // 4

{ 0b01110010, 0b01010001, 0b01010001, 0b01010001, 0b01001110, 0b00000000  }, // 5

{ 0b00011110, 0b00101001, 0b01001001, 0b01001001, 0b00000110, 0b00000000  }, // 6

{ 0b01000000, 0b01000111, 0b01001000, 0b01010000, 0b01100000, 0b00000000  }, // 7

{ 0b00110110, 0b01001001, 0b01001001, 0b01001001, 0b00110110, 0b00000000  }, // 8

{ 0b00110000, 0b01001001, 0b01001001, 0b01001010, 0b00111100, 0b00000000  }, // 9

{ 0b00000000, 0b00110110, 0b00110110, 0b00000000, 0b00000000, 0b00000000  }, // :

{ 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000  }};

// space





//**************************************

//            M A I N

//**************************************

void main()

{

WDTCR = 0b00001110;                          // Enable Watch Dog at 0.97 sec

                    

PORTD = 0b00110101;                          // Pull up on PD2 & PD0 blue LED ON

DDRD =   0b00000001;                    	 // PD0-O PD1-I PD2-I PD3-I PD4-I PD5-I PD6-I //PD7-I

                                                                // Configure Port D as output for PD0 and 

                                                               //Input on PD2, all others are unused



//External Interrupt from Hall Sensor positioned at 12:00

MCUCR = 0b00000010;                      // Configure Int0 to generate on falling edge

GIMSK =  0b01000000;                      // Enable Int0 interrupt



//Timer0

TCCR0 = 0b00000101;                       // Prescale : Timer0 / 1024 



//Timer1

TCCR1B = 0b01000010;                     // Timer1 / 8 & Input Capture on Rising edge

TIMSK =   0b01001010;                     // int enable on Timer1 Compare Match 

                                                             // int enable on Timer0 Overflow

PORTB = 0b00000000;                      // no LEDís lit

DDRB =  0b11111111;                       // Configure PB0-7 as output



Hrs = 0;

Min = 0;

Sec = 0;

SEI();



while(1)                                               //infinite loop

               {

               Time();                                 //call time function to increment seconds

}



// Time Handler Ė incrementing and roll over

void Time(void)

{

Sec++;                                                 // increment seconds upon entering the         

                                                             //time function

if (Sec > 59)

   {

   Sec = 0;

   Min++;

   if (Min > 59)

                 {

                 Min = 0;

                 Hrs++;

                 if (Hrs > 11)

                               {

                                Hrs = 0;

                                }

                 }

   }

TimeStringPtr = &TimeString[0];       // Set time string pointer to the 

//address of the first element in the TimeString vector array

// Go to the Data function passing in the parameter hrs,min,sec, array elements are filled with references to 

//character from table

   Data(Hrs);                                         //First 12 elements in Array, 6 per character             

   Dot();                                                //Use next 6 elements, single character for Ď:í

   Data(Min);                                        //Use next 12 elements

   Dot();                                                //Use next 6 elements

   Data(Sec);                                         //Use next 12 elements

   }

}



// void Data:  Function called to store the time data, ie. Hrs, mins, sec in the vector the time string is //pointing to.

//If the value is less than ten,  a zero must first be displayed.



void Data(int Value)

{

if (Value < 10)

   {

   for (i=0;i<6;i++) *TimeStringPtr++ = table[0][i];

   for (i=0;i<6;i++) *TimeStringPtr++ = table[Value][i];

   }

else

   {

   for (i=0;i<6;i++) *TimeStringPtr++ = table[Value/10][i];         

   for (i=0;i<6;i++) *TimeStringPtr++ = table[Value/10 -1)*10)][i];

   }           

}



//void Dot:  Function to place the dots separating hrs, min and sec



void Dot(void)

{

for (i=0;i<6;i++) *TimeStringPtr++ = table[10][i];

}



// Void Display:  This display function clears portb on execution (turns off LEDís) and then calculates //according to position what should be displayed. If the board is in the range of 100-244 degrees then the //LEDís are being lit according the character indicated by the data stored in the TimeString Array.

// For example at 244 degrees the value at TimeString[0] is being display ie. Hours value

// Each of the six vectors that makes up a character are displayed for 3 degrees.



void Display(void)

{

PORTB = 0b00000000;

   Pos = ((Position-100) / 3);              

   if (Pos < 49)       

                 {

                 PORTB = TimeString[48-Pos];

                 }

   }

Position++;

}



// INTERRUPTS

            

// External Interrupt on INT0, PD6.

// Used to keep track of rotational position. This interrupt uses the time to complete one revolution to set up 
//the output compare interrupt that is used to display. References board position from Ď12:00 positioní.  



void Hall_interrupt(void)

{

//Local Variables List



static unsigned int LastCount;

static unsigned int Difference;

static int ClockNow;

static unsigned char Spins



Latch = TCNT1;

Difference = ClockNow - LastCount;  //The difference between times in a complete rotation

LastCount = ClockNow;

Spins++;

if (Spins>250)                                     //if Spins is greater than 250 than the                                     

                              //Variable Adder is updated to stay in tune with the 
                                                           //motor speed.

   {

   Adder = TotalCount / 360;            //Adder contains the time per degree per rotation

   Spins = 0;

   }



Position = 0;                                         //Rotation position is set to zero

OCR1 = ClockNow + Adder;              // Output Compare interrupt is configured to

TIFR |= 0b10000000;                          //interrupt per degree in the rotation and the 

                                                             //program is returned to the display function

Display();

}



//Used to cause an interrupt every degree and then jump to the display function which will light LEDís or 
//not, dependant upon the board position.



void Degree_interrupt(void)

{

OCR1 = TCNT1 + Adder;

Display();

}

//Used to control timing function. Timer0 is prescaled, when it overflows (8 bit counter, overflows every 255 //cycles) this interrupt is called and the variable BitOfSecond is incremented. If this interrupt is called 
//more than 37 times, the time function is incremented resulting in the seconds being incremented.



void Timer_interrupt(void)

{

static unsigned char BitOfSecond;

BitOfSecond++;

if (BitOfSecond > 37)

   {

   Time(FALSE);

   BitOFSecond = 0;

   }

TCNT0 = 0b00000000; // reload counter

}