Estoy tratando de hacer que PSMC1 en un 16F1782 funcione como un simple generador PWM. He estado golpeando mi cabeza contra la pared durante los últimos días y he pensado que sería mejor que pidiera ayuda.
Estoy utilizando tanto MPLAB 8.92 como MPLAB-X 4.05 con un PICkit3 y el procesador de destino directamente o usando un encabezado de depuración de emulación AC244064 conectado a la placa de destino.
El problema es que el temporizador en el módulo no parece continuar contando. He intentado una variedad de cosas para tratar de resolver esto: puedo pausar la sesión de depuración, precargar el byte alto o bajo del temporizador con algún valor arbitrario y luego reiniciar la sesión de depuración. El temporizador siempre aparece como 0x0001 cuando la sesión de depuración se detiene nuevamente y el bit _PSMC1LD siempre pasa a LO.
He intentado la sincronización de Fosc y el reloj interno de 64 MHz. Fosc es de 4 MHz para este proyecto. Aunque mi tablero está diseñado para usar la salida PSMC1E, también lo he probado con el pin que se muestra en el código de ejemplo: PSMC1A.
Obviamente estoy haciendo algo mal y espero que algún alma amable pueda señalar mi error.
Lo siguiente contiene dos secciones: primero son los valores de registro inicial y definición que escribo en los diversos registros de PSMC durante la inicialización, la segunda sección es la salida de desensamblaje como se muestra en MPLAB-X v4.05. Tenga en cuenta que en el listado de desensamblaje, cada instrucción se muestra dos veces: primero: luego se muestra como está escrito en mi código, luego el código desensamblado
;PSMC CONTROL REGISTER
#define _P1MODE0 PSMC1CON,0 ;0000= 1 PWM 0001= same /w Comp o/p
#define _P1MODE1 PSMC1CON,1 ;0010= PushPull 0011= same /w Comp o/p
#define _P1MODE2 PSMC1CON,2 ;0100= P-P /w 4 o/p 0101= same /w Comp o/p
#define _P1MODE3 PSMC1CON,3 ;0110= PulseSkip PWM 0111= same /w Comp o/p
;1000= ECCP Full Br Rev 1001 same /w For
;1010= Fix DC, Var Freq 1011 same /w Comp o/p
;1100= 3ph PWM 1101, 1110, 1111 reserved
#define _P1DBRE PSMC1CON,4 ;Rise Edge Dead Band Enable 1= Enabled
#define _P1DBFE PSMC1CON,5 ;Fall Edge Dead Band Enable 1= Enabled
#define _PSMC1LD PSMC1CON,6 ;0= Buffer Update done 1= Ready to Update
#define _PSMC1EN PSMC1CON,7 ;Enable: 1= Enabled
PSMC1CON_INIT EQU b'11000000' ;enabled, 1 PWM, load steering & timing regs
;PSMC OUTPUT ENABLE CONTROL
#define _P1OEA PSMC1OEN,0 ;o/p Enable A RC0
#define _P1OEB PSMC1OEN,1 ; B RC1
#define _P1OEC PSMC1OEN,2 ; C RC2
#define _P1OED PSMC1OEN,3 ; D RC3
#define _P1OEE PSMC1OEN,4 ; E RC4
#define _P1OEF PSMC1OEN,5 ; F RC5
PSMC1OEN_INIT EQU b'00010000' ;pin RC4
;PSMC STEERING CONTROL Zero in any bit position (A-F) disables that bit
#define _P1STRA PSMC1STR0,0 ;P1MODE= 000x (1ph) o/p
;P1MODE= 1100 (3ph) A,D HI B,C,E,F LO
#define _P1STRB PSMC1STR0,1 ;P1MODE= 0000 (1ph)
;P1MODE= 0001 (1ph) comp o/p
;P1MODE= 1100 (3ph) A,F HI C,C,D,E LO
#define _P1STRC PSMC1STR0,2 ;P1MODE= 000x (1ph) o/p
;P1MODE= 1100 (3ph) C,F HI A,B,D,E LO
#define _P1STRD PSMC1STR0,3 ;P1MODE= 000O (1ph) o/p
;P1MODE= 0001 (1ph) comp o/p
;P1MODE= 1100 (3ph) B,C HI A,D,E,F LO
#define _P1STRE PSMC1STR0,4 ;P1MODE= 000x (1ph) o/p
;P1MODE= 1100 (3ph) B,E HI A,C,D,F LO
#define _P1STRF PSMC1STR0,5 ;P1MODE= 0000 (1ph) o/p
;P1MODE= 0001 (1ph) comp o/p
;P1MODE= 1100 (3ph) D,E HI A,B,C,F LO
;Note: lowest bit takes precedence for 3ph
PSMC1STR0_INIT EQU b'00010000' ;pin rc4
;PSMC POLARITY CONTROL
#define _P1POLA PSMC1POL,0 ;o/p A Polarity 0= Act HI 1= Act LO
#define _P1POLB PSMC1POL,1 ; B
#define _P1POLC PSMC1POL,2 ; C
#define _P1POLD PSMC1POL,3 ; D
#define _P1POLE PSMC1POL,4 ; E
#define _P1POLF PSMC1POL,5 ; F
#define _P1INPOL PSMC1POL,6 ;PSMC1 i/p Polarity 0= Act HI 1= Act LO
PSMC1POL_INIT EQU b'00000000' ;active HI
;PSMC MODULATION CONTROL
#define _P1MSRC0 PSMC1MDL,0 ;Modulation Source: 0000= P1MDLBIT
#define _P1MSRC1 PSMC1MDL,1 ;0001= C1OUT 0010= C2OUT 0011= C3OUT
#define _P1MSRC2 PSMC1MDL,2 ;1000 reserved 0101= CCP1 0110= CCP2
#define _P1MSRC3 PSMC1MDL,3 ;0111 reserved 1000= PSMC1IN pin
#define _P1MDLBIT PSMC1MDL,5 ;
#define _P1MDLPOL PSMC1MDL,6 ;Mod Select Polarity 0= Mod=1 1= Mod=0
#define _P1MDLEN PSMC1MDL,7 ;Mod enable: 0= No Modulation
;1= active when Mod signal
PSMC1MDL_INIT EQU b'00000000' ;no modulation
;PSMC1 SYNCHRONIZATION CONTROL
#define _P1SYNC0 PSMC1SYNC,0 ;00= Sync /w Period Event 01= reserved
#define _P1SYNC1 PSMC1SYNC,1 ;10= Sync /w PSMC2 module 11= reserved
PSMC1SYNC_INIT EQU b'00000000' ;sync /w period event
;PSMC CLOCK CONTROL
#define _P1CSRC0 PSMC1CLK,0 ;00= Fosc 01= 64MHz
#define _P1CSRC1 PSMC1CLK,1 ;10= PSMC1clk pin 11= reserved
#define _P1CPRE0 PSMC1CLK,4 ;00= Clk /1 01= Clk /2
#define _P1CPRE1 PSMC1CLK,5 ;10= Clk /4 11= Clk /8
PSMC1CLK_INIT EQU b'00000000' ;Fosc /1
;PSMC BLANKING CONTROL
#define _P1REBM0 PSMC1BLNK,0 ;Rise Edge Blanking 00= None 01= Immediate
#define _P1REBM1 PSMC1BLNK,1 ; 10= reserved 11= reserved
#define _P1FEBM0 PSMC1BLNK,4 ;Fall Edge Blanking 00= None 01= Immediate
#define _P1FEBM1 PSMC1BLNK,5 ; 10= reserved 11= reserved
PSMC1BLNK_INIT EQU b'00000000' ;no blanking
;PSMC RISING EDGE BLANKED SOURCE 0= not source of blanking 1= source blanks
#define _P1REBSC1 PSMC1REBS,1 ;Blanked from sync_C1OUT
#define _P1REBSC2 PSMC1REBS,2 ;Blanked from sync_C2OUT
#define _P1REBSC3 PSMC1REBS,3 ;Blanked from sync_C3OUT
#define _P1REBSIN PSMC1REBS,7 ;Blanked from PSMC1IN pin
PSMC1REBS_INIT EQU b'00000000' ;no blanking
;PSMC FALLING EDGE BLANKED SOURCE 0= not source of blanking 1= source blanks
#define _P1FEBSC1 PSMC1FEBS,1 ;Blanked from sync_C1OUT
#define _P1FEBSC2 PSMC1FEBS,2 ;Blanked from sync_C2OUT
#define _P1FEBSC3 PSMC1FEBS,3 ;Blanked from sync_C3OUT
#define _P1FEBSIN PSMC1FEBS,7 ;Blanked from PSMC1IN pin
PSMC1FEBS_INIT EQU b'00000000' ;no blanking
;PSMC PHASE SOURCE (Rise Edge Event) 0 means that signal does NOT cause event
#define _P1PHST PSMC1PHS,0 ;1= Rise Edge Event when PSMCxTMR = PSMCxPH
#define _P1PHSC1 PSMC1PHS,1 ;1= Rise Edge Event when sync_C1OUT goes true
#define _P1PHSC2 PSMC1PHS,2 ;1= Rise Edge Event when sync_C2OUT goes true
#define _P1PHSC3 PSMC1PHS,3 ;1= Rise Edge Event when sync_C3OUT goes true
#define _P1PHSIN PSMC1PHS,7 ;1= Rise Edge Event when PSMC1IN pin goes true
PSMC1PHS_INIT EQU b'00000001' ;from timebase
;PSMC DUTY CYCLE SOURCE (Fall Edge Event) 0 means that signal does NOT cause event
#define _P1DCST PSMC1DCS,0 ;1= Fall Edge Event when PSMCxTMR = PSMCxDC
#define _P1DCSC1 PSMC1DCS,1 ;1= Fall Edge Event when sync_C1OUT goes true
#define _P1DCSC2 PSMC1DCS,2 ;1= Fall Edge Event when sync_C2OUT goes true
#define _P1DCSC3 PSMC1DCS,3 ;1= Fall Edge Event when sync_C3OUT goes true
#define _P1DCSIN PSMC1DCS,7 ;1= Fall Edge Event when PSMC1IN pin goes true
PSMC1DCS_INIT EQU b'00000001' ;from timebase
;PSMC PERIOD SOURCE 0 means that signal does NOT cause event
#define _P1PRST PSMC1PRS,0 ;1= Period Event when PSMCxTMR = PSMCxPR
#define _P1PRSC1 PSMC1PRS,1 ;1= Period Event when sync_C1OUT goes true
#define _P1PRSC2 PSMC1PRS,2 ;1= Period Event when sync_C2OUT goes true
#define _P1PRSC3 PSMC1PRS,3 ;1= Period Event when sync_C3OUT goes true
#define _P1PRSIN PSMC1PRS,7 ;1= Period Event when PSMC1IN pin goes true
PSMC1PRS_INIT EQU b'00000001' ;from timebase
;PSMC AUTO-SHUTDOWN CONTROL ("AS")
#define _P1ASDOV PSMC1ASDC,0 ;AS OverRide: 0= No Effect 1=
#define _P1ARSEN PSMC1ASDC,5 ;AS Auto-Restart 1= auto 0= require restart
#define _P1ASDEN PSMC1ASDC,6 ;AS Enable: 0= No AS 1= Enabled
#define _P1ASE PSMC1ASDC,7 ;AS Status: 0= normal 1= Shutdown occurred
PSMC1ASDC_INIT EQU b'00000000' ;no auto shutdown
;PSMC AUTO-SHUTDOWN OUTPUT LEVEL Sets Pin Level when AutoShutdown occurs
#define _P1ASDLA PSMC1ASDD,0 ;Pin A 0= pin goes LO 1= pin goes HI
#define _P1ASDLB PSMC1ASDD,1 ; B
#define _P1ASDLC PSMC1ASDD,2 ; C
#define _P1ASDLD PSMC1ASDD,3 ; D
#define _P1ASDLE PSMC1ASDD,4 ; E
#define _P1ASDLF PSMC1ASDD,5 ; F
PSMC1ASDD_INIT EQU b'00000000' ;non-active (shutdown) levels all LO (0)
;PSMC AUTO-SHUTDOWN SOURCE 0= signal does NOT cause shutdown 1= signal enabled
#define _P1ASDSC1 PSMC1ASDS,1 ;AS occurs when sync_C1OUT output goes true
#define _P1ASDSC2 PSMC1ASDS,2 ;AS occurs when sync_C2OUT output goes true
#define _P1ASDSC3 PSMC1ASDS,3 ;AS occurs when sync_C3OUT output goes true
#define _P1ASDSIN PSMC1ASDS,7 ;AS occurs when PSMC1IN pin goes true
PSMC1ASDS_INIT EQU b'00000000' ;no auto shutdown
;PSMC TIMEBASE INTERRUPT CONTROL
#define _P1TPRIF PSMC1INT,0 ;1= 16-bit PSMC1TMR matched PSMC1PR<15:0>
#define _P1TDCIF PSMC1INT,1 ;1= 16-bit PSMC1TMR matched PSMC1DC<15:0>
#define _P1TPHIF PSMC1INT,2 ;1= 16-bit PSMC1TMR matched PSMCxPH<15:0>
#define _P1TOVIF PSMC1INT,3 ;1= 16-bit PSMC1TMR overflowed 0xFFFF -> 0x0
#define _P1TPRIE PSMC1INT,4 ;1= TimeBase Period match ints enabled
#define _P1TDCIE PSMC1INT,5 ;1= TimeBase Duty Cycle match ints enabled
#define _P1TPHIE PSMC1INT,6 ;1= TimeBase Phase Match ints enabled
#define _P1TOVIE PSMC1INT,7 ;1= TimeBase overflow ints enabled
PSMC1INT_INIT EQU b'00000000' ;no interrupts
!; Single-phase PWM PSMC setup
!; Fully synchronous operation
!; Period =
!; Duty cycle = 50%
! SETBSR PSMC1CON
0x1DE: MOVLB 0x10
! movlw 0x02 ; set period
0x1DF: MOVLW 0x2
! movwf RBS(PSMC1PRH)
0x1E0: MOVWF PSMC1PRH
! movlw 0x7F
0x1E1: MOVLW 0x7F
! movwf RBS(PSMC1PRL)
0x1E2: MOVWF PSMC1PR
! movlw 0x01 ; set duty cycle
0x1E3: MOVLW 0x1
! movwf RBS(PSMC1DCH)
0x1E4: MOVWF PSMC1DCH
! movlw 0x3F
0x1E5: MOVLW 0x3F
! movwf RBS(PSMC1DCL)
0x1E6: MOVWF PSMC1DC
! clrf RBS(PSMC1PHH) ; no phase offset
0x1E7: CLRF PSMC1PHH
! clrf RBS(PSMC1PHL)
0x1E8: CLRF PSMC1PH
! movlw PSMC1CLK_INIT
0x1E9: MOVLW 0x0
! movwf RBS(PSMC1CLK)
0x1EA: MOVWF PSMC1CLK
!; output on E, normal polarity
! bcf BBS(_P1STRA) ;chip pwr-up default is HI
0x1EB: BCF PSMC1STR0, 0x0
! bsf BBS(_P1STRE)
0x1EC: BSF PSMC1STR0, 0x4
! bcf BBS(_P1POLE)
0x1ED: BCF PSMC1POL, 0x4
! bsf BBS(_P1OEE)
0x1EE: BSF PSMC1OEN, 0x4
!; set time base as source for all events
! bsf BBS(_P1PRST)
0x1EF: BSF PSMC1PRS, 0x0
! bsf BBS(_P1PHST)
0x1F0: BSF PSMC1PHS, 0x0
! bsf BBS(_P1DCST)
0x1F1: BSF PSMC1DCS, 0x0
!; enable PSMC in Single-Phase Mode
!; this also loads steering and time buffers
! movlw PSMC1CON_INIT
0x1F2: MOVLW 0xC0
! movwf RBS(PSMC1CON)
0x1F3: MOVWF PSMC1CON
! SETBSR TRISC
0x1F4: MOVLB 0x1
! bcf BBS(TRISC,4) ; enable pin driver
0x1F5: BCF TRISC, 0x4
!
! rampg0
0x1F6: MOVLB 0x0