www.pudn.com > ucosii_block.rar > LED.C


/* 
********************************************************************************************************* 
*                                    Embedded Systems Building Blocks 
*                                 Complete and Ready-to-Use Modules in C 
* 
*                                     Multiplexed LED Display Driver 
* 
*                            (c) Copyright 1999, Jean J. Labrosse, Weston, FL 
*                                           All Rights Reserved 
* 
* Filename   : LED.C 
* Programmer : Jean J. Labrosse 
********************************************************************************************************* 
*                                              DESCRIPTION 
* 
* This module provides an interface to a multiplexed "8 segments x N digits" LED matrix. 
* 
* To use this driver: 
* 
*     1) You must define (LED.H): 
* 
*        DISP_N_DIG          The total number of digits to display (up to 8) 
*        DISP_N_SS           The total number of seven-segment digits in the display (up to 8) 
*        DISP_PORT_DIG       The address of the DIGITS   output port 
*        DISP_PORT_SEG       The address of the SEGMENTS output port 
* 
*     2) You must allocate a hardware timer which will interrupt the CPU at a rate of at least: 
* 
*        DISP_N_DIG * 60  (Hz) 
* 
*        The timer interrupt must vector to DispMuxISR (defined in LED_IA.ASM).  You MUST write the 
*        code to clear the interrupt source.  The interrupt source must be cleared either in DispMuxISR 
*        or in DispMuxHandler(). 
* 
*     3) Adapt DispInitPort(), DispOutSeg() and DispOutDig() for your environment. 
********************************************************************************************************* 
*/ 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                              INCLUDE FILES 
********************************************************************************************************* 
*/ 
 
#include "includes.h" 
 
/* 
********************************************************************************************************* 
*                                            LOCAL VARIABLES 
********************************************************************************************************* 
*/ 
 
static   INT8U  DispDigMsk;                 /* Bit mask used to point to next digit to display         */ 
static   INT8U  DispSegTbl[DISP_N_DIG];     /* Segment pattern table for each digit to display         */ 
static   INT8U  DispSegTblIx;               /* Index into DispSegTbl[] for next digit to display       */ 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                             ASCII to SEVEN-SEGMENT conversion table 
*                                                             a 
*                                                           ------ 
*                                                        f |      | b 
*                                                          |  g   | 
* Note: The segments are mapped as follows:                 ------ 
*                                                        e |      | c 
*        a    b    c    d    e    f    g                   |  d   | 
*        --   --   --   --   --   --   --   --              ------ 
*        B7   B6   B5   B4   B3   B2   B1   B0 
********************************************************************************************************* 
*/ 
 
const INT8U DispASCIItoSegTbl[] = {    /* ASCII to SEVEN-SEGMENT conversion table                      */ 
    0x00,                              /* ' '                                                          */ 
    0x00,                              /* '!', No seven-segment conversion for exclamation point       */ 
    0x44,                              /* '"', Double quote                                            */ 
    0x00,                              /* '#', Pound sign                                              */ 
    0x00,                              /* '$', No seven-segment conversion for dollar sign             */ 
    0x00,                              /* '%', No seven-segment conversion for percent sign            */ 
    0x00,                              /* '&', No seven-segment conversion for ampersand               */ 
    0x40,                              /* ''', Single quote                                            */ 
    0x9C,                              /* '(', Same as '['                                             */ 
    0xF0,                              /* ')', Same as ']'                                             */ 
    0x00,                              /* '*', No seven-segment conversion for asterix                 */ 
    0x00,                              /* '+', No seven-segment conversion for plus sign               */ 
    0x00,                              /* ',', No seven-segment conversion for comma                   */ 
    0x02,                              /* '-', Minus sign                                              */ 
    0x00,                              /* '.', No seven-segment conversion for period                  */ 
    0x00,                              /* '/', No seven-segment conversion for slash                   */ 
    0xFC,                              /* '0'                                                          */ 
    0x60,                              /* '1'                                                          */ 
    0xDA,                              /* '2'                                                          */ 
    0xF2,                              /* '3'                                                          */ 
    0x66,                              /* '4'                                                          */ 
    0xB6,                              /* '5'                                                          */ 
    0xBE,                              /* '6'                                                          */ 
    0xE0,                              /* '7'                                                          */ 
    0xFE,                              /* '8'                                                          */ 
    0xF6,                              /* '9'                                                          */ 
    0x00,                              /* ':', No seven-segment conversion for colon                   */ 
    0x00,                              /* ';', No seven-segment conversion for semi-colon              */ 
    0x00,                              /* '<', No seven-segment conversion for less-than sign          */ 
    0x12,                              /* '=', Equal sign                                              */ 
    0x00,                              /* '>', No seven-segment conversion for greater-than sign       */ 
    0xCA,                              /* '?', Question mark                                           */ 
    0x00,                              /* '@', No seven-segment conversion for commercial at-sign      */ 
/*$PAGE*/ 
    0xEE,                              /* 'A'                                                          */ 
    0x3E,                              /* 'B', Actually displayed as 'b'                               */ 
    0x9C,                              /* 'C'                                                          */ 
    0x7A,                              /* 'D', Actually displayed as 'd'                               */ 
    0x9E,                              /* 'E'                                                          */ 
    0x8E,                              /* 'F'                                                          */ 
    0xBC,                              /* 'G', Actually displayed as 'g'                               */ 
    0x6E,                              /* 'H'                                                          */ 
    0x60,                              /* 'I', Same as '1'                                             */ 
    0x78,                              /* 'J'                                                          */ 
    0x00,                              /* 'K', No seven-segment conversion                             */ 
    0x1C,                              /* 'L'                                                          */ 
    0x00,                              /* 'M', No seven-segment conversion                             */ 
    0x2A,                              /* 'N', Actually displayed as 'n'                               */ 
    0xFC,                              /* 'O', Same as '0'                                             */ 
    0xCE,                              /* 'P'                                                          */ 
    0x00,                              /* 'Q', No seven-segment conversion                             */ 
    0x0A,                              /* 'R', Actually displayed as 'r'                               */ 
    0xB6,                              /* 'S', Same as '5'                                             */ 
    0x1E,                              /* 'T', Actually displayed as 't'                               */ 
    0x7C,                              /* 'U'                                                          */ 
    0x00,                              /* 'V', No seven-segment conversion                             */ 
    0x00,                              /* 'W', No seven-segment conversion                             */ 
    0x00,                              /* 'X', No seven-segment conversion                             */ 
    0x76,                              /* 'Y'                                                          */ 
    0x00,                              /* 'Z', No seven-segment conversion                             */ 
    0x00,                              /* '['                                                          */ 
    0x00,                              /* '\', No seven-segment conversion                             */ 
    0x00,                              /* ']'                                                          */ 
    0x00,                              /* '^', No seven-segment conversion                             */ 
    0x00,                              /* '_', Underscore                                              */ 
    0x00,                              /* '`', No seven-segment conversion for reverse quote           */ 
    0xFA,                              /* 'a'                                                          */ 
    0x3E,                              /* 'b'                                                          */ 
    0x1A,                              /* 'c'                                                          */ 
    0x7A,                              /* 'd'                                                          */ 
    0xDE,                              /* 'e'                                                          */ 
    0x8E,                              /* 'f', Actually displayed as 'F'                               */ 
    0xBC,                              /* 'g'                                                          */ 
    0x2E,                              /* 'h'                                                          */ 
    0x20,                              /* 'i'                                                          */ 
    0x78,                              /* 'j', Actually displayed as 'J'                               */ 
    0x00,                              /* 'k', No seven-segment conversion                             */ 
    0x1C,                              /* 'l', Actually displayed as 'L'                               */ 
    0x00,                              /* 'm', No seven-segment conversion                             */ 
    0x2A,                              /* 'n'                                                          */ 
    0x3A,                              /* 'o'                                                          */ 
    0xCE,                              /* 'p', Actually displayed as 'P'                               */ 
    0x00,                              /* 'q', No seven-segment conversion                             */ 
    0x0A,                              /* 'r'                                                          */ 
    0xB6,                              /* 's', Actually displayed as 'S'                               */ 
    0x1E,                              /* 't'                                                          */ 
    0x38,                              /* 'u'                                                          */ 
    0x00,                              /* 'v', No seven-segment conversion                             */ 
    0x00,                              /* 'w', No seven-segment conversion                             */ 
    0x00,                              /* 'x', No seven-segment conversion                             */ 
    0x76,                              /* 'y', Actually displayed as 'Y'                               */ 
    0x00                               /* 'z', No seven-segment conversion                             */ 
}; 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                             HEXADECIMAL to SEVEN-SEGMENT conversion table 
*                                                             a 
*                                                           ------ 
*                                                        f |      | b 
*                                                          |  g   | 
* Note: The segments are mapped as follows:                 ------ 
*                                                        e |      | c 
*        a    b    c    d    e    f    g                   |  d   | 
*        --   --   --   --   --   --   --   --              ------ 
*        B7   B6   B5   B4   B3   B2   B1   B0 
********************************************************************************************************* 
*/ 
 
const INT8U DispHexToSegTbl[] = {      /* HEXADECIMAL to SEVEN-SEGMENT conversion table                */ 
    0xFC,                              /* '0'                                                          */ 
    0x60,                              /* '1'                                                          */ 
    0xDA,                              /* '2'                                                          */ 
    0xF2,                              /* '3'                                                          */ 
    0x66,                              /* '4'                                                          */ 
    0xB6,                              /* '5'                                                          */ 
    0xBE,                              /* '6'                                                          */ 
    0xE0,                              /* '7'                                                          */ 
    0xFE,                              /* '8'                                                          */ 
    0xF6,                              /* '9'                                                          */ 
    0xEE,                              /* 'A'                                                          */ 
    0x3E,                              /* 'B', Actually displayed as 'b'                               */ 
    0x9C,                              /* 'C'                                                          */ 
    0x7A,                              /* 'D', Actually displayed as 'd'                               */ 
    0x9E,                              /* 'E'                                                          */ 
    0x8E                               /* 'F'                                                          */ 
}; 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                          CLEAR THE DISPLAY 
* 
* Description: This function is called to clear the display. 
* Arguments  : none 
* Returns    : none 
********************************************************************************************************* 
*/ 
 
void  DispClrScr (void) 
{ 
    INT8U i; 
 
 
    for (i = 0; i < DISP_N_DIG; i++) {           /* Clear the screen by turning OFF all segments       */ 
        OS_ENTER_CRITICAL(); 
        DispSegTbl[i] = 0x00; 
        OS_EXIT_CRITICAL(); 
    } 
} 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                      DISPLAY DRIVER INITIALIZATION 
* 
* Description : This function initializes the display driver. 
* Arguments   : None. 
* Returns     : None. 
********************************************************************************************************* 
*/ 
 
void  DispInit (void) 
{ 
    DispInitPort();                    /* Initialize I/O ports used in display driver                  */ 
    DispDigMsk   = 0x80; 
    DispSegTblIx = 0; 
    DispClrScr();                      /* Clear the Display                                            */ 
} 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                        DISPLAY NEXT SEVEN-SEGMENT DIGIT 
* 
* Description: This function is called by DispMuxISR() to output the segments and select the next digit 
*              to be multiplexed.  DispMuxHandler() is called by DispMuxISR() defined in LED_IA.ASM 
* Arguments  : none 
* Returns    : none 
* Notes      : - You MUST supply the code to clear the interrupt source.  Note that with some 
*                microprocessors (i.e. Motorola's MC68HC11), you must clear the interrupt source before 
*                enabling interrupts. 
********************************************************************************************************* 
*/ 
 
void  DispMuxHandler (void) 
{ 
                                                 /* Insert code to CLEAR INTERRUPT SOURCE here         */ 
 
    DispOutSeg(0x00);                            /* Turn OFF segments while changing digits            */ 
    DispOutDig(DispDigMsk);                      /* Select next digit to display                       */ 
    DispOutSeg(DispSegTbl[DispSegTblIx]);        /* Output digit's seven-segment pattern               */ 
    if (DispSegTblIx == (DISP_N_DIG - 1)) {      /* Adjust index to next seven-segment pattern         */ 
        DispSegTblIx =    0;                     /* Index into first segments pattern                  */ 
        DispDigMsk   = 0x80;                     /* 0x80 will select the first seven-segment digit     */ 
    } else { 
        DispSegTblIx++; 
        DispDigMsk >>= 1;                        /* Select next digit                                  */ 
    } 
} 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                         CLEAR STATUS SEGMENT 
* 
* Description: This function is called to turn OFF a single segment on the display. 
* Arguments  : dig   is the position of the digit where the segment appears (0..DISP_N_DIG-1) 
*              bit   is the segment bit to turn OFF (0..7) 
* Returns    : none 
********************************************************************************************************* 
*/ 
 
void  DispStatClr (INT8U dig, INT8U bit) 
{ 
    OS_ENTER_CRITICAL(); 
    DispSegTbl[dig] &= ~(1 << bit); 
    OS_EXIT_CRITICAL(); 
} 
 
 
/* 
********************************************************************************************************* 
*                                           SET STATUS SEGMENT 
* 
* Description: This function is called to turn ON a single segment on the display. 
* Arguments  : dig   is the position of the digit where the segment appears (0..DISP_N_DIG-1) 
*              bit   is the segment bit to turn ON (0..7) 
* Returns    : none 
********************************************************************************************************* 
*/ 
 
void  DispStatSet (INT8U dig, INT8U bit) 
{ 
    OS_ENTER_CRITICAL(); 
    DispSegTbl[dig] |= 1 << bit; 
    OS_EXIT_CRITICAL(); 
} 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                            DISPLAY ASCII STRING ON SEVEN-SEGMENT DISPLAY 
* 
* Description: This function is called to display an ASCII string on the seven-segment display. 
* Arguments  : dig   is the position of the first digit where the string will appear: 
*                        0 for the first  seven-segment digit. 
*                        1 for the second seven-segment digit. 
*                        .  .   .     .     .      .      . 
*                        .  .   .     .     .      .      . 
*                        DISP_N_SS - 1 is the last seven-segment digit. 
*              s     is the ASCII string to display 
* Returns    : none 
* Notes      : - Not all ASCII characters can be displayed on a seven-segment display.  Consult the 
*                ASCII to seven-segment conversion table DispASCIItoSegTbl[]. 
********************************************************************************************************* 
*/ 
 
void  DispStr (INT8U dig, char *s) 
{ 
    INT8U stat; 
 
 
    while (*s && dig < DISP_N_SS) { 
        OS_ENTER_CRITICAL(); 
        stat              = DispSegTbl[dig] & 0x01;                  /* Save state of B0 (i.e. status) */ 
        DispSegTbl[dig++] = DispASCIItoSegTbl[*s++ - 0x20] | stat; 
        OS_EXIT_CRITICAL(); 
    } 
} 
 
/*$PAGE*/ 
#ifndef CFG_C 
/* 
********************************************************************************************************* 
*                                        I/O PORTS INITIALIZATION 
* 
* Description: This is called by DispInit() to initialize the output ports used in the LED multiplexing. 
* Arguments  : none 
* Returns    : none 
* Notes      : 74HC573  8 bit latches are used for both the segments and digits outputs. 
********************************************************************************************************* 
*/ 
 
void  DispInitPort (void) 
{ 
    outp(DISP_PORT_SEG, 0x00);              /* Turn OFF segments                                       */ 
    outp(DISP_PORT_DIG, 0x00);              /* Turn OFF digits                                         */ 
} 
 
 
/* 
********************************************************************************************************* 
*                                        DIGIT output 
* 
* Description: This function outputs the digit selector. 
* Arguments  : msk    is the mask used to select the current digit. 
* Returns    : none 
********************************************************************************************************* 
*/ 
 
void  DispOutDig (INT8U msk) 
{ 
    outp(DISP_PORT_DIG, msk); 
} 
 
 
/* 
********************************************************************************************************* 
*                                        SEGMENTS output 
* 
* Description: This function outputs seven-segment patterns. 
* Arguments  : seg    is the seven-segment pattern to output 
* Returns    : none 
********************************************************************************************************* 
*/ 
 
void  DispOutSeg (INT8U seg) 
{ 
    outp(DISP_PORT_SEG, seg); 
} 
#endif