News:

;) This forum is the property of Proton software developers

Main Menu

16F1824 - can't get 2nd PWM to work as expected.

Started by david, Oct 21, 2024, 09:10 AM

Previous topic - Next topic

david

Hi All,
I tried to set up the second PWM output in the 16F1824 chip but it doesn't seem to want to take on the associated timer value.
The first PWM set up was straight forward and I thought it would be easy to arrange a second one on a different frequency.

I think these are the registers involved-

T2CON=%00000100         'Tmr2 on, 1:1 prescale 
CCP1CON=%00001100       'PWM1
T4CON=%00000111         'Tmr4 on, 1:64 prescale
CCP2CON=%00001100       'PWM2 
CCPTMRS0=%01000000      'Tmr2, Tmr4 allocation
PR2=249                 'PWM1
PR4=249                 'PWM2

Changing Tmr2 prescale changes the frequency of the first PWM output but I can't make Tmr4 control the 2nd PWM.
The register CCPTMRS0=%01000000 was my biggest concern but I tried all 4 combinations of clock allocation and either PWM2 stopped or was the same frequency as PWM1.  I only need simple PWM operation and not enhanced, multi-output PWM.

Any ideas would be appreciated.

Cheers,
David




david

SORTED!   
It required this clock allocation-
CCPTMRS0=%00000100

I did try this value but I think I had 0% duty cycle at the time so not very revealing for diagnostics.

David

top204

You beat me to it David. However, for a future reference for other users, I created a demonstration program to setup the EPWM1 and EPWM2 peripherals on a PIC16F1824 device, using two independent oscillators of Timer2 and Timer4. The code listing is below:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' A demonstration of the CCP1 and CCP2 peripherals operating as PWM on a PIC16F1824 device.
' Using Timer2 for the EPWM1 peripheral, and Timer4 for the EPWM2 peripheral.
'
' Written for the Positron8 BASIC compiler by Les Johnson.
'
    Device = 16F1824                                                ' Tell the compiler what device to compile for
    Declare Xtal = 32                                               ' Tell the compiler what frequency the device is operating at (in MHz)
'
' Setup USART1
'
    Declare Hserial1_Baud = 9600
    Declare HRSOut1_Pin = PORTA.0

'-----------------------------------------------------------------------------------------
' Timer2 Meta-Macros for a PIC16F1824 device
'
$define Timer2_Start() T2CONbits_TMR2ON = 1                         ' Start Timer2
$define Timer2_Stop() T2CONbits_TMR2ON = 0                          ' Stop Timer2
$define Timer2_Read() TMR2                                          ' Read Timer2
$define Timer2_Write(pValue) TMR2 = pValue                          ' Write pValue to Timer2 TMR2 SFR
$define Timer2_Period(pPeriod) PR2 = pPeriod                        ' Write pPeriod to Timer2 PR2 SFR

'-----------------------------------------------------------------------------------------
' Timer4 Meta-Macros for a PIC16F1824 device
'
$define Timer4_Start() T4CONbits_TMR4ON = 1                         ' Start Timer4
$define Timer4_Stop() T4CONbits_TMR4ON = 0                          ' Stop Timer4
$define Timer4_Read() TMR4                                          ' Read Timer4
$define Timer4_Write(pValue) TMR4 = pValue                          ' Write pValue to Timer4 TMR4 SFR
$define Timer4_Period(pPeriod) PR4 = pPeriod                        ' Write pPeriod to Timer4 PR4 SFR
   
$define EPWM1_Pin PORTC.5                                           ' The pin for the EPWM1 output
$define EPWM2_Pin PORTC.3                                           ' The pin for the EPWM2 output
'
' Create global variables here:
'
    Dim bTimer_Period As Byte                                       ' Holds the timer value

'-----------------------------------------------------------------------------------------
' The main program starts here
' Setup the CCP1 and CCP2 peripherals for PWM, with CCP1 using Timer2 and CCP2 using Timer4
' Alter the period values of both timers and this alters the PWM waveforms
'
Main:
    Setup()                                                         ' Setup the program and peripherals
    HRSOutLn "Start"                                                ' Transmit to a serial terminal, to make sure the device is operating at the correct speed
   
    Do                                                              ' Create a loop
        For bTimer_Period = 0 To 255                                ' Create a loop to alter the timer period values
            Timer2_Period(bTimer_Period)                            ' Alter the Timer2 period value
            Timer4_Period(bTimer_Period)                            ' Alter the Timer4 period value
            HRSOutLn "Timer Period = ", Dec bTimer_Period           ' Transmit the period values to a serial terminal
            DelayMS 20                                              ' A small delay so the periods can be seen changing
        Next                                                        ' Close the period loop
    Loop                                                            ' Do it forever
   
'-----------------------------------------------------------------------------------------
' Setup the program and peripherals
' Input     : None
' Output    : None
' Notes     : None
'
Proc Setup()
    Osc_Init()                                                      ' Initialise the internal oscillator
    APFCON0bits_TXCKSEL = 1                                         ' Set the USART1 TX line to pin PORTA.0
   
    Timer2_Init()                                                   ' Setup Timer2
    Timer4_Init()                                                   ' Setup Timer4
    EPWM1_Init()                                                    ' Setup the EPWM1 peripheral
    EPWM2_Init()                                                    ' Setup the EPWM2 peripheral
    PinOutput EPWM1_Pin                                             ' Make the CCP1 pin an output
    PinOutput EPWM2_Pin                                             ' Make the CCP2 pin an output
EndProc

'-----------------------------------------------------------------------------------------
' Setup the CCP1 peripheral as PWM
' Input     : None
' Output    : None
' Notes     : Sets the EPWM1 peripheral to use Timer2
'           : For use with a PIC16F1824 Device
'
Proc EPWM1_Init()
    CCP1CON  = %00011100                                                
    ECCP1AS  = %00000000
    PWM1CON  = %10000000                                            ' Automatic restart
    PSTR1CON = %00000001                                         
    CCPR1H   = $00
    CCPR1L   = $3B
    CCPTMRSbits_C1TSEL0 = 0                                         ' \
    CCPTMRSbits_C1TSEL0 = 0                                         ' / CCP1 is using Timer2 in PWM Mode
EndProc

'-----------------------------------------------------------------------------------------
' Setup the CCP2 peripheral as PWM
' Input     : None
' Output    : None
' Notes     : Sets the EPWM2 peripheral to use Timer4
'           : For use with a PIC16F1824 Device
'
Proc EPWM2_Init()
    CCP2CON  = %00011100                                                  
    CCP2AS   = %00000000
    PWM2CON  = %10000000                                            ' Automatic restart
    PSTR2CON = %00000001                                         
    CCPR2H   = $00
    CCPR2L   = $3B
    CCPTMRSbits_C2TSEL0 = 0                                         ' \
    CCPTMRSbits_C2TSEL0 = 1                                         ' / CCP2 is using Timer4 in PWM Mode
EndProc

'-----------------------------------------------------------------------------------------
' Write the duty to the EPWM1 peripheral
' Input     : pDuty holds the duty cycle value of the PWM waveform
' Output    : None
' Notes     : None
'
Proc EPWM1_Duty(pDuty As Word)
    CCP1CON = CCP1CON & %11001111
    WREG = pDuty << 4
    WREG = WREG & %00110000
    CCP1CON = CCP1CON | WREG
    CCPR1L = pDuty >> 2
EndProc

'-----------------------------------------------------------------------------------------
' Write the duty to the EPWM2 peripheral
' Input     : pDuty holds the duty cycle value of the PWM waveform
' Output    : None
' Notes     : For use with a PIC16F1824 Device
'
Proc EPWM2_Duty(pDuty As Word)
    CCP2CON = CCP2CON & %11001111
    WREG = pDuty << 4
    WREG = WREG & %00110000
    CCP2CON = CCP2CON | WREG
    CCPR2L = pDuty >> 2
EndProc

'-----------------------------------------------------------------------------------------
' Setup Timer2
' Input     : None
' Output    : None
' Notes     : Sets Timer2 to operate at 16.6KHz with a 32MHz device frequency
'           : For use with a PIC16F1824 Device
'
Proc Timer2_Init()
    PR2 = $77
    TMR2 = $00
    PIR1bits_TMR2IF = 0
    T2CON = %00000101                                               ' Prescaler is 1:4. Postscaler is 1:1. Timer2 enabled
EndProc

'-----------------------------------------------------------------------------------------
' Setup Timer4
' Input     : None
' Output    : None
' Notes     : Sets Timer4 to operate at 16.6KHz with a 32MHz device frequency
'           : For use with a PIC16F1824 Device
'
Proc Timer4_Init()
    PR4 = $77
    TMR4 = $00
    PIR3bits_TMR4IF = 0
    T4CON = %00000101                                               ' Prescaler is 1:4. Postscaler is 1:1. Timer4 enabled
EndProc

'-----------------------------------------------------------------------------------------
' Setup the internal oscillator
' Input     : None
' Output    : None
' Notes     : For use with a PIC16F1824 Device
'
Proc Osc_Init()
    OSCCON  = %01110000                                             ' 8MHz
    OSCTUNE = $00
    BORCON  = $00 
    DelayMS 100                                                     ' Wait for the PLL to stabilise
EndProc

'-----------------------------------------------------------------------------------------
' Setup the config fuses for internal oscillator on a PIC16F1824 device
' Osc pins are general purpose I/O
'
    Config1 FOSC_INTOSC,_                           ' Internal oscillator. I/O function on CLKIN pin
            WDTE_OFF,_                              ' Watchdog Timer disabled
            PWRTE_OFF,_                             ' PWRT disabled
            MCLRE_ON,_                              ' MCLR/VPP pin function is MCLR
            CP_OFF,_                                ' Program memory code protection is disabled
            CPD_OFF,_                               ' Data memory code protection is disabled
            BOREN_ON,_                              ' Brown-out Reset enabled
            CLKOUTEN_OFF,_                          ' CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
            IESO_ON,_                               ' Internal/External Switchover mode is enabled
            FCMEN_ON                                ' Fail-Safe Clock Monitor is enabled

    Config2 WRT_OFF,_                               ' Flash Memory Write protection off
            PLLEN_ON,_                              ' 4xPLL enabled
            STVREN_ON,_                             ' Stack Overflow or Underflow will cause a Reset
            BORV_19,_                               ' Brown-out Reset Voltage (VBOR) set to 1.9 V
            LVP_OFF                                 ' High-voltage on MCLR/VPP must be used for programming
           

david

That was quick!   
That's a great reference item for the future.  Thank for posting.

Cheers,
David