Eli haluisin ohjata PWM 16f88 mikro-ohjaimessa 10 bittisesti. Niin että luen tuon piirin A/D-muuntimen tuloksen, joka kyllä onnistuu 10-bittisenä lukea. Mutta sen siirtäminen PWM ei onnistu täysin. Eli 10 bitllä pääsee 1024 asti.
Mutta kun A/D-muuntimeen kytketty potentimetriä vääntää. Niin PWM menee nollaan, kun mennään 255 yli. Eli esim 0-255 ledi kirkastuu. Sitten pimenee josta taas alkaa kirkastua 510 , sitten taas sammuu jne. Aina tuohon 1024 lukemaan asti.
Miksei siis A/D-muuntimen 10 bittinen lukema ei siirry kokonaan PWM? Vaan se menee 255 paloissa.
Jotain koodia asiasta.
Ensin tuon PWM alustus:
ALUSTAPWM
clrf T2CON
clrf TMR2
clrf INTCON
bsf STATUS,RP0
clrf PIE1
bcf STATUS,RP0
clrf PIR1
bsf STATUS,RP0
movlw 0xFF
movwf PR2 ; compare with 255
bcf STATUS,RP0
movlw 0x00
movwf CCPR1L ;Tämä ohjaa toimintajaksoa.
movlw 0x03;
movwf T2CON ; prescaler 1:16 and postscaler 1:1
movlw 0x0C
movwf CCP1CON ;Laitetaan PWM päälle.
bsf T2CON,TMR2ON ; Timeri käyntiin.
return
Sitten lopuksi se, miten siirtelen A/D-muuntimen 10 lukeman tuolle PWM:lle.
LOOP
;
; turn on the ADC module, take a reading, return with 8 most
; signigicant bits of reading in W
;
banksel ADCON0
ADC bsf ADCON0,ADON ; turn on AD module |B0
bcf PIR1,ADIF ; clear AD interrupt flag |B0
movlw d'33' ; use 33 (20 mhz) or 13 (8 mhz) |B0
movwf TEMP ; |B0
ACQ decfsz TEMP,F ; wait 20 usec to acquire |B0
goto ACQ ; |B0
bsf ADCON0,GO_DONE ; start conversion |B0
ADX btfsc ADCON0,GO_DONE ; conversion complete? |B0
goto ADX ; no, loop |B0
banksel ADCON1
bsf ADCON1,ADFM ; Haetaan A/D-muunnos alempitavu.
nop
nop
nop
nop
nop
movf ADRESL,W ; get result low byte |B0
banksel ADCON0
movwf ADL
call ADVIIVE
movf ADRESH,W ; get result high byte |B0
movwf ADH
bcf ADCON0,ADON ; turn off AD module |B0
;Säädetään A/D-muntimelta saatu arvo myös PWM rekistereihin.
clrf TEMP
movlw 0x0C
movwf TEMP ;Laitetaan PWM päälle, muuten se menee pois päältä, kun TEMP rekisteri siirretään CCP1CON rekisteriin.
btfsc ADH,0
bsf TEMP, 4 ;
btfsc ADH,1
bsf TEMP, 5 ;
btfss ADH,0
bcf TEMP, 4 ;
btfss ADH,1
bcf TEMP, 5 ;
movf TEMP,W ;
movwf CCP1CON
nop
nop
nop
nop
nop
movf ADL,W ;
movwf CCPR1L ;Tämä ohjaa toimintajaksoa.
goto LOOP
Eli miten tuon AD-muuntimen 10 bittisen lukeman saa saa toimimaan tuossa PWM myös 10 bittisenä?
Kiitoksia jo mahdollisesti vastauksesta etukäteen.
Mutta kun A/D-muuntimeen kytketty potentimetriä vääntää. Niin PWM menee nollaan, kun mennään 255 yli. Eli esim 0-255 ledi kirkastuu. Sitten pimenee josta taas alkaa kirkastua 510 , sitten taas sammuu jne. Aina tuohon 1024 lukemaan asti.
Miksei siis A/D-muuntimen 10 bittinen lukema ei siirry kokonaan PWM? Vaan se menee 255 paloissa.
Jotain koodia asiasta.
Ensin tuon PWM alustus:
ALUSTAPWM
clrf T2CON
clrf TMR2
clrf INTCON
bsf STATUS,RP0
clrf PIE1
bcf STATUS,RP0
clrf PIR1
bsf STATUS,RP0
movlw 0xFF
movwf PR2 ; compare with 255
bcf STATUS,RP0
movlw 0x00
movwf CCPR1L ;Tämä ohjaa toimintajaksoa.
movlw 0x03;
movwf T2CON ; prescaler 1:16 and postscaler 1:1
movlw 0x0C
movwf CCP1CON ;Laitetaan PWM päälle.
bsf T2CON,TMR2ON ; Timeri käyntiin.
return
Sitten lopuksi se, miten siirtelen A/D-muuntimen 10 lukeman tuolle PWM:lle.
LOOP
;
; turn on the ADC module, take a reading, return with 8 most
; signigicant bits of reading in W
;
banksel ADCON0
ADC bsf ADCON0,ADON ; turn on AD module |B0
bcf PIR1,ADIF ; clear AD interrupt flag |B0
movlw d'33' ; use 33 (20 mhz) or 13 (8 mhz) |B0
movwf TEMP ; |B0
ACQ decfsz TEMP,F ; wait 20 usec to acquire |B0
goto ACQ ; |B0
bsf ADCON0,GO_DONE ; start conversion |B0
ADX btfsc ADCON0,GO_DONE ; conversion complete? |B0
goto ADX ; no, loop |B0
banksel ADCON1
bsf ADCON1,ADFM ; Haetaan A/D-muunnos alempitavu.
nop
nop
nop
nop
nop
movf ADRESL,W ; get result low byte |B0
banksel ADCON0
movwf ADL
call ADVIIVE
movf ADRESH,W ; get result high byte |B0
movwf ADH
bcf ADCON0,ADON ; turn off AD module |B0
;Säädetään A/D-muntimelta saatu arvo myös PWM rekistereihin.
clrf TEMP
movlw 0x0C
movwf TEMP ;Laitetaan PWM päälle, muuten se menee pois päältä, kun TEMP rekisteri siirretään CCP1CON rekisteriin.
btfsc ADH,0
bsf TEMP, 4 ;
btfsc ADH,1
bsf TEMP, 5 ;
btfss ADH,0
bcf TEMP, 4 ;
btfss ADH,1
bcf TEMP, 5 ;
movf TEMP,W ;
movwf CCP1CON
nop
nop
nop
nop
nop
movf ADL,W ;
movwf CCPR1L ;Tämä ohjaa toimintajaksoa.
goto LOOP
Eli miten tuon AD-muuntimen 10 bittisen lukeman saa saa toimimaan tuossa PWM myös 10 bittisenä?
Kiitoksia jo mahdollisesti vastauksesta etukäteen.
Vastaukset 3
Vanhimmat
Aikoihin en ole noiden kanssa pelannut. Muistaakseni tuo data on juurikin 10bit, mutta sitä voitiin lukea vain joko 2 korkeimmalta bitiltä annettiin muuttujalle arvo tai 8 vähiten merkitsevältä annettiin samalle muuttujalle arvo. tjsp.
arvo PWM rekisteriin CCPR1L. Niin että otan tuosta A/D-muuntimen tuottmasta 10 bitistä 8 ylintä bittiä ja siirrän ne tuohon CCPR1L rekisteriin? Niin saa "10 bittisen" PWM-signaalin.
Eli tuota A/D-muuntimen tuottamaa 10 bittisen lukeman kahta ylintä bittiä ei tungetakaan CCP1CON rekisterin 4 ja 5 biteiksi?
CCP1CON rekisteriin tulee kaksi vähiten merkitsevää bittiä ja CCPR1L rekisteriin ylemmät kahdeksan
Tuossa koodissasi se meni juuri päinvastoin, siksi se hyppi...
Allaolevan pitäisi toimia:
-------------------------------------------------
include "P16F88.INC"
TEMP equ 0x20
ADL equ 0x21
ADH equ 0x22
ALUSTAPWM
clrf T2CON
clrf TMR2
clrf INTCON
bsf STATUS,RP0
clrf TRISB
movlw 0xFF
movwf PR2 ; compare with 255
bcf STATUS,RP0
clrf CCPR1L ;Tämä ohjaa toimintajaksoa.
movlw 0x03;
movwf T2CON ; prescaler 1:16 and postscaler 1:1
movlw 0x0C
movwf CCP1CON ;Laitetaan PWM päälle.
bsf T2CON,TMR2ON ; Timeri käyntiin.
;Sitten lopuksi se, miten siirtelen A/D-muuntimen 10 lukeman tuolle PWM:lle.
LOOP
banksel ADCON1
bcf ADCON1,ADFM ;Ylempi tavu -> ADRESH
banksel ADCON0
ADC bsf ADCON0,ADON ;AD moduuli päälle
movlw d'33' ;use 33 (20 mhz) or 13 (8 mhz)
movwf TEMP ;
ACQ decfsz TEMP,F ;wait 20 usec to acquire
goto ACQ
bsf ADCON0,GO_DONE ;Aloitetaan muunnos
ADX btfsc ADCON0,GO_DONE ;Valmis?
goto ADX ;ei, odotetaan
banksel ADCON1
movf ADRESL,W ; Haetaan A/D-muunnos alempitavu (kaksi bittiä).
banksel ADCON0
movwf ADL
movf ADRESH,W ; Haetaan A/D-muunnos ylempitavu
movwf ADH
call ADVIIVE ;Ennen seuraavaa muunnostä pitää odottaa vähintään 2 Tad
bcf ADCON0,ADON ; AD sammuksiin
;Säädetään A/D-muntimelta saatu arvo myös PWM rekistereihin.
bcf CCP1CON, 0x4 ;CCP1CON 2 vähiten merkitsevää tavua
bcf CCP1CON, 0x5
btfsc ADL,0x6
bsf CCP1CON, 0x4;
btfsc ADL,0x7
bsf CCP1CON, 0x5 ;
movf ADH,W ;
movwf CCPR1L ;YLEMPI tavu CCPR1L rekisteriin. Loogista?
goto LOOP
ADVIIVE
movlw 0xff
movwf TEMP
ACQ2 decfsz TEMP,F
goto ACQ2
return
end