T
// PWM test for PIC18857 using 4MHz internal oscillator
// amateur code - use at your own risk - author accepts no responsibility for anything, anywhere, ever
// Example of using NCO module for DDS - gives approx 500Hz square wave on RA2
// spec from forum - We need to set a fixed PWM of 30% duty at approx. 500Hz on RA2.
// We also need a variable PWM on RA1. (frequency anywhere between 2kHz and 300Hz, but again it will be a fixed frequency)
void main() {
OSCEN = 0x20; // internal oscillator explicit selection
OSCFRQ = 0x02; // change internal oscillator to 4 MHz
OSCCON1 = 0x60; // select internal oscillator, divider = 1
ANSELA = 0; // all digital
TRISA = 0; // all output
LATA = 0; // start all low
ANSELB = 0; // all digital
TRISB = 0; // all output
LATB = 0; // start all low
ANSELC = 0; // all digital
TRISC = 0; // all output
LATC = 0; // start all low
Unlock_IOLOCK(); // allow PPS mapping
PPS_Mapping_NoLock(2, _OUTPUT, _PWM7OUT); // Set pin A2 to be Output, and map PWM7 to it
PPS_Mapping_NoLock(1, _OUTPUT, _NCO); // Set pin A1 to be Output, and map NCO to it
NCO1CON = 0x80; // enable NCO in 50% mode
NCO1CLK = 0x00; // processor clock as NCO source
NCO1INCH = 0x01; // always write high before low
NCO1INCL = 0x03; // latch high and low together - 0002 gives approx 1Hz
T2CLKCON = 0x01; // Fosc/4 as clock
T2CON = 0xd0; // T2 on, 1:4 prescaler, 1:1 postscaler
T2HLT = 0x00; // free running mode
PR2 = 0x3e; // 0x3e seems to give 500Hz
PWM7CON = 0x80; // enable PWM7
PWM7DCH = 0x13; // 0x1300 seems to give 30% duty
PWM7DCL = 0x00; // only top 2 bits used for fine control
while(1){
}
}
Amazing how I could miss the obvious! That's the solution, thanks FvM.As far as I understand, timer 4 and 6 can be chosen alternatively for each PWM unit. But as mentioned before, you face the problem of maximal PWM period, you'll probably need to go for a more complex solution.
// PWM test for PIC18857 using 4MHz internal oscillator
// amateur code - use at your own risk - author accepts no responsibility for anything, anywhere, ever
// spec from forum - We need to set a fixed PWM of 30% duty at approx. 500Hz on RA2.
// We also need a variable PWM on RA1. (frequency anywhere between 2kHz and 300Hz, but again it will be a fixed frequency)
void main() {
OSCEN = 0x20; // internal oscillator explicit selection
OSCFRQ = 0x02; // change internal oscillator to 4 MHz
OSCCON1 = 0x60; // select internal oscillator, divider = 1
ANSELA = 0; // all digital
TRISA = 0; // all output
LATA = 0; // start all low
Unlock_IOLOCK(); // allow PPS mapping
PPS_Mapping_NoLock(2, _OUTPUT, _PWM7OUT); // Set pin A2 to be Output, and map PWM7 to it
PPS_Mapping_NoLock(1, _OUTPUT, _PWM6OUT); // Set pin A1 to be Output, and map PWM6 to it
T2CLKCON = 0x01; // Fosc/4 as clock
T2CON = 0xd0; // T2 on, 1:4 prescaler, 1:1 postscaler
T2HLT = 0x00; // free running mode
T6CLKCON = 0x01; // Fosc/4 as clock
T6CON = 0xd0; // T6 on, 1:4 prescaler, 1:1 postscaler
T6HLT = 0x00; // free running mode
PR2 = 0x3e; // 0x3e seems to give 500Hz
PR6 = 0x4e; // 0x4e seems to give 400Hz
CCPTMRS1 = 0x1D; // PWM6 clocked by timer 6, PWM7 clocked by timer 2
PWM6CON = 0x80; // enable PWM6
PWM6DCH = 0x23; // 0x2300 seems to give 45% duty
PWM6DCL = 0x00; // only top 2 bits used for fine control
PWM7CON = 0x80; // enable PWM7
PWM7DCH = 0x13; // 0x1300 seems to give 30% duty
PWM7DCL = 0x00; // only top 2 bits used for fine control
while(1); // infinite loop
}
// PIC16F18856
// XC8 compiler
// MPLAB X V3.61
// date 10 Nov 2018
// updated by amateur coder who accepts no responsibility for anything, anywhere, ever
// spec from forum - We need to set a fixed PWM of 30% duty at approx. 500Hz on RA2.
// We also need a variable PWM on RA1. (frequency anywhere between 2kHz and 300Hz, but again it will be a fixed frequency)
// CONFIG1
#pragma config FEXTOSC = OFF // External Oscillator mode selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT1 // Power-up default value for COSC bits (HFINTOSC (1MHz))
#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
#pragma config CSWEN = ON // Clock Switch Enable bit (The NOSC and NDIV bits can be changed by user software)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (FSCM timer disabled)
// CONFIG2
#pragma config MCLRE = OFF // Master Clear Enable bit (MCLR pin function is port defined function)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config LPBOREN = OFF // Low-Power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = ON // Brown-out reset enable bits (Brown-out Reset Enabled, SBOREN bit is ignored)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
#pragma config ZCD = OFF // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
#pragma config PPS1WAY = OFF // Peripheral Pin Select one-way control (The PPSLOCK bit can be set and cleared repeatedly by software)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will not cause a reset)
// CONFIG3
#pragma config WDTCPS = WDTCPS_31 // WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF // WDT operating mode (WDT Disabled, SWDTEN is ignored)
#pragma config WDTCWS = WDTCWS_7 // WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)
// CONFIG4
#pragma config WRT = OFF // UserNVM self-write protection bits (Write protection off)
#pragma config SCANE = not_available // Scanner Enable bit (Scanner module is not available for use)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (High Voltage on MCLR/Vpp must be used for programming)
// CONFIG5
#pragma config CP = OFF // UserNVM Program memory code protection bit (Program Memory code protection disabled)
#pragma config CPD = OFF // DataNVM code protection bit (Data EEPROM code protection disabled)
// #pragma config statements should precede project file includes.
#include <xc.h> // forum will remove xc.h within braces :(
#include <stdint.h> // forum will remove stdint.h within braces :(
#define _XTAL_FREQ 4000000
void main(void){
OSCEN = 0x20; // internal oscillator explicit selection
OSCFRQ = 0x02; // change internal oscillator to 4 MHz
OSCCON1 = 0x60; // select internal oscillator, divider = 1
TRISA = 0x90; // RA4 temperature input, RA7 ?
ANSELA = 0x10; // RA4 analogue selection for temperature input
CM1CON0 = 0x00;
CM1CON1 = 0x00;
CM2CON0 = 0x00;
CM2CON1 = 0x00;
ZCDCON = 0x00;
RA1PPS = 0x0e; // map PWM6 to RA1
RA2PPS = 0x0f; // map PWM7 to RA1
T2CLKCON = 0x01; // Fosc/4 as clock
T2CON = 0xd0; // T2 on, 1:4 prescaler, 1:1 postscaler
T2HLT = 0x00; // free running mode
T6CLKCON = 0x01; // Fosc/4 as clock
T6CON = 0xd0; // T6 on, 1:4 prescaler, 1:1 postscaler
T6HLT = 0x00; // free running mode
PR2 = 0x3e; // 0x3e seems to give 500Hz
PR6 = 0x4e; // 0x4e seems to give 400Hz
CCPTMRS1 = 0x1D; // PWM6 clocked by timer 6, PWM7 clocked by timer 2
PWM6CON = 0x80; // enable PWM6
PWM6DCH = 0x23; // 0x2300 seems to give 45% duty
PWM6DCL = 0x00; // only top 2 bits used for fine control
PWM7CON = 0x80; // enable PWM7
PWM7DCH = 0x13; // 0x1300 seems to give 30% duty
PWM7DCL = 0x00; // only top 2 bits used for fine control
// main loop
while(1){
}
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?