7Segment
This little program shows how you can display a four digit number, using four 7 segment displays. The display is updated every 1ms or so. The program was tested on an EasyPIC 5 board with the data lines on PORTD and the enable lines from PORTA.0 to PORTA.3. All you need to do to set a display value is call Display(). Display doesn't actually update the LEDs (this is done in the interrupt routine) but prepares and loads a variable which is used by the OnUpdate() interrupt routine. For example,
Display(100) Display(1234)
Program Code
// set device and clock... Device = 18F452 Clock = 20 // 7 segment display constants (0..9) and TMR1 reload constant... Const Segment() As Byte = ($3F, $06, $5B, $4F, $66, $6D, $7D, $07, $7F, $67), ReloadTimerValue As Word = 65536 - _clock * 250 // timer registers... Dim TMR1 As TMR1L.AsWord, TMR1IF As PIR1.0, TMR1IE As PIE1.0, TMR1ON As T1CON.0, TMR1IP As IPR1.0 // program variables... Dim SegValue As LongWord, SegState As Byte, Index As Word { **************************************************************************** * Name : On Update * * Purpose : This routine triggered every 1ms to update the 7 segment * * : displays * **************************************************************************** } Interrupt OnUpdate() Dim Index As Byte // reload timer value and clear TMR1 flag TMR1 = TMR1 + ReloadTimerValue TMR1IF = 0 // context save the table pointer and decide which of the four // 7 segment displays we are going to update... Save(TABLEPTR) If SegState.3 = 1 Then Index = SegValue.Byte3 ElseIf SegState.2 = 1 Then Index = SegValue.Byte2 ElseIf SegState.1 = 1 Then Index = SegValue.Byte1 ElseIf SegState.0 = 1 Then Index = SegValue.Byte0 EndIf // update segment... PORTA = PORTA And $F0 Or SegState PORTD = Segment(Index) // prepare for next... SegState = SegState >> 1 If SegState = 0 Then SegState = $08 EndIf Restore End Interrupt { **************************************************************************** * Name : Display * * Purpose : Display a word value to 4 seven segment displays. This routine * * : just prepares the number that will be displayed. The actual * * : display code is in the interrupt above * **************************************************************************** } Sub Display(pValue As Word) Disable(OnUpdate) SegValue.Byte3 = pValue / 1000 pValue = pValue Mod 1000 SegValue.Byte2 = pValue / 100 pValue = pValue Mod 100 SegValue.Byte1 = pValue / 10 SegValue.Byte0 = pValue Mod 10 Enable(OnUpdate) End Sub { **************************************************************************** * Name : Initialise * * Purpose : Initialise the program * **************************************************************************** } Public Sub Initialize() // TMR1 setup... TMR1 = ReloadTimerValue T1CON = 0 TMR1IF = 0 TMR1IE = 1 TMR1ON = 1 // clear port... PORTA = $00 PORTD = $00 // set ports to output... TRISA = $F0 TRISD = $00 // set the segment update state variable // and then enable the interrupt... SegState = $08 Enable(OnUpdate) End Sub // program start... Initialize While true Index = 0 Repeat Display(Index) Inc(Index) DelayMS(100) Until Index > 9999 Wend