//**************************************************************** // MULTLED.C Driving a multiplexed 7-Segment LED display // // // Version: 1.1 // // // By: J. Winpenny // // Date: 15/12/03 // // //**************************************************************** #define COMMON_CATHODE_LED // ***** #define COMMON_ANODE_LED ******* #define LED_SEGMENT_PORT PORTD // Set PORT selecting LED segments #define LED_MULTIPLEX_PORT PORTC // Set PORT for multplexing digits #define NUM_LEDS 4 // Set number of LEDs connected //*********************************** // PORT Connections for LED //*********************************** // Segment of LED //*********************************** // g f e d c b a // // Bit position 6 5 4 3 2 1 0 //*********************************** #define COUNT_INTERVAL 4500 // Set Count rate #define COM_RELOAD 1 #define TIMER_BIT 0x01 char TRISC@0x87; char TRISD@0x88; char PORTD@0x08; unsigned char cTimerFlag; unsigned char sLedArray[NUM_LEDS]; unsigned int iCountIntervalTimer; unsigned char cLedPos; void UpdateLEDs( void ); void DriveLED( unsigned char cData, unsigned char cNumber ); void IncrementDisplayedNumber(void); void interrupt( void ) { if ( ( INTCON & 0x04 ) != 0 ) // If the TIMER0 times-out { cTimerFlag = 1; if ( iCountIntervalTimer != 0 ) iCountIntervalTimer--; // Increment count timer TMR0 = COM_RELOAD; clear_bit( INTCON, T0IF ); } } void main(void) { char c; //******************************************** // Target specific setup TRISC = 0; // Set PORT C to all outputs TRISD = 0; // Set PORT D to all outputs //******************************************** cTimerFlag = 0; // Reset the timer iCountIntervalTimer = 0; // Initialise LED to display ZERO for( c=0; c< NUM_LEDS; c++ ) sLedArray[c] = 0; while(1) { if ( cTimerFlag ) // when the timer times out { // update the display cTimerFlag &= ~TIMER_BIT; // Reset timer flag // Increment the value displayed // when the larger timer times out if ( iCountIntervalTimer == COUNT_INTERVAL ) { IncrementDisplayedNumber(); iCountIntervalTimer = 0; } UpdateLEDs(); // Update the Multiplexed display } } } //************************************************** // Increment the number displayed on the LEDs //************************************************** void IncrementDisplayedNumber(void) { char c; char cTmp; //char *p; No pointer on C2C char cRollover = 0; //p = sLedArray; for ( c=0; c < NUM_LEDS; c++) { cTmp = sLedArray[c]; if ( ( cTmp + (1 + cRollover) ) > 9 ) { sLedArray[c] = 0; cRollover = 1; } else { sLedArray[c] = sLedArray[c] + 1 + cRollover; } //p++; } } //************************************************** // Update the LED display //************************************************** void UpdateLEDs( void ) { if ( cLedPos > NUM_LEDS-1 ) cLedPos = 0; // Test for max LED number DriveLED( sLedArray[cLedPos], cLedPos ); // Update the display for the // this digit. cLedPos++; // Next LED } //************************************************** // Display a number 0 - 9 ( binary ) on a 7 SEG LED //************************************************** void DriveLED( unsigned char cData, unsigned char cNumber ) { unsigned char cTmp; #ifdef COMMON_CATHODE_LED char CommonCathode7SEG[] = { 0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67 }; #endif #ifdef COMMON_ANODE_LED char CommonAnode7SEG[] = { 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x18 }; #endif typedef unsigned char DIGIT_POSITION_TYPE; enum DIGIT_POSITION_TYPE { ZERO = 0x01, ONE = 0x02, TWO = 0x04, THREE = 0x08, FOUR = 0x10, FIVE = 0x20, SIX = 0x40, SEVEN = 0x80 } DIGIT_POSITION_TYPE cDigitSel; cDigitSel = cNumber; // Obtain select bit patern for LED number n #ifdef COMMON_CATHODE_LED LED_MULTIPLEX_PORT = cDigitSel; // Select the LED required #endif #ifdef COMMON_ANODE_LED LED_MULTIPLEX_PORT = ~DigitSel; #endif if ( Number < 10 ) // So we don't exceed the array bounds { // Select segments for cData #ifdef COMMON_CATHODE_LED LED_SEGMENT_PORT = CommonCathode7SEG[Number]; #endif #ifdef COMMON_ANODE_LED LED_SEGMENT_PORT = CommonAnode7SEG[Number]; #endif } }