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

Dan zal het kloppen :)
Voor het maskeren van bits wordt inderdaad de AND gebruikt.

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 ????