PIC 16F887 en MikroBasic

Je leest gewoon de pin status uit. Als die als output staat, zul je die (met de schakelaar) met geweld naar beneden trekken.
Dat vinden de output drivers niet fijn (die proberen de pin hoog te houden), maar ze overleven het meestal wel...

Hier dacht ik aan. Ik mocht met S1 de zaak niet naar 0 trekken.

Nee, een uitgang mag je uiteraard niet extern naar boven of beneden trekken, dan gaat de boel kapot.
Latch = 1 is niet extern, maar intern. Een uitgang zou ook weinig zin hebben als je 'm niet hoog of laag kan maken... ;)

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Tja,
Ik dacht of je het nu met eens schakelaar doet of logisch, om het even.
Niet dus.

Maar goed, het werkt nu.

Wel nog een apart iets (ben ik inmiddels kampioen in geworden vrees ik).

Normaal begint het programma na programmeren door de Pickit3 meteen te lopen.

In dit geval met de Max-en eraan, moet ik na het programmeren de MCLR even naar 0 zetten (met een schakelaar).
Dan pas begint het te lopen.

Is wel mee te leven, maar wel weer anders dan anders.

Zal wel een kwestie van te korte wachttijd zijn. Power-up timer altijd aan zetten en een korte wachttijd van 100mS na een reset/opstart.
In- of extern een uitgang hoog/laag maken is natuurlijk heel wat verschillends. Als de micro de pin hoog trekt en jij maakt 'm extern laag dan blaas je de boel op.
Aan een ingang valt intern helemaal niks laag of hoog te maken...

[Bericht gewijzigd door Arco op 4 november 2019 01:04:20 (46%)]

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Power-Up timer was het inderdaad.

Ik loop weer tegen iets 'raars' op.

Ik heb een programmaatje dat 2 matrix led's aanstuurt die allebei de cijfers 0 t/m 9 tonen. Puur om mee te testen.
De cijfers worden getoond.

De procedure karakters() regelt het. Nu is het vreemde, dat ik daar een while true --- wend loop in heb.
Hierbinnen is wederom een while -- wend. Als z1 de waarde 9 bereikt, dan gaat hij het hele programma weer opnieuw uitvoeren vanaf main:
dus alle procedures weer opnieuw.

Maar dat kan toch niet, want uit een while - true loop kan hij toch in principe nooit komen?

pic basic code:

Program Matrix

Dim ClockPin as sbit at PORTC.3
DIM Latch as sbit at PORTC.7
DIM Datapin as sbit at PORTC.5

Dim Kolom as Byte
Dim Inhoud1 as Byte
Dim Inhoud2 as Byte
Dim Tel as Word

Dim i1 as byte
Dim j1 as word
dim z1 as byte

const font as byte[80] =
(
        0x00, 0x7C, 0xFE, 0xB2, 0x9A, 0x8E, 0xFE, 0x7C,        ' Char 048 (0)
        0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x40, 0x00,        ' Char 049 (1)
        0x00, 0x00, 0x62, 0xF2, 0x92, 0x9A, 0xCE, 0x46,        ' Char 050 (2)
        0x00, 0x00, 0x6C, 0xFE, 0x92, 0x92, 0xC6, 0x44,        ' Char 051 (3)
        0x00, 0x08, 0xFE, 0xFE, 0xC8, 0x68, 0x38, 0x18,        ' Char 052 (4)
        0x00, 0x00, 0x9C, 0xBE, 0xA2, 0xA2, 0xE6, 0xE4,        ' Char 053 (5)
        0x00, 0x00, 0x0C, 0x9E, 0x92, 0xD2, 0x7E, 0x3C,        ' Char 054 (6)
        0x00, 0x00, 0xE0, 0xF0, 0x9E, 0x8E, 0x80, 0x80,        ' Char 055 (7)
        0x00, 0x00, 0x6C, 0xFE, 0x92, 0x92, 0xFE, 0x6C,        ' Char 056 (8)
        0x00, 0x00, 0x78, 0xFC, 0x96, 0x92, 0xF2, 0x60         ' Char 057 (9)
)
'==========================================

Sub Procedure Max_Write_2()
Latch = 0
SPI1_Write(Kolom)
SPI1_Write(Inhoud1)
SPI1_Write(Kolom)
SPI1_Write(Inhoud2)
Latch = 1
end sub

Sub Procedure Max7219_Init()
                                    'Hier worden de registers geïnitialiseerd
Kolom = $09                         'Decode Mode Register:
Inhoud1 = $00   
Inhoud2 = $00                       'Code B for digits
Max_Write_2 ()

Kolom = $0B                         'Scan-Limit Register:
Inhoud1 = $07
Inhoud2 = $07                       'Digit 0,1,2,3,4,5,6,7 ($00-$07)
Max_Write_2()

Kolom = $0C                         'Shutdown Register:
Inhoud1 = $01
Inhoud2 = $01                       'Normal Operation
Max_Write_2()

Kolom = $0A                         'Intensity Register
Inhoud1 = $01
Inhoud2 = $01
Max_Write_2()
delay_ms(500)
end sub

'==========================================
Sub Procedure Display_Testen()      'Testen van het display; alle LEDS aan

Kolom = $0F
Inhoud1 = $01
Inhoud2 = $01
Max_Write_2()
DELAY_MS(1000)

Kolom = $0F                         'Weer terugzetten naar normal operation
Inhoud1 = $00
Inhoud2 = $00
Max_Write_2()
DELAY_MS(1000)
end sub

Sub Procedure Uitzetten_Leds()
'leds uitzetten per kolom

FOR i1 = 1 TO 8
  Kolom = i1
  Inhoud1 = 0
  Inhoud2 = 0
  Max_Write_2()
  Delay_Ms(20)
NEXT i1
end sub

Sub Procedure Karakters()
i1 = 0
while true
j1 = 0
z1 = 0
   while z1 < 10
     for Kolom = 1 to 8
         Inhoud1 = font[j1]
         Inhoud2 = font[i1]
         Max_Write_2()
         delay_ms(10)
         j1 =  j1 + 1
         i1 = i1 + 1
      next Kolom
      delay_ms(1000)
      z1 = z1 + 1
   wend
      delay_ms(2500)
      i1 = i1 + 8
wend

end sub

main:

delay_ms(100)

'        76543210
TRISC = %01011011

 SPI1_Init()
 Max7219_Init()
 Display_Testen()
 Uitzetten_Leds()
 Karakters()

While true wend
END. 

Ik heb de code iets anders gemaakt (geen dubbel while).
Maar met een for --- next loop.

Testen via een Ledje toont aan dat wanneer z1 > 9 wordt, het programma compleet uit de procedure springt en weer vanaf main: start.

pic basic code:

 Sub Procedure Karakters()
i1 = 0
while true
lab3:

   j1 = 0
   z1 = 0
   for z1 = 0 to 9
     for Kolom = 1 to 8
         Inhoud1 = font[j1]
         Inhoud2 = font[i1]
         Max_Write_2()
         delay_ms(10)
         j1 =  j1 + 1
         i1 = i1 + 1
     next Kolom
     delay_ms(250)
   next z1
   delay_ms(100)
   i1 = i1 + 8
   goto lab3
wend
end sub 

Je hebt nu een loop binnen een loop: die zou ik eerst weghalen...
Je hebt WHILE TRUE...WEND (wat nooit wordt uitgevoerd), en daarbinnen LAB3:...GOTO LAB3 wat precies hetzelfde doet.

(Die GOTO's komen er bij mij echt niet in, omdat 't niet nodig is en gauw een rommeltje wordt.)
Een WHILE TRUE...WEND kun je zeker wel verlaten, met een BREAK...

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Ik heb zelf ook een hekel aan goto's en probeer ze altijd te vermijden. Maar deed het even om te achterhalen waar het nu fout gaat.

Maar alle statements tussen de While en Wend worden toch uitgevoerd omdat dit een oneindige loop is?

Ik heb geen Break erin gezet, maar toch vliegt hij uit de procedure.

Tja,

't Is inderdaad vreemd. Ik zou in ieder geval die lab3: goto lab3 weghalen...
Ik maak de meest complexe programma's ermee en heb nog nooit zoiets meegemaakt... :)

(maar ik doe wel niet zulke vreemde dingen als jij: een eindeloze loop in een subroutine is niet normaal natuurlijk...)

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Een goede kanshebber is ook dat de stack crasht. Al gekeken bij View -> Statistics -> Functions tree?
(daar kun je zien hoe diep elke functie de stack gebruikt, de 887 heeft 8 levels)

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Ik heb de goto's verwijderd en geen oneindige loop meer in de subroutine.
Wel een geneste for - next maar dat is volgens mij wel netjes.

Je wilt 8 kolommen aansturen, met 9 cijfers en dat allemaal 9 keer.

pic basic code:

Sub Procedure Karakters()
i1 = 0
j1 = 0
z1 = 0

for Tel = 0 to 9
    for z1 = 0 to 9
        for Kolom = 1 to 8
            Inhoud1 = font[j1]
            Inhoud2 = font[i1]
            Max_Write_2()
            j1 = j1 + 1
            i1 = i1 + 1
        next Kolom
        delay_ms(500)
    next z1
next Tel
End sub  

Het effect is dat wanneer z1 de waarde 9 heeft bereikt, hij uit de subroutine springt en alles wordt herstart vanaf MAIN:

Een goede kanshebber is ook dat de stack crasht. Al gekeken bij View -> Statistics -> Functions tree?
(daar kun je zien hoe diep elke functie de stack gebruikt, de 887 heeft 8 levels)

Je moet wel de subroutines aanklikken om wat te zien...

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Heb ik gedaan.
Volgens mij ziet dat er wel goed uit. Toch?

Het is inderdaad dat hij niet alleen uit de routine springt, maar de MC reset en herstart het programma.

Het is inderdaad iets met de geneste for - next (of andere loop) in de subroutine.

Want wanneer ik het anders doe:

pic basic code:

for Tel = 0 to 9 
   Karakters()
next Tel
 

en hiermee één loop uit de sub haal dan gaat het wel goed.

Je kunt BOR (config) nog uitzetten, misschien dat de reset daardoor komt...

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Arco... je verdient een pluim voor uw geduld :)

LDmicro user.

Ik ben er inmiddels achter. Het had niks te maken met for - next of andere loops.
Er zat een fout in de logica.

Het ging fout bij

pic basic code:

Inhoud2 = font[i1]  

De waarde van de index i1 wordt dermate hoog dat hij uit de constanten-tabel vliegt. Dan refereert de index naar een deel van het programmageheugen of een ander gedefiniëerd of gereserveerd gebied, met rare resultaten tot gevolg. Zoals het resetten van de PIC.

Arco... je verdient een pluim voor uw geduld :)

Ik zou zeggen maak er maar een lintje van! ;)
Geweldig!

De 887 is een oud beestje, heeft geen LATx registers...

Onlangs noemde je (Arco) de PIC 16F1709 en PIC16F1769.

Zit er nog een logische lijn in de de ontwikkeling van PIC's van Microchip?

Bijvoorbeeld: is de 1769 nieuwer dan bv de 1827?

Wat heet logisch?... ;)
Diverse verschillende micro's hebben ook verschillende peripherals. De 1769 is vrij compleet:

- PWM heeft uitgebreide mogelijkheden.
- Heeft twee 10 bit en twee 5 bit DA converters.
- Heeft een PPS (heel handig!...)
- Heeft CLC's (logic cells)
- Twee i/o pins die 100mA kunnen leveren.
- Zero-cross detector
- Twee OPA's (opamps)
- DSM (modulator voor o.a. FSK)

Enige storende is (zoals ik in een andere post meldde) dat je beide oscillatoren niet tegelijk kunt gebruiken... :(

Arco - "Simplicity is a prerequisite for reliability" - www.arcovox.com

Werderom dank, Arco.
De 1769 is bij Farnell gewoon goedkoop te noemen.

Ik probeerde onlangs te zoeken in de posts (bijvoorbeeld waar jij een site gaf met voorbeelden van MikroBasic), maar als je een trefwoord ingeeft bij zoeken, dan krijg je het topic waar het woord in voorkomt. Maar als dat topic uit veel posts bestaat, dan wordt het lastig.

Of kan je toch ergens 'doorscrollen' naar de gevonden trefwoorden binnen de posts?