Mikrobasic, Interrupts en multiplexen

Bavelt

Golden Member

Hij update wel, maar met een tempo van 1 seconde. Ben je wel even bezig met het gelijkzetten...

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Dan staat er toch wat verkeerd, want de repeattime staat op 40mS...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik krijg er nog niet de vinger achter. Het werkt ook nog niet.

In de code staat:

pic basic code:

Const Keytime        = 120             '0.6sec
      Keydebounce    = 10              '40mS
      Keyrpttime     = 10              '40mS
	  
	  
 

Maar als de klokfrequentie 10Mhz is, dan is de instructietijd toch FOsc / 4 = 0,4 uS?.
* 10 zou dat betekenen 10 * 0,4 = 4 Us. Dat is geen 40mS. Waar maak ik de fout?

Daarbij staat ook:

pic basic code:


	  If Button = 0 Then                                              'Button pressed?
      Inc(KeyCount)                                                 'Yes, count + 1
      Select Case KeyCount                                          '
        Case KeyTime                                                'See if it's a nor-
          fKeyRpt  = 1                                              'mal or a repeated
          KeyCount = 0                                              'keypress.
        Case KeyDebounce                                            '
          fUpdate = 1                                               '
          SecCount  = 0                                             '
          Mincount = 0                                              '
        Case KeyRptTime                                             '
          If fKeyRpt Then                                           '
            fUpdate  = 1                                            '
            SecCount  = 0
            MinCount = 0                                             '
            KeyCount = 0                                            '
          End If                                                    '
      End Select                                                    '
    Else                                                            'No key, clear count
      fKeyRpt   = 0                                                 'and flag
      KeyCount  = 0                                                 '
    End If   

Maar Case KeyDebounce en Case KeyRptTime hebben toch dezelfde waarde?

(als je er een literal in zet van 10 pikt de Compiler het ook niet omdat de waarden niet uniek zijn).

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

De timerinterrupt komt iedere 1/250 seconde (4mS)
Tien maal 4mS is 40mS...

De twee tijden staan (toevallig) gelijk, maar hebben niets met elkaar te maken.
De ene is de debounce time en de andere repeat. (tijd tussen twee toetsdetecties tijdens repeat)

[Bericht gewijzigd door Arco op woensdag 11 december 2019 14:05:54 (55%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op 11 december 2019 14:03:27 schreef Arco:
De timerinterrupt komt iedere 1/250 seconde (4mS)
Tien maal 4mS is 40mS...

Daar zat dus de denkfout; de interrupt aanroep met 250Hz. |:(

Maar het ingedrukt houden van de button levert als resultaat dat digit 0 met ca 0,5 seconde interval optelt, terwijl je verwacht dat dat aanzienlijk sneller zou gebeuren.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Als je code overneemt, moet je wel alles doen en niet dingen weglaten... :)

pic basic code:


      Inc(KeyCount)                                                 'Yes, count + 1
      Select Case KeyCount                                          '
        Case KeyTime                                                'See if it's a nor-
          fKeyRpt  = 1                                              'mal or a repeated
          KeyCount = 0                                              'keypress.
        Case KeyDebounce                                            '
          fUpdate = 1                                               '
          SecCount  = 0                                             '
          Mincount = 0                                              '
          If fKeyRpt Then KeyCount = 0 End If                       ' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        Case KeyRptTime                                             '
          If fKeyRpt Then                                           '
            fUpdate  = 1                                            '
            SecCount  = 0
            MinCount = 0                                             '
            KeyCount = 0                                            '
          End If                                                    '
      End Select                                                    '
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Keycount weer op 0...Tja.
Hoe gelukkig kan een mens zijn met een klein dingetje... :D :)

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ondertussen heb ik de frequentie op 10.000 Mhz (ik heb nog geen 8 digit counter om meer precies te worden, komt nog).

Ik kan natuurlijk ook voor iedere digit een micro switch nemen die zijn waarde bepaalt (die 3 extra dingetjes nemen nauwelijks ruimte in beslag). Poorten te over met een 887.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik heb het programma uitgebreid met 4 knopjes. iedere Digit kan nu apart worden ingesteld (bij iedere druk 1 hoger).
Het werkt.

Maar misschien is het wel op een slimmere manier te doen; het is nogal wat code wat erbij komt.
De afvraging van het drukken op een van de druktoetsen, misschien kan dat ook met een interrupt gebeuren?

pic basic code:

 Program MatrixKlok

Dim DigCount   As Byte
    Digit      As Byte[4]
    Seccount   As Byte
    MinCount   As Byte
    KeyCount   As Byte
    Flags      As Byte
    fKeyRpt    As sBit At Flags.0
    fUpdate    As sBit At Flags.1
    fDigit0    As sBit At Flags.2
    fDigit1    As sBit At Flags.3
    fDigit2    As sBit At Flags.4
    fDigit3    As sBit At Flags.5
    Button     As sBit At PORTD.4      'Pin 27

Const Maxdigits      = 4               'Displayed digits
      Keytime        = 120             '0.6sec
      Keydebounce    = 10              '40mS
      Keyrpttime     = 10              '40mS

Dim ClockPin as sbit at PORTC.3        'pin 18
    Latch    as sbit at PORTC.7        'pin 26
    Datapin  as sbit at PORTC.5        'pin 24
    Kolom    as Byte

const font as byte[80] =               'Character tabel, 90 Degrees turn left
(
  0x3c, 0x66, 0x6e, 0x76, 0x66, 0x66, 0x3c, 0x00,
  0x7e, 0x18, 0x18, 0x18, 0x1c, 0x18, 0x18, 0x00,
  0x7e, 0x06, 0x0c, 0x30, 0x60, 0x66, 0x3c, 0x00,
  0x3c, 0x66, 0x60, 0x38, 0x60, 0x66, 0x3c, 0x00,
  0x30, 0x30, 0x7e, 0x32, 0x34, 0x38, 0x30, 0x00,
  0x3c, 0x66, 0x60, 0x60, 0x3e, 0x06, 0x7e, 0x00,
  0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
  0x18, 0x18, 0x18, 0x30, 0x30, 0x66, 0x7e, 0x00,
  0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
  0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00
)

'===============================================================================
Sub Procedure Max_Write(Dim pCol, PDig0, pDig1, pDig2, Pdig3 as Byte)
'===============================================================================
 Latch = 0
 SPI1_Write(pCol)
 SPI1_Write(pDig0)
 SPI1_Write(pCol)
 SPI1_Write(pDig1)
 SPI1_Write(pCol)
 SPI1_Write(pDig2)
 SPI1_Write(pCol)
 SPI1_Write(pDig3)
 Latch = 1
 delay_ms(2)
End sub

'===============================================================================
Sub Procedure Max7219_Init()
'===============================================================================
Max_Write(0x09, 0x00, 0x00, 0x00, 0x00)
Max_Write(0x0B, 0x07, 0x07, 0x07, 0x07)
Max_Write(0x0C, 0x01, 0x01, 0x01, 0x01)
Max_Write(0x0A, 0x01, 0x01, 0x01, 0x01)
End sub

'===============================================================================
Sub Procedure Display_Testen()      'Testen van het display; alle LEDS aan
'===============================================================================
Max_Write(0x0F, 0x01, 0x01, 0x01, 0x01)
DELAY_MS(50)
Max_Write(0x0F, 0x00, 0x00, 0x00, 0x00)
DELAY_MS(50)
End sub

'===============================================================================
Sub Procedure Aanzetten_Leds()      'Leds aanzetten per kolom
'===============================================================================
  For Kolom = 1 TO 8
    Max_Write(Kolom,0xFF,0xFF,0xFF,0xFF)
    delay_ms(100)
  Next Kolom
End sub

'===============================================================================
Sub Procedure Uitzetten_Leds()      'Leds uitzetten per kolom
'===============================================================================
FOR Kolom = 1 TO 8
   Max_Write(Kolom, 0x00, 0x00, 0x00, 0x00)
   delay_ms(100)
NEXT Kolom
End sub

'===============================================================================
Sub Procedure Update_LED            'Update LED
'===============================================================================
     For Kolom = 1 to 8
        Max_Write(Kolom, Font[(Digit[0]<<3) + (Kolom - 1)],
                         Font[(Digit[1]<<3) + (Kolom - 1)],
                         Font[(Digit[2]<<3) + (Kolom - 1)],
                         Font[(Digit[3]<<3) + (Kolom - 1)])
     Next Kolom
End sub

'===============================================================================
sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'===============================================================================
  If TMR2IF_bit Then                                        'See if timer2 irq
    Inc(Seccount)                                           'If so, update coun-
    If Seccount = 250 Then                                  'ters.
      Seccount = 0                                          'Set flag if minute
      Inc(MinCount)                                         'passed.
      If MinCount = 60 Then
         MinCount = 0
         fUpdate = 1                                        'Set Flag to Update LED
      End If
    End If
   '------------------------------------------------------------------------------------
    If Button = 0 Then                                      'Button pressed?
      Inc(KeyCount)                                         'Yes, count + 1
      Select Case KeyCount                                  '
        Case KeyTime                                        'See if it's a nor-
          fKeyRpt  = 1                                      'mal or a repeated
          KeyCount = 0                                       'keypress.
        Case KeyDebounce                                            '
          fUpdate = 1                                               '
          SecCount  = 0                                             '
          Mincount = 0
          if fKeyRpt then KeyCount = 0 End if                       '
        Case KeyRptTime                                             '
          If fKeyRpt Then                                           '
            fUpdate  = 1                                            '
            SecCount  = 0
            MinCount = 0                                             '
            KeyCount = 0                                            '
          End If                                                    '
      End Select                                                    '
    Else                                                            'No key, clear count
      fKeyRpt   = 0                                                 'and flag
      KeyCount  = 0                                                 '
    End If     '
    TMR2IF_bit = 0
  End If
End sub

'===============================================================================
Main:

'===============================================================================
  T2CON      = %00100110                                            'Post:5 - Pre:16
  PR2        = 124                                                  'Timer load value
  ANSEL      = %00000000                                            'All ports digital
  ANSELh     = %00000000                                            '
  TRISC      = %00111101
  TRISB      = %00000000
  TRISD      = %11111111
  PORTD      = %11111111
  fUpdate    = 0
  fDigit3    = 0
  GIE_bit    = 1                                                    'Enable timer2 irq
  PEIE_bit   = 1                                                    '
  TMR2IE_bit = 1                                                    '
                                                                    'Set digits Initial Value
  Digit[0]   = 8                                                    '
  Digit[1]   = 4                                                    '
  Digit[2]   = 1                                                    '
  Digit[3]   = 2

  SPI1_Init()
  Max7219_Init()
  Display_Testen()
  Uitzetten_Leds()
  Update_LED()  
                                                                    '
  '--------------------------------------------------------------------------------------
  While True
     if portd.3 = 0 then                                          'Settings for
       delay_ms(20)                                               'each digit
       if portd.3 = 0 then
         if fDigit3 = 0 then
            fdigit3 = 1
            inc(Digit[3])
            if (Digit[3] > 1) And (Digit[2] > 3) then Digit[3] = 0 Digit[2] = 0 end if
            if Digit[3] = 3 then Digit[3] = 0 end if
            Update_LED()
            portd.3 = 1
            SecCount = 0
         end if
       end if
   else
       fDigit3 = 0
   end if
   
   if portd.2 = 0 then
       delay_ms(20)
       if portd.2 = 0 then
         if fDigit2 = 0 then
            fdigit2 = 1
            inc(Digit[2])
            if (DIgit[3] = 2) AND (Digit[2] = 4) then Digit[2] = 0 end if
            if Digit[2] = 10 then Digit[2] = 0 end if
            Update_LED()
            portd.2 = 1
            SecCount = 0
         end if
       end if
   else
       fDigit2 = 0
   end if
   
   if portd.1 = 0 then
       delay_ms(20)
       if portd.1 = 0 then
         if fDigit1 = 0 then
            fdigit1 = 1
            inc(Digit[1])
            if Digit[1] = 6 then Digit[1] = 0 end if
            Update_LED()
            portd.1 = 1
            SecCount = 0
         end if
       end if
   else
       fDigit1 = 0
   end if

   if portd.0 = 0 then
       delay_ms(20)
       if portd.0 = 0 then
         if fDigit0 = 0 then
            fdigit0 = 1
            inc(Digit[0])
            if Digit[0] = 10 then Digit[0] = 0 end if
            Update_LED()
            portd.0 = 1
            SecCount = 0
         end if
       end if
   else
       fDigit0 = 0
   end if
  
  if fUpdate = 1 then
     Inc(Digit[0])
     If Digit[0] = 10 Then                                          'Update all 4 Digit-
        Digit[0] = 0                                                'values
        Inc (Digit[1])
        If Digit[1] = 6 Then
           Digit[1] = 0
           Inc (Digit[2])
           If Digit[2] = 10 Then
              Digit[2] = 0
              Inc(Digit[3])
           End If
         End If
      End If
      If (Digit[3] = 2) And (Digit[2] = 4) Then                     'If hour '24', reset
          Digit[0]=0    Digit[1]=0    Digit[2]=0    Digit[3]=0      'to 00:00
      End If
    Update_LED()                                                    'Reset flag
    fUpdate = 0                                                     'Reset flag
    fdigit3 = 0
    End if
  Wend
  
  End.
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Dat moet ook in een interrupt, de meest logische keuze...
Ik zie het nut niet erg van 4 drukknoppen? Je zet de klok misschien een paar maal in zijn leven gelijk, met 1 drukker duurt dat misschien een halve minuut...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Dat klopt. Maar het was primair bedoeld als oefening.
Om steeds wat meer vertrouwder te raken met MikroBasic en met het werken met interrupts.

Hoe doe je zoiets op een juiste manier?

Is er - net zoals met de timer (zoals TMR2IF_bit) - ook een register/bit waar je aan kan zien dat de waarde van een poort is veranderd?

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 12 december 2019 00:47:42 schreef Bavelt:

Hoe doe je zoiets op een juiste manier?

Is er - net zoals met de timer (zoals TMR2IF_bit) - ook een register/bit waar je aan kan zien dat de waarde van een poort is veranderd?

Ik ga het eerst zelf bestuderen, ik heb al wat tutorials gevonden omtrent interrupts.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik doe vast wel iets verkeerd..

Na wat studeren dacht ik dat ik hiermee er was om een Led te laten branden op PoortD.5 als PoortB.7 dmv een schakelaar even op 0 wordt gezet.

pic basic code:


'===============================================================================
sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'===============================================================================
if INTCON.INTF = 1 then
  portd.5 = 1
  intcon.intf = 0
else
  portd.5 = 0
end if 

en in de main:

pic basic code:


  GIE_bit      = 1                                                    
  PEIE_bit     = 1                                                    '
  TMR2IE_bit   = 1    
  INTCON. RBIE = 1  
  INTCON.INTF =  0   



  ANSEL      = %00000000         
  ANSELh     = %00000000                                            '
  TRISB      = %10000000
  TRISD      = %11011111
  PORTD      = %00000000
  


   

Gebeurt niks..

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Geheel volgens verwachting... :)

INTF flag is voor de RB0 external interrupt pin, en daar doe je niks mee. Je moet RBIF testen...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

En ik maar denken dat ik het een keer goed had doorgelezen... ;(

Maar inderdaad, intcon.rbif is het.
ik heb al wel gezien dat je dan tevens IOCB.7 = 1 moet opgeven om de change op de Poort aan te zetten.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

is het een goede gewoonte om het terugzetten van de flag in de interrupt routine zélf te doen (als het ware mee afsluiten), of in de main procedure waar na de interrupt naar wordt teruggekeerd?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Altijd in de interruptroutine zelf.
In main kan niet; je weet toch meestal niet dat er een interrupt geweest is? (en je hebt kans dat je interrupts gaat missen)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Vermoedde ik al. Boter bij de vis dus.. ;)

Het is met interrupts op poorten dus wel oppassen, begrijp ik. Zo is bv bij de 887 de interrupts op een poort voorbestemd voor de B-Poort.
Je kan dan dus niet kiezen voor bv de D of C-poort.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

pic basic code:

 sub procedure Interrupt() iv 0x0004 ics ICS_AUTO 

Waar kan ik deze parameters iv 0x0004 ics ICS_AUTO terugvinden?

Is de procedure Interrupt() dan tevens een 'reserved routine?'

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Je kan dan dus niet kiezen voor bv de D of C-poort.

Nee, dan moet je een wat nieuwere pic nemen, die hebben dat wel...
(kun je per pin instellen: interrupt, ST/TTL input, OD output of normaal, slew-rate,...)
Interruptroutines kun je aanmaken met Tools -> Interrupt assistent...

[Bericht gewijzigd door Arco op donderdag 12 december 2019 17:52:35 (13%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Het blijft wat lastig voor me als in de interrupt routine twee(of meer dingen) gebeuren.
Als ik de timer heb, dan treedt die interrupt iedere 1/250 seconde op.
Dan komt er ook nog een interrupt van de buttons tussendoor.
Het werkt wel, maar echt lekker lijkt het me niet. Daarbij is de keydebounce ook nog niet goed. (1 keer drukken moet de bijbehorende digit verhogen en . Dat gebeurt in de Main procedure zoals het hoort.

pic basic code:

 
'===============================================================================
sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'===============================================================================
  if INTCON.RBIF = 1 then
     if portb.3 = 0 then
         for TestByte = 1 to 255 next TestByte        'Loop, soort delay
         if portb.3 = 0  then     'Testen welke B-poort laag is gegaan
           inc(Digit[3])
           fmuteer = 1        'Aparte vlag voor muteren zonder dat timer dat doet
           INTCON.RBIF = 0
         end if
     end if
   end if


'Timer 
If TMR2IF_bit Then                                        'See if timer2 irq
    Inc(Seccount)                                           'If so, update coun-
    If Seccount = 250 Then                                  'ters.
      Seccount = 0                                          'Set flag if minute
      Inc(MinCount)                                         'passed.
      If MinCount = 60 Then
         MinCount = 0
         fUpdate = 1                                        'Set Flag to Update LED
      End If
    End If
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Als je in de interruptroutine zit, kan er op dat moment de procedure opnieuw worden aangeroepen vanwege een nieuwe interrupt?

Want stel dat je in de interrupt routine iets doet wat ca 50 ms doet, als voorbeeld. Normaliter zou iedere 4 ms de interrupt routine worden aangeroepen vanuit de timer.Hoe gaat zoiets dan?

Of maakt hij eerst de routine af alvorens opnieuw kan worden aangeroepen?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Interrups (bij de 16F althans) zijn niet re-entrant.
GIE wordt automatisch gedisabled bij de interrupt call en gere-enabled bij de return. Meerdere interrupts tegelijk kan dus niet.

Ik zie niet in waarom verschillende interrupts een probleem zijn? (kwestie van flags testen en de juiste interrupt uitvoeren)
Ik zou de 4 buttons gewoon in de timerinterrupt afhandelen, is simpeler.

Iets heel traags wat 50mS duurt moet je sowieso niet in een interrupt afhandelen, daar is die niet voor...
(en je gaat interrupts missen)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Nou, het is mooi gelukt allemaal!

4 knopjes in totaal om iedere digit apart te regelen.
Met gebruikmaking van de timer interrupt.
Processor: PIC16F887
Display 4 Matrix LED's 8 * 8 (SPI interface met Max7219)
Taal: MikroBasic

Voor verdere verbetering van de programmacode houd ik me aanbevolen!

pic basic code:

Program MatrixKlok

Dim DigCount   As Byte
    Digit      As Byte[4]
    Seccount   As Byte
    MinCount   As Byte
    KeyCount   As Byte
    Flags      As Byte
    fKeyRpt    As sBit At Flags.0
    fDigit     As Byte                 'Inidcates which Digit has to be updated
    ClockPin as sbit at PORTC.3        'pin 18
    Latch    as sbit at PORTC.7        'pin 26
    Datapin  as sbit at PORTC.5        'pin 24
    Kolom    as Byte
    
Const Keytime        = 120             '0.6sec
      Keydebounce    = 10              '40mS

Const font as byte[80] =               'Character tabel, 90 Degrees turn left
(
  0x3c, 0x66, 0x6e, 0x76, 0x66, 0x66, 0x3c, 0x00,
  0x7e, 0x18, 0x18, 0x18, 0x1c, 0x18, 0x18, 0x00,
  0x7e, 0x06, 0x0c, 0x30, 0x60, 0x66, 0x3c, 0x00,
  0x3c, 0x66, 0x60, 0x38, 0x60, 0x66, 0x3c, 0x00,
  0x30, 0x30, 0x7e, 0x32, 0x34, 0x38, 0x30, 0x00,
  0x3c, 0x66, 0x60, 0x60, 0x3e, 0x06, 0x7e, 0x00,
  0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
  0x18, 0x18, 0x18, 0x30, 0x30, 0x66, 0x7e, 0x00,
  0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
  0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00
)

'===============================================================================
Sub Procedure Max_Write(Dim pCol, PDig0, pDig1, pDig2, Pdig3 as Byte)
'===============================================================================
 Latch = 0
 SPI1_Write(pCol)
 SPI1_Write(pDig0)
 SPI1_Write(pCol)
 SPI1_Write(pDig1)
 SPI1_Write(pCol)
 SPI1_Write(pDig2)
 SPI1_Write(pCol)
 SPI1_Write(pDig3)
 Latch = 1
 delay_ms(2)
End sub

'===============================================================================
Sub Procedure Max7219_Init()
'===============================================================================
Max_Write(0x09, 0x00, 0x00, 0x00, 0x00)
Max_Write(0x0B, 0x07, 0x07, 0x07, 0x07)
Max_Write(0x0C, 0x01, 0x01, 0x01, 0x01)
Max_Write(0x0A, 0x01, 0x01, 0x01, 0x01)
End sub

'===============================================================================
Sub Procedure Display_Testen()      'Testen van het display; alle LEDS aan
'===============================================================================
Max_Write(0x0F, 0x01, 0x01, 0x01, 0x01)
DELAY_MS(50)
Max_Write(0x0F, 0x00, 0x00, 0x00, 0x00)
DELAY_MS(50)
End sub

'===============================================================================
Sub Procedure Aanzetten_Leds()      'Leds aanzetten per kolom (test)
'===============================================================================
  For Kolom = 1 TO 8
    Max_Write(Kolom,0xFF,0xFF,0xFF,0xFF)
    delay_ms(50)
  Next Kolom
End sub

'===============================================================================
Sub Procedure Uitzetten_Leds()      'Leds uitzetten per kolom
'===============================================================================
FOR Kolom = 1 TO 8
   Max_Write(Kolom, 0x00, 0x00, 0x00, 0x00)
   delay_ms(50)
NEXT Kolom
End sub

'===============================================================================
Sub Procedure Update_LED            'Update LED
'===============================================================================
  If (Digit[0] > 9) then Digit[0] = 0 inc (Digit[1]) end if
  If (Digit[1] > 5) then Digit[1] = 0 inc (Digit[2]) end if
  If (Digit[2] > 9) then Digit[2] = 0 inc (Digit[3]) end if
  If (Digit[3] > 2) then Digit[3] = 0 end if
  If (Digit[3] = 2) And (Digit[2] > 3) Then                     'If hour '24',
      Digit[0] = 0  Digit[1] = 0    Digit[2] = 0  Digit[3] = 0  'reset to 00:00
  end if

  For Kolom = 1 to 8
     Max_Write(Kolom, Font[(Digit[0]<<3) + (Kolom - 1)],
                      Font[(Digit[1]<<3) + (Kolom - 1)],
                      Font[(Digit[2]<<3) + (Kolom - 1)],
                      Font[(Digit[3]<<3) + (Kolom - 1)])
  Next Kolom
End sub

'===============================================================================
sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'===============================================================================
  If TMR2IF_bit Then                                    'See if timer2 irq
    Inc(Seccount)                                       'If so, update coun-
    If Seccount = 250 Then                              'ters.
       Seccount = 0                                     'Set flag if minute
       Inc(MinCount)                                    'passed.
       If MinCount = 60 Then
          MinCount = 0
          fDigit = 5                                    'Set Flag to Update LED
       End If
    End If
   '----------------------------------------------------------------------------
    if portb = 255 then                                 'No key pressed
       fKeyRpt = 0 
       KeyCount  = 0 
    Else
       Inc(KeyCount)
         if KeyCount = KeyDebounce then                                           '
            if portb.3 = 0 then FDigit = 4 end if
            if portb.2 = 0 then FDigit = 3 end if
            if portb.1 = 0 then FDigit = 2 end if
            if portb.0 = 0 then FDigit = 1 end if                                   '
            SecCount  = 0                                             '
            Mincount = 0
         End if
    End if                                                 '
   TMR2IF_bit = 0
  End If
End sub

'===============================================================================
Main:

'===============================================================================
  T2CON      = %00100110                                      'Post:5 - Pre:16
  PR2        = 124                                            'Timer load value
  ANSELh     = %00000000                                      'Port B   digital
  TRISC      = %00111101
  TRISB      = %00000000
  PORTB      = %11111111
  fDigit     = 0                                              'FLag Display
  
  GIE_bit    = 1                                              'Enable timer2 irq
  PEIE_bit   = 1
  TMR2IE_bit = 1 

  Digit[0] = 0                                                'Start with 00:00
  Digit[1] = 0
  Digit[2] = 0
  Digit[3] = 0

  SPI1_Init()
  Max7219_Init()
  Display_Testen()
  Uitzetten_Leds()
  Update_LED()

  ' Loop ----------------------------------------------------------------------
  While True
  if fDigit > 0 then
     select case fDigit
     case 1, 2, 3, 4
        Inc (Digit[(fDigit - 1)])
        Update_LED()
     case 5
        Inc(Digit[0])
        Update_Led()
     end select
     Fdigit = 0
  End if
  Wend
  
  End.
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Wat ik mezelf nog even afvroeg:

Welke initiële waarden hebben gedeclareerde variabelen bij de start van het programma als je dat zelf niet opgeeft?
Is dat ongedefinieerd of voegt de compiler daar bv zelf een 0-waarde aan?
(bij een Byte).

Zo maak ik de display's bij start leeg:

pic basic code:

For fDigit = 0 to 5                                         'Start with 00:00
   Digit[fDigit] = 0
  Next fDigit 

Maar wanneer ik dit weglaat begint het ook gewoon met '0'.

Ik neem daarbij aan dat het sowieso een goede gewoonte is de startwaarden op te geven.

Fouten zijn het bewijs dat je het probeert..