In een ander artikel las ik dat de instructietijd = 4 / oscillatorfrequentie.
Instructieclock is oscillatorfrequentie / 4...
( sysclock >> 2 is hetzelfde als sysclock / 4 )
Special Member
In een ander artikel las ik dat de instructietijd = 4 / oscillatorfrequentie.
Instructieclock is oscillatorfrequentie / 4...
( sysclock >> 2 is hetzelfde als sysclock / 4 )
Golden Member
Ik heb het programmaatje wat versimpeld zodat er een knipperfrequentie overblijft van ca 1 sec.
Het lukt nu allemaal. Het blijft wel even wennen bij het maken van loops en condities, omdat door bijvoorbeeld de Decfsz er één statement wordt overgeslagen.
Er is geen end if of wat daar op lijkt, waarmee je een aantal statements zou kunnen vangen in het blok (zoals in basic).
In plaats daarvan moet het dan worden opgevangen met goto's.
Ik heb het nu zo:
pic asm code:
;**********************************************************************
#include <p16f1827.inc> ;processor specific variable definitions
__CONFIG _CONFIG1, _FOSC_XT & _WDTE_OFF & _BOREN_OFF & _PWRTE_ON & _CP_OFF & _CPD_OFF & _MCLRE_OFF & _IESO_ON
__CONFIG _CONFIG2, _LVP_OFF & _PLLEN_OFF & _BORV_19
ErrorLevel - 302
;**********************************************************************
org 00h ;beginadres kiezen
banksel TRISA ;kies bank 1
clrf TRISA ;alles pinnen poort A uitgang maken
CBLOCK 0X20
Count1 ; delen door 250
Count2 ; delen door 200
Count3 ; delen door 4
ENDC
knipper
banksel LATA
movf LATA,w ;laad 01h in W
xorlw 1
movwf LATA ;zet de waarde van W
call delay_1sec
goto knipper
Delay_1sec ;delen door 4*200*250 = 200.000
movlw d'4'
movwf count3
loop1
movlw d'200'
movwf count2
loop2
movlw d'250'
movwf count1
loop3
nop
nop
decfsz count1,f
goto loop3
decfsz count2,f
goto loop2
decfsz count3,f
goto loop1
return
END
Special Member
MPSIM is heel handig om timeloops te bestuderen, kun je stap voor stap of animated er doorheen lopen...
Er zweven wel hulpfiles met macro's rond die FOR/WHILE/DO/SELECT CASE functionaliteit bieden, zoals ENGR2210.INC (een keer getest en werkt, maar ik gebruik 't niet)
Golden Member
Bij nieuwe projecten wordt de vraag gesteld of het 'absolute' of 'relocatable' moet worden gebuild.
Wat is aanbevelenswaardig?
Special Member
Golden Member
Op 6 november 2019 16:12:56 schreef Arco:
Hier heb ik al eens een leuk voorbeeld gegeven in assembly: een 4 digit led klok met gelijkzetmogelijkheid in maar 171 words geheugen...
https://www.circuitsonline.net/forum/view/message/2107242#2107242
Ik heb geen 648A. De uitdaging is om dit aan de praat te krijgen met een PIC16F628A.
Beiden lijken veel op elkaar als ik in de datasheets kijk, zij het dat de 648A meer Flash geheugen heeft zo te zien.
De displays lichten echter niet op.
(connecties / aansluitingen zijn goed, een testprogrammaatje toont dit aan).
Ik gebruik een extern kristal van 4 Mhz.
Special Member
Zou gewoon moeten werken. Je moet wel de clock goedzetten met _FOSC_XT. (staat op externe oscillator 10MHz)
Voor 4 MHz moet je dan
code:
banksel pr2 ;Timer 2 value
movlw d'124'
movwf pr2
veranderen in
code:
banksel pr2 ;Timer 2 value
movlw d'49'
movwf pr2
Je kunt ook de 1827 code gebruiken. (die heb je toch ook?)
Golden Member
Ik heb er voor alle zekerheid een 10Mhz kristal in gedaan en de oude waarden laten staan.
Maar help niet.
Het programma lijkt niet te 'lopen'; zo staan alle Poorten B op 0, net zoals de vier 'driver' Poorten A3 t/m A0.
De MCLR is hoog, met een pull-up naar de +5V.
Special Member
Zoals gezegd, hij staat op externe oscillator, dus geen kristal. Voor 10MHz moet je die op _FOSC_HS zetten...
Werkt hier prima met een 628a/648a/1827
Hexfile voor de 628a attached.
Golden Member
Nu weer even terug naar MikroBasic om 7-segment displays te multiplexen.
Ik tel tot 59 met 1 seconde als telfrequentie.
Op zich lukt dat wel, maar ik worstel alleen nog even met de vraag waar je nu de delay van 1000 ms neerlegt.
Onderstaand programma telt tot 59, maar je ziet de displays maar in een flits van 5ms vanwege de delay_ms(5).
Verhoog ik die delay, dan krijg je knipperen als effect.
Eigenlijk zou je de display loop continue willen laten lopen voor een strak beeld, maar hoe krijg je er dan in dat je per seconde de waarden ververst?
pic basic code:
program LedBasic
' Declarations section
Const Cijfer as Byte [10] = (63, 6, 91, 79, 102, 109, 125, 7, 127, 111)
Const Disp as Byte [4] = (1, 2, 4, 8)
Dim Inhoud as Byte[4]
Dim D1 as byte
Dim D2 as byte
Dim X1 as byte
sub procedure Tonen()
for x1 = 0 to 1
Portb = Inhoud[x1]
Porta = Disp[x1]
delay_ms(5)
Porta = %00000000
next x1
end sub
main:
trisa = %00000000
porta = %00000000
trisb = %00000000
portb = %00000000
while true
For D2 = 0 to 5
Inhoud[1] = Cijfer[D2]
For D1 = 0 to 9
delay_ms(1000)
Inhoud[0] = Cijfer[D1]
Tonen()
Next D1
Next D2
wend
end.
Special Member
Eigenlijk heb je voor nette timing interrupts nodig zoals in mijn klok voorbeeld...
Belangrijkste is dat je alle displays om de beurt even lang laat zien. En dat met een snelheid hoger als een mens kan waarnemen.
(in mijn klok voorbeeld is de multiplexrate 250Hz, dwz. elk display is 1/250 seconde aan)
Golden Member
Jawel,
Maar als je ergens een delay inbouwt van 1 sec, dan wordt de subroutine Tonen pas om de seconde aangeroepen. En zie je daardoor maar heel even de displays oplichten.
Special Member
Je moet ook 250x per seconde van display wisselen, niet 1 seconde lang hetzelfde display... Dus:
- Disp1 aan, 4mS wachten, disp1 uit.
- Disp2 aan, 4mS wachten, disp2 uit.
- Disp3 aan, 4mS wachten, disp3 uit.
- Disp4 aan, 4mS wachten, disp4 uit.
- Disp1 aan, 4mS wachten, disp1 uit.
...
...
Golden Member
Dat was dus inderdaad de truc.
Het MikroBasic programma werkt nu.
Misschien wel niet helemaal zuiver qua tijd: 4 display's met een vertraging van 1ms 250 keer laten knipperen levert in principe 1000ms op.
Daarbij is de tijd die nodig is voor het aansturen van de displays niet meegeteld (wellicht valt dat mee).
In ieder geval hier mijn programma. (Wie had dat kunnen denken nog geen 2 maanden geleden...)
pic basic code:
program LedBasic
' Declarations section
Const Cijfer as Byte [10] = (63, 6, 91, 79, 102, 109, 125, 7, 127, 111)
Const Disp as Byte [4] = (1, 2, 4, 8)
Dim Inhoud as Byte[4]
Dim D1 as byte
Dim D2 as byte
Dim D3 as byte
Dim D4 as byte
Dim X1 as byte
Dim T1 as byte
sub procedure Tonen()
For T1 = 1 to 250
For X1 = 0 to 3
Portb = Inhoud[x1]
Porta = Disp[x1]
delay_ms(1)
Porta = %00000000
Next X1
Next t1
end sub
main:
trisa = %00000000
porta = %00000000
trisb = %00000000
portb = %00000000
while true
For D4 = 0 to 5
Inhoud[3] = Cijfer[D4]
For D3 = 0 to 9
Inhoud[2] = (Cijfer[D3] OR %10000000)
For D2 = 0 to 5
Inhoud[1] = Cijfer[D2]
For D1 = 0 to 9
Inhoud[0] = Cijfer[D1]
Tonen()
Next D1
Next D2
Next D3
Next D4
wend
end.