PIC12F1840 ECCP peripheral PWM running at 200KHz with a 7-bit resolution
PIC12F1840 ECCP peripheral PWM running at 200KHz with a 7-bit resolution
A question came up the other week about creating a high frequency signal from the ECCP peripheral on a PIC12F, enhanced 14-bit core device, so I created a small program to illustate how it is done, and how simple it can be done with the Positron8 BASIC compiler.
With timer based PWM, the resolution of the PWM waveform reduces as the frequency increases. There is an equation in the devic's datasheet to calculate the resolution for a given PWM frequency. Here's a demo program for the PIC12F1840, running at 32MHz internal oscillator, producing a 200KHz PWM waveform with 50% duty cycle. The EPWM operates at 7-bit resolution, which is quite good for the frequency.
The Positron8 BASIC compiler listing below shows how to generate a 200KHz square wave signal from the ECCP peripheral:
'
' /\\\\\\\\\
' /\\\///////\\\
' \/\\\ \/\\\ /\\\ /\\\
' \/\\\\\\\\\\\/ /\\\\\ /\\\\\\\\\\ /\\\\\\\\ /\\\\\\\\\\\ /\\\\\\\\\\\ /\\\\\\\\\
' \/\\\//////\\\ /\\\///\\\ \/\\\////// /\\\/////\\\ \////\\\//// \////\\\//// \////////\\\
' \/\\\ \//\\\ /\\\ \//\\\ \/\\\\\\\\\\ /\\\\\\\\\\\ \/\\\ \/\\\ /\\\\\\\\\\
' \/\\\ \//\\\ \//\\\ /\\\ \////////\\\ \//\\/////// \/\\\ /\\ \/\\\ /\\ /\\\/////\\\
' \/\\\ \//\\\ \///\\\\\/ /\\\\\\\\\\ \//\\\\\\\\\\ \//\\\\\ \//\\\\\ \//\\\\\\\\/\\
' \/// \/// \///// \////////// \////////// \///// \///// \////////\//
' Let's find out together what makes a PIC Tick!
'
' Setup the ECCP peripheral on a PIC12F1840 to produce a PWM waveform at 200KHz with a 50% duty cycle
'
' Written by Les Johnson for the Positron8 BASIC compiler.
' https://sites.google.com/view/rosetta-tech/home
'
Device = 12F1840 ' Select the device to compile for
Declare Xtal = 32 ' Inform the compiler the device will be operating at 32MHz
'-------------------------------------------------------------------
' Initialise the EPWM peripheral for 200KHz operation at 7-bit resolution
' 50% duty cycle, on a device running at 32MHz
'
Proc EPWM_Init()
CCP1CON = $3C
ECCP1AS = $00
PWM1CON = $80
PSTR1CON = $01
CCPR1H = $00
CCPR1L = $13
Output PORTA.2 ' Set the ECCP1 pin as an output
EndProc
'-------------------------------------------------------------------
' Alter the duty cycle of the ECCP1 peripheral operating with an 8-bit or less resolution
' Input : pDuty holds the duty cycle value (0 to 255)
' Output : None
' Notes : None
'
Proc EPWM_Duty(pDuty As Byte)
CCP1CON = CCP1CON & $CF
WREG = pDuty << 4
WREG = WREG & $30
CCP1CON = CCP1CON | WREG
CCPR1L = pDuty >> 2
EndProc
'-------------------------------------------------------------------
' Initialise Timer2 to operate at 5uS with a device running at 32MHz
'
Proc Timer2_Init()
PR2 = $27
TMR2 = $00
T2CON = $04
EndProc
'-------------------------------------------------------------------
$define Timer2_Start() T2CONbits_TMR2ON = 1
$define Timer2_Stop() T2CONbits_TMR2ON = 0
$define Timer2_Write(pVal) TMR2 = pVal
$define Timer2_Period(pVal) PR2 = pVal
'-------------------------------------------------------------------
' Setup the internal oscillator to run the device at 32MHz
'
Proc Osc_32MHz()
OSCCON = $F0
OSCTUNE = $00
BORCON = $00
DelayMs 100
EndProc
'-------------------------------------------------------------------
' The main program starts here
' Output a 200KHz PWM waveform from pin PORTA.2 with a 50% duty cycle
'
Main:
Osc_32MHz() ' Set the device to run at 32MHz with its internal oscillator
Timer2_Init() ' Initialise Timer2 to run at 200KHz (5us)
EPWM_Init() ' Initialise the ECCP1 peripheral to operate as EPWM with 50% duty
'-------------------------------------------------------------------
' Set the config fuses for internal oscillator and PLL enabled
'
Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_OFF, MCLRE_ON, CLKOUTEN_OFF, IESO_OFF, CP_OFF, CPD_OFF, BOREN_OFF
Config2 WRT_OFF, PLLEN_ON, LVP_OFF
In order to get pulsed PWM signals, simply make the PORTA.2 pin an input when the signal is not required, then an output when it is required. The ECCP peripheral does not need disabling. The above demo code also has a procedure to alter the duty cycle of the PWM waveform and it worked well when looking at the waveform in simulation.
I couldn't find a real PIC12F1840 in any of my drawers, so I ran a simulation in Isis: