SegCount

SwordfishUser.SegCount History

Hide minor edits - Show changes to output

March 05, 2008, at 04:02 PM by David Barker -
Added lines 1-128:
%lfloat% http://www.sfcompiler.co.uk/wiki/uploads/DavidBarker/led00.gif
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,

=code [=
Display(100) 
Display(1234)
=]

!!!Program Code
=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
=]