Hallo,
Ik ben bezig met een pic16f819. Hierbij gebruik ik de pwm uitgang om een waveform te generenen. Hiervoor heb ik timer1 op 320 HZ ingesteld op iedere interrupt van deze timer wil ik de duty cycle aanpassen. De vorm van het signaal heb ik in een (const) array staan. Met een teller die iedere interrupt verhoogt wordt haal ik de juiste waarde uit het array.
Nu heb ik om een compiler die pascal omzet asm. Nu merk ik dat soms erg grof gebeurd. Dit is meestal niet erg maar in de interrupt moet straks veel meer gaan gebeuren dus wil ik mijn code zo klein mogelijk houden. Ik wil dus mijn pascal code zelf omzetten naar asm.
Eigenlijk lukt dat best aardig er is echter een stukje waar ik niet uitkom. Hoe kan ik de waarde van een bepaald adres uitlezen.
Ik ben nu zover dat ik de adres locatie op kan slaan in het fsr register maar wat daarna moet komen ??
pascal code
const waveform: array[0..63] of byte =(60,66,..);
.
.
inc(teller);
value:=waveform[teller and $3F];
CCP1CON.4 := value.0;
CCP1CON.5 := value.1;
CCPR1L:=value shr 2;
asm code
incf _teller,f ; verghoog teller zet op f
movlw $3F ; zet $3F op w
andwf _teller,f ; $3F and teller+1 naar f
movlw #waveform ; zet het adres van waveform op w
addwf _teller,w ; adres van waveform + teller
movwf fsr ; adres waarde naar het fsr register
??
?? ; haal de waarde van het adres
??
?? ; laad het array item w
movwf _temp
bcf CCP1CON,4 ; maak bit 4 en 5 laag
bcf CCP1CON,5
andlw 1 ; het array item and 1
btfss status,z ; is bit 0 1 dan zet bit 4 van CCP1COn
bsf CCP1CON,4
movf _temp,w ; laad het array item
andlw 2 ; het array item and 2
btfss status,z ; is bit 2 1 dan zet bit 5 van CCP1COn
bsf CCP1CON,5
rrf _temp,f
rrf _temp,w
andlw $3F
movwf CCPR1L
Is er iemand die mij hiermee kan helpen
Het FSR-register heb je hierbij niet nodig.
Op de plaats van je vraagteken komt een call instructie die naar de tabel verwijst.
de tabel ziet er bijvoorbeeld zo uit:
Lookup movlw HIGH 7segm_codetable ;get high byte of table data address
movwf PCLATH ; and save in PCLATH register
movfw DISPL_VALUE
7segm_codetable addwf PCL,F ; compute goto
RETLW d'63' ; 0, 1, 2, 3
RETLW d'6'
RETLW d'91'
RETLW d'79'
RETLW d'102' ; 4, 5, 6
RETLW d'109'
RETLW d'125'
RETLW d'7' ; 7, 8, 9
RETLW d'127'
RETLW d'103'
RETLW d'119' ; A, B, C
RETLW d'124'
RETLW d'57'
RETLW d'94' ; D, E, F
RETLW d'121'
RETLW d'113'
BTW, je gebruikt een aantal maal de AND-instructie, waarschijnlijk moet dat de ADD zijn?
AND is een logische bewerking en ADD is optellen.
Bedankt,
Ik sanp wat je bedoeld hoe ik het moet implementeren nog niet maar ik zal een s wat proberen.
wat de add versus and betreft ik gebruik add voor optellen en and bij het maskeren van bits, volgens mij (en mijn tests tot nu toe) klopt het, maar als je kunt aangeven waar het volgens jouw niet klopt of beter kan dan hoor ik het graag
Mijn tabel ziet er als volgt uit
[/code]
table__waveform: ;adress = 0088
RETLW 60
RETLW 66
RETLW 72
RETLW 78
.
.
RETLW 72
RETLW 66
RETURN
[/code]
hoe moet ik deze aanroepen immers ik heb het adres (0x88) al in fsr staan maar
call fsr
movfw PCLATH
werkt niet, ook
call table__waveform
movfw PCLATH
geeft niet het goede resultaat. Heeft iemand een voorbeeld voor mij
Op microchip.com kun je ook info vinden over tabellen aanroepen.
Het is de bedoeling dat je de hele tabel een naam geeft en apart wegzet aan het begin van een page in het program memory.
Mijn tabel heet Lookup.
In mijn hoofdprogrammma geef ik de instructie "call Lookup".
In Lookup wordt in de eerste 2 instructies de PCLATH op de juiste waarde geladen.
Dan wordt de sprongwaarde "DISP-VALUE" in w geladen
Dit getal wordt met ADDWF PCL,f opgeteld bij de waarde van de program counter zodat naar de juiste plaats in de tabel wordt gesprongen.
Met RETLW.. wordt teruggesprongen uit de tabel naar het hoofdprogramma naar de plek direct na de call-instructie.
In w bevindt zich nu de waarde die uit de tabel is gehaald.
Oke ik snap het (een beetje)
Aangezien ik niet de volledige controle over de asm code heb (dit iv.m. mijn compiler die ook een hoop goede dingen doet) heb ik wat moeten improviseren.
Als ik mijn code gewoon in het hoofd programma uitvoer gaat alles goed
Ik heb een lookup label gemaakt welke de data uit de tabel haalt. Ik kan deze helaas niet boven in main programma plaatsen omdat dat wordt overschreven door mijn compiler. Daarom heb ik het volgende gedaan in mijn hoofdprogramma
//normale pascal code.
asm
bcf status,z ; maak zero status nul
btfss status,z ; controleer of dit zo is (natuurlijk is dat zo)
goto Normal ; gan naar normaal
Lookup: ; dit wordt enkel uitgevoer bij een expliciete call naar lookup
MOVWF PCL
RETURN
Normal: ; rest van de code volgt hier
Wanneer ik nu mijn waveform generator code direct in het hoofdprogramma uitvoer (dus na het label Normal) gaat alles goed. Maar ik wil deze code in de interrupt uit laten voeren
code van de interrupt routine
asm
btfss Pir1,TMR1IF ; check of de interrupt van timer1 is
goto L2
bcf Pir1,TMR1IF ; clear de interrupt
MOVLW 231 ; preload timer 1 met de juiste waarden
MOVWF TMR1H
MOVLW 150
MOVWF TMR1L
bcf CCP1CON,4 ; maak bit 4 en 5 laag
bcf CCP1CON,5
INCF _counter, w ;increase the counter
andlw $3F ; maskeer bit 6 en 7
addlw #waveform ;verkrijg het adres van de waveform tabel
call lookup ;haal de juiste waarde op
// na de call moet het programma hier terugkeren, maar helaas
movwf _temp
andlw 1 ; het array item and 1
btfss status,z ; is bit 0 1 dan zet bit 4 van CCP1COn
bsf CCP1CON,4
movf _temp,w ; laad het array item
andlw 2 ; het array item and 2
btfss status,z ; is bit 2 1 dan zet bit 5 van CCP1COn
bsf CCP1CON,5
rrf _temp,f
rrf _temp,w
andlw $3F
movwf CCPR1L
movf PORTB,W ;lees portb zet op w
xorlw $04 ;Xor portb met $04 (enkel bit 2)
movwf PORTB ;zet portb
L2:
end;
Wat moet ik nu doen om vanuit de call weer terug te keren in de interrupt ????
