News:

Let's find out together what makes a PIC Tick!

Main Menu

Help with hpwm for pic16f18855, it doesn't work

Started by jam19857, Sep 27, 2022, 12:06 PM

Previous topic - Next topic

jam19857

Hello, do you have an example with hpwm for pic16f18855? I have used pic18f26k22 with 5 PWM and it works very well but for pic16f18855 I can't make it work. Could you help me?

HAL

Hi jam19857
Unfortunately, I do not have an example.

There is a footnote for the 16F18855 that mentions:  "Note: The corresponding TRIS bit must be cleared to enable the PWM output on the PWMx pin".   Just in case you have missed it..
 
Regards Hal

Stephen Moss

The names of the registers used to set up the PWM and the functions of the bits within them may be different between the devices and so would need altering accordingly, so first compare the datasheets of the two devices and make any necessary adjustmets to your code.

Then if you are still having problems it would help if you posted the code you have as that would make it easier for people to identify where the problem lies, otherwise how can you expect people to have any concept of what/where the issue may be with nothing to go on other than "it does not work".

John Lawton

Yes, please post your register configurations. This device looks a bit different to the '26K22 so a close study of the PWM section of the datasheet is advised.

top204

#4
I'm afraid Microchip have caught me out with this device family as well with their peripheral changes, but only in the 16F188xx series of them. :-(

I've had to create a brand new library subroutine within the compiler to cater for the extra bit they have added in the timer select mechanism they use in that particular device family.

I don't have any of those devies but I have simulated the new library code in the latest Proteus because it has added them into it, and it works like a charm now.

I have an update nearly ready, so I will add this to it as well and upload it ASAP.

You can create a procedure library for the CCP peripherals operating as PWM and use that instead, which is actually a better method than the compiler's HPWM comand, because it has to do things that are not always required, everytime it is called. Whereas a dedicated procedure library can set up the timer once, and set the CCP peripheral to PWM modeonce, then just change the duty cycle when required, instead of what the HPWM command has to do and alter everything whenever it is used in program, whether they have previously been set or or not.

jam19857

Thank you very much everyone for answering, I will wait for the next update, thank you very much Less for your compiler it is powerful and great. I wish you good health and continue with your work.

Make an example code and manage to configure the pwm works with 3 PWM at the same frequency, I leave the code.

Device 16F18855
Declare Xtal 20

TRISA = 0
TRISB = 0
TRISC = 0

PORTA = 0
PORTB = 0
PORTC = 0


Symbol LED = PORTB.0

RC2PPS = 0X09   ; selecion del PPS para el CCP1
RC1PPS = 0X0A   ; selecion del PPS para el CCP2
RB5PPS = 0X0B   ; selecion del PPS para el CCP3
'RC2PPS = 0X0C   ; selecion del PPS para el CCP4
'RC2PPS = 0X0D   ; selecion del PPS para el CCP5


CCP1_initialize()
CCP2_initialize()
CCP3_initialize()

;Set to xxx% duty cycle
While PIR4BITS_TMR2IF = 0; // espera a que cambie el perirodo  
    PR2 = 78;
            ;                     (FOSC)
            ; PR2 = [ --------------------------------- ] - 1
            ;            (4*TMR2Prescaler*PWMFrequency)
           
            ; FOSC = 20MHz
            ; TMR2Prescaler = 1:64           PR2 = 78.125  ==> 78
            ; PWMFrequency  = 1000 Hz
           
    CCPR1L = 0   ; CCPRxL REGISTER: CCP1 REGISTER LOW BYTE
    CCPR1H = 78  ; CCPRxH REGISTER: CCP1 REGISTER HIGH BYTE
   
'                  log[4(pr2 + 1)]
'    resolution = -----------------  = 8.30 bits  ==> 10 bits
'                       log(2)
   
'    CCPRxH:CCPRxL = 4*(PR2 + 1)* DutyCycleRatio

'                  Pr2 = 78                          CCPRxH:CCPRxL = 316 = %0100111100
'                  DutyCycleRatio = 100% ==> 1       CCPRxH = %01001111 = 79 ==> usamos el 99% ==> 78
'                                                    CCPRxL = %00       = 0


   
    CCPR2L = 0   ; CCPRxL REGISTER: CCP2 REGISTER LOW BYTE
    CCPR2H = 35  ; CCPRxH REGISTER: CCP2 REGISTER HIGH BYTE
'                        CCPRxH:CCPRxL      35 | 00     %0010001100      140
'    DutyCycleRatio = ----------------- =  ---------- = ------------ = ------- = 0.443 * 100% = 44.30%
'                         4*(PR2 + 1)        4(78+1)        316          316

'    DutyCycleRatio = 44.30%

    CCPR3L = 0   ; CCPRxL REGISTER: CCP3 REGISTER LOW BYTE
    CCPR3H = 10  ; CCPRxH REGISTER: CCP3 REGISTER HIGH BYTE
   
'    DutyCycleRatio = 12.65%
   
Wend


INICIO:
    LED = 1
    DelayMS 100
    LED = 0
    DelayMS 100
GoTo INICIO
End


Proc CCP1_initialize()
   
    ;CCPxCON: CCPx CONTROL REGISTER
            CCP1CON = %10111111
'            CCP1CONbits_EN =  1      ; BIT 7 Module Enable bit; "1" is enabled, "0" is disabled
'            CCP1CONbits_OUT = 0      ; BIT 5 CCPx Output Data bit (read-only)
'            CCP1CONbits_FMT = 1      ; BIT 4 CCPW (Pulse Width) Alignment bit, "1" Left-aligned format, "0" Right-aligned format
'            CCP1CONbits_MODE3 = 1    ; MODE = PWM mode;
'            CCP1CONbits_MODE2 = 1    ; BIT 3 - BIT 0; CCPx Mode Select bits
'            CCP1CONbits_MODE1 = 1    ; 1111 = PWM mode
'            CCP1CONbits_MODE0 = 1         
   
    ;CCP TIMERS CONTROL 0 REGISTER
'            CCPTMRS0 = %00000001
            CCPTMRS0bits_C4TSEL1 = 0
            CCPTMRS0bits_C4TSEL0 = 0
            CCPTMRS0bits_C3TSEL1 = 0
            CCPTMRS0bits_C3TSEL0 = 0
            CCPTMRS0bits_C2TSEL1 = 0
            CCPTMRS0bits_C2TSEL0 = 0
            CCPTMRS0bits_C1TSEL1 = 0
            CCPTMRS0bits_C1TSEL0 = 1
           
            'bit 7-6 C4TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP4 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP4 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP4 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
            'bit 5-4 C3TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP3 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP3 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP3 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
            'bit 3-2 C2TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP2 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP2 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP2 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
            'bit 1-0 C1TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP1 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP1 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP1 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
    ;TxCON: TIMER2/4/6 CONTROL REGISTER
            'T2CON = %11100000;
            T2CONBITS_ON = 1
            T2CONBITS_CKPS2 = 1
            T2CONBITS_CKPS1 = 1
            T2CONBITS_CKPS0 = 0
            T2CONBITS_OUTPS3 = 0
            T2CONBITS_OUTPS2 = 0
            T2CONBITS_OUTPS1 = 0
            T2CONBITS_OUTPS0 = 0
           
            'bit 7 ON: Timerx On bit
                    '1 = Timerx is on
                    '0 = Timerx is off: all counters and state machines are reset
            'bit 6-4 CKPS<2:0>: Timer2-type Clock Prescale Select bits
                    '111 = 1:128 Prescaler
                    '110 = 1:64 Prescaler
                    '101 = 1:32 Prescaler
                    '100 = 1:16 Prescaler
                    '011 = 1:8 Prescaler
                    '010 = 1:4 Prescaler
                    '001 = 1:2 Prescaler
                    '000 = 1:1 Prescaler
            'bit 3-0 OUTPS<3:0>: Timerx Output Postscaler Select bits
                    '1111 = 1:16 Postscaler
                    '1110 = 1:15 Postscaler
                    '1101 = 1:14 Postscaler
                    '1100 = 1:13 Postscaler
                    '1011 = 1:12 Postscaler
                    '1010 = 1:11 Postscaler
                    '1001 = 1:10 Postscaler
                    '1000 = 1:9 Postscaler
                    '0111 = 1:8 Postscaler
                    '0110 = 1:7 Postscaler
                    '0101 = 1:6 Postscaler
                    '0100 = 1:5 Postscaler
                    '0011 = 1:4 Postscaler
                    '0010 = 1:3 Postscaler
                    '0001 = 1:2 Postscaler
                    '0000 = 1:1 Postscaler
    
'     TxCLKCON: TIMER2/4/6 CLOCK SELECTION REGISTER      
            'T2CLKCON = %00000001; 0x01;
            T2CLKCONBITS_CS3 = 0
            T2CLKCONBITS_CS2 = 0
            T2CLKCONBITS_CS1 = 0
            T2CLKCONBITS_CS0 = 1
           
            'bit 7-4 Unimplemented: Read as '0'
            'bit 3-0 CS<3:0>: Timer2/4/6 Clock Select bits
                    '1111 = Reserved
                    '1110 = Reserved
                    '1101 = LC4_out
                    '1100 = LC3_out
                    '1011 = LC2_out
                    '1010 = LC1_out
                    '1001 = ZCD1_output
                    '1000 = NCO output
                    '0111 = CLKR
                    '0110 = SOSC
                    '0101 = MFINTOSC/16 (31.25 kHz)
                    '0100 = LFINTOSC
                    '0011 = HFINTOSC (16 MHz)
                    '0010 = FOSC
                    '0001 = FOSC/4
                    '0000 = TxCKIPPS
                       
'     PIR4: PERIPHERAL INTERRUPT REQUEST REGISTER 4
            PIR4BITS_TMR2IF = 0;  ;Timer2 Interrupt Flag bit
                '1 = The TMR2 postscaler overflowed, or in 1:1 mode, a TMR2 to PR2 match occurred
                '    (must be cleared in software)
                '0 = No TMR2 event has occurred
EndProc

Proc CCP2_initialize()
   
    ;CCPxCON: CCPx CONTROL REGISTER
            CCP2CON = %10111111
'            CCP2CONbits_EN =  1      ; BIT 7 Module Enable bit; "1" is enabled, "0" is disabled
'            CCP2CONbits_OUT = 0      ; BIT 5 CCPx Output Data bit (read-only)
'            CCP2CONbits_FMT = 1      ; BIT 4 CCPW (Pulse Width) Alignment bit, "1" Left-aligned format, "0" Right-aligned format
'            CCP2CONbits_MODE3 = 1    ; MODE = PWM mode;
'            CCP2CONbits_MODE2 = 1    ; BIT 3 - BIT 0; CCPx Mode Select bits
'            CCP2CONbits_MODE1 = 1    ; 1111 = PWM mode
'            CCP2CONbits_MODE0 = 1         
   
    ;CCP TIMERS CONTROL 0 REGISTER
'            CCPTMRS0 = %00000001
            CCPTMRS0bits_C4TSEL1 = 0
            CCPTMRS0bits_C4TSEL0 = 0
            CCPTMRS0bits_C3TSEL1 = 0
            CCPTMRS0bits_C3TSEL0 = 0
            CCPTMRS0bits_C2TSEL1 = 0
            CCPTMRS0bits_C2TSEL0 = 1
            CCPTMRS0bits_C1TSEL1 = 0
            CCPTMRS0bits_C1TSEL0 = 0
           
            'bit 7-6 C4TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP4 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP4 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP4 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
            'bit 5-4 C3TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP3 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP3 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP3 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
            'bit 3-2 C2TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP2 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP2 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP2 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
            'bit 1-0 C1TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP1 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP1 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP1 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
    ;TxCON: TIMER2/4/6 CONTROL REGISTER
            'T2CON = %11100000;
            T1CONBITS_ON = 1
            T2CONBITS_CKPS2 = 1
            T2CONBITS_CKPS1 = 1
            T2CONBITS_CKPS0 = 0
            T2CONBITS_OUTPS3 = 0
            T2CONBITS_OUTPS2 = 0
            T2CONBITS_OUTPS1 = 0
            T2CONBITS_OUTPS0 = 0
           
            'bit 7 ON: Timerx On bit
                    '1 = Timerx is on
                    '0 = Timerx is off: all counters and state machines are reset
            'bit 6-4 CKPS<2:0>: Timer2-type Clock Prescale Select bits
                    '111 = 1:128 Prescaler
                    '110 = 1:64 Prescaler
                    '101 = 1:32 Prescaler
                    '100 = 1:16 Prescaler
                    '011 = 1:8 Prescaler
                    '010 = 1:4 Prescaler
                    '001 = 1:2 Prescaler
                    '000 = 1:1 Prescaler
            'bit 3-0 OUTPS<3:0>: Timerx Output Postscaler Select bits
                    '1111 = 1:16 Postscaler
                    '1110 = 1:15 Postscaler
                    '1101 = 1:14 Postscaler
                    '1100 = 1:13 Postscaler
                    '1011 = 1:12 Postscaler
                    '1010 = 1:11 Postscaler
                    '1001 = 1:10 Postscaler
                    '1000 = 1:9 Postscaler
                    '0111 = 1:8 Postscaler
                    '0110 = 1:7 Postscaler
                    '0101 = 1:6 Postscaler
                    '0100 = 1:5 Postscaler
                    '0011 = 1:4 Postscaler
                    '0010 = 1:3 Postscaler
                    '0001 = 1:2 Postscaler
                    '0000 = 1:1 Postscaler
    
'     TxCLKCON: TIMER2/4/6 CLOCK SELECTION REGISTER      
            'T2CLKCON = %00000001; 0x01;
            T2CLKCONBITS_CS3 = 0
            T2CLKCONBITS_CS2 = 0
            T2CLKCONBITS_CS1 = 0
            T2CLKCONBITS_CS0 = 1
           
            'bit 7-4 Unimplemented: Read as '0'
            'bit 3-0 CS<3:0>: Timer2/4/6 Clock Select bits
                    '1111 = Reserved
                    '1110 = Reserved
                    '1101 = LC4_out
                    '1100 = LC3_out
                    '1011 = LC2_out
                    '1010 = LC1_out
                    '1001 = ZCD1_output
                    '1000 = NCO output
                    '0111 = CLKR
                    '0110 = SOSC
                    '0101 = MFINTOSC/16 (31.25 kHz)
                    '0100 = LFINTOSC
                    '0011 = HFINTOSC (16 MHz)
                    '0010 = FOSC
                    '0001 = FOSC/4
                    '0000 = TxCKIPPS
                       
'     PIR4: PERIPHERAL INTERRUPT REQUEST REGISTER 4
            PIR4BITS_TMR2IF = 0;  ;Timer2 Interrupt Flag bit
                '1 = The TMR2 postscaler overflowed, or in 1:1 mode, a TMR2 to PR2 match occurred
                '    (must be cleared in software)
                '0 = No TMR2 event has occurred
EndProc

Proc CCP3_initialize()
   
    ;CCPxCON: CCPx CONTROL REGISTER
            CCP3CON = %10111111
'            CCP2CONbits_EN =  1      ; BIT 7 Module Enable bit; "1" is enabled, "0" is disabled
'            CCP2CONbits_OUT = 0      ; BIT 5 CCPx Output Data bit (read-only)
'            CCP2CONbits_FMT = 1      ; BIT 4 CCPW (Pulse Width) Alignment bit, "1" Left-aligned format, "0" Right-aligned format
'            CCP2CONbits_MODE3 = 1    ; MODE = PWM mode;
'            CCP2CONbits_MODE2 = 1    ; BIT 3 - BIT 0; CCPx Mode Select bits
'            CCP2CONbits_MODE1 = 1    ; 1111 = PWM mode
'            CCP2CONbits_MODE0 = 1         
   
    ;CCP TIMERS CONTROL 0 REGISTER
'            CCPTMRS0 = %00000001
            CCPTMRS0bits_C4TSEL1 = 0
            CCPTMRS0bits_C4TSEL0 = 0
            CCPTMRS0bits_C3TSEL1 = 0
            CCPTMRS0bits_C3TSEL0 = 1
            CCPTMRS0bits_C2TSEL1 = 0
            CCPTMRS0bits_C2TSEL0 = 0
            CCPTMRS0bits_C1TSEL1 = 0
            CCPTMRS0bits_C1TSEL0 = 0
           
            'bit 7-6 C4TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP4 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP4 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP4 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
            'bit 5-4 C3TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP3 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP3 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP3 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
            'bit 3-2 C2TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP2 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP2 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP2 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
            'bit 1-0 C1TSEL<1:0>: CCP4 Timer Selection
                    '11 = CCP1 based on TMR5 (Capture/Compare) or TMR6 (PWM)
                    '10 = CCP1 based on TMR3 (Capture/Compare) or TMR4 (PWM)
                    '01 = CCP1 based on TMR1 (Capture/Compare) or TMR2 (PWM)
                    '00 = Reserved
    ;TxCON: TIMER2/4/6 CONTROL REGISTER
            'T2CON = %11100000;
            T1CONBITS_ON = 1
            T2CONBITS_CKPS2 = 1
            T2CONBITS_CKPS1 = 1
            T2CONBITS_CKPS0 = 0
            T2CONBITS_OUTPS3 = 0
            T2CONBITS_OUTPS2 = 0
            T2CONBITS_OUTPS1 = 0
            T2CONBITS_OUTPS0 = 0
           
            'bit 7 ON: Timerx On bit
                    '1 = Timerx is on
                    '0 = Timerx is off: all counters and state machines are reset
            'bit 6-4 CKPS<2:0>: Timer2-type Clock Prescale Select bits
                    '111 = 1:128 Prescaler
                    '110 = 1:64 Prescaler
                    '101 = 1:32 Prescaler
                    '100 = 1:16 Prescaler
                    '011 = 1:8 Prescaler
                    '010 = 1:4 Prescaler
                    '001 = 1:2 Prescaler
                    '000 = 1:1 Prescaler
            'bit 3-0 OUTPS<3:0>: Timerx Output Postscaler Select bits
                    '1111 = 1:16 Postscaler
                    '1110 = 1:15 Postscaler
                    '1101 = 1:14 Postscaler
                    '1100 = 1:13 Postscaler
                    '1011 = 1:12 Postscaler
                    '1010 = 1:11 Postscaler
                    '1001 = 1:10 Postscaler
                    '1000 = 1:9 Postscaler
                    '0111 = 1:8 Postscaler
                    '0110 = 1:7 Postscaler
                    '0101 = 1:6 Postscaler
                    '0100 = 1:5 Postscaler
                    '0011 = 1:4 Postscaler
                    '0010 = 1:3 Postscaler
                    '0001 = 1:2 Postscaler
                    '0000 = 1:1 Postscaler
    
'     TxCLKCON: TIMER2/4/6 CLOCK SELECTION REGISTER      
            'T2CLKCON = %00000001; 0x01;
            T2CLKCONBITS_CS3 = 0
            T2CLKCONBITS_CS2 = 0
            T2CLKCONBITS_CS1 = 0
            T2CLKCONBITS_CS0 = 1
           
            'bit 7-4 Unimplemented: Read as '0'
            'bit 3-0 CS<3:0>: Timer2/4/6 Clock Select bits
                    '1111 = Reserved
                    '1110 = Reserved
                    '1101 = LC4_out
                    '1100 = LC3_out
                    '1011 = LC2_out
                    '1010 = LC1_out
                    '1001 = ZCD1_output
                    '1000 = NCO output
                    '0111 = CLKR
                    '0110 = SOSC
                    '0101 = MFINTOSC/16 (31.25 kHz)
                    '0100 = LFINTOSC
                    '0011 = HFINTOSC (16 MHz)
                    '0010 = FOSC
                    '0001 = FOSC/4
                    '0000 = TxCKIPPS
                       
'     PIR4: PERIPHERAL INTERRUPT REQUEST REGISTER 4
            PIR4BITS_TMR2IF = 0;  ;Timer2 Interrupt Flag bit
                '1 = The TMR2 postscaler overflowed, or in 1:1 mode, a TMR2 to PR2 match occurred
                '    (must be cleared in software)
                '0 = No TMR2 event has occurred
EndProc


Pepe