View previous topic :: View next topic |
Author |
Message |
andresteff
Joined: 21 Mar 2020 Posts: 44
|
PIC24F16KA301: Output Compare with Trigger Mode |
Posted: Wed Mar 02, 2022 5:42 am |
|
|
PIC24F16KA301
ICD3
PCWHD: 5.080
Hey,
I have a problem with output compare unit. After the Init the OC2 pin is HIGH!
Also timer1 is used as counter. If timer1 is config as asynchronous counter the OC2 pin is HIGH. If timer1 is config as synchronous timer the OC2 pin is low. It is fine.
Setup OC2:
Center Aligned PWM Mode / OCSTSEL: FOSC/2
trigger Mode / source is Comparator C2 / Trigger source Mode: Hardware or Software.
Problem 2:
With the CCS i can't config the OC2 unit with trigger mode AND
clear the trigstat bit with hardware OR software
Code: |
#include <24F16KA301.h>
#device ADC=8
#device ICSP=3
#device CONST=READ_ONLY
#use delay(clock=500000)
#fuses LPFRC_DIV //Low-Power FRC oscillator with divide-by-N
#FUSES NOBROWNOUT //No brownout reset
#fuses MCLR //Master Clear pin enabled
#fuses PUT //Power Up Timer
#fuses SOSC_DIGITAL //SOSC pins set for Digital mode for use with external clock or Digital I/O
#fuses OSCIO //OSC2 is general purpose output
#WORD OC2CON1 = 0x019A
#WORD OC2CON2 = 0x019C
#bit TRIGSTAT = 0x192.6
void main()
{
setup_oscillator( OSC_LPFRC , 500000);
#use delay(clock=500000)
delay_us(100);
delay_ms(2000);
/*****************************************************************************
IN:
Compa. C2 generate Trigger Event for OC2
Timer1 : Count
OUT:
Output Compare OC2: Pulse triggered by Comp. C2
******************************************************************************/
output_low(pin_B9);
delay_ms(1);
// This pulse on input C2 helps: OC2 is low! without this pulse OC2 is low
output_high(PIN_B9);
delay_us(100);
output_low(pin_B9);
set_timer1(0);
setup_timer1( T1_EXTERNAL_T1CK | TMR_DIV_BY_1 ); // NOK
// setup_timer1( T1_EXTERNAL_T1CK | TMR_DIV_BY_1 | TMR_EXTERNAL_SYNC ); // OK
output_high(PIN_A4); // led
setup_compare(2, COMPARE_OFF );
set_compare_time(2, 3, 17);
// config with MCC, with the ccs it does not func!!!
OC2CON1 = 0x1C0F; // Center Aligned PWM Mode / OCSTSEL: FOSC/2
OC2CON2 = 0x99; // trigger Mode / source is Comparator C2 / Trigger source Mode: Hardware or Software
while(TRUE);
}
|
Last edited by andresteff on Wed Mar 02, 2022 6:17 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Wed Mar 02, 2022 6:16 am |
|
|
A big part of this is in the family reference manual.
If you look at the entry for Timer1, with output compare, there is the
note:
Quote: |
Timer1 clock (only the synchronous clock is supported)
|
This is why you can't get it to work with the asynchronous clock.... |
|
|
andresteff
Joined: 21 Mar 2020 Posts: 44
|
|
Posted: Wed Mar 02, 2022 6:32 am |
|
|
Ttelmah wrote: | A big part of this is in the family reference manual.
If you look at the entry for Timer1, with output compare, there is the
note:
Quote: |
Timer1 clock (only the synchronous clock is supported)
|
This is why you can't get it to work with the asynchronous clock.... |
OK thanks. But i don't use timer1 as clock, sync or trigger unit for ocx module.
Clock for the OC2 is FOSC/2 and trigger is comp. C2
I use timer1 independent as counter! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Wed Mar 02, 2022 8:24 am |
|
|
OK.
So what are you using as the sync source. Again the data sheet tells you
this cannot be the same clock as you are clocking it from. |
|
|
andresteff
Joined: 21 Mar 2020 Posts: 44
|
|
Posted: Wed Mar 02, 2022 9:24 am |
|
|
Ttelmah wrote: | OK.
So what are you using as the sync source. Again the data sheet tells you
this cannot be the same clock as you are clocking it from. |
...I do not either.
I use the trigger operation of the OCx.
Chapter 3.3.9, Output Compare with Dedicated Timer
Trigger is Comparator C2.
The Event Bit of the Comparator than starts the timer of OC2 Unit.
PIN_OC2 goes high and when the OC2R=OC2RS, then PIN_OC2 goes low |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Wed Mar 02, 2022 11:43 am |
|
|
There seem to be a huge difference between what you are describing.
Understand that it the OC module is setup as a PWM, it can't be 'triggered'.
The compare modes support triggering, but they don't then offer PWM.
Read document 70005159a.pdf. Look at the 'modes of operation':
You can generate s pulse train in compare mode, but this is not 'PWM'.
The setup for PWM, specifically requires that self synchronisation is
selected. |
|
|
andresteff
Joined: 21 Mar 2020 Posts: 44
|
|
Posted: Thu Mar 03, 2022 5:48 am |
|
|
Ttelmah wrote: | There seem to be a huge difference between what you are describing.
Understand that it the OC module is setup as a PWM, it can't be 'triggered'.
The compare modes support triggering, but they don't then offer PWM.
Read document 70005159a.pdf. Look at the 'modes of operation':
You can generate s pulse train in compare mode, but this is not 'PWM'.
The setup for PWM, specifically requires that self synchronisation is
selected. |
In chapter 3.3 PWM there is a subchapter 3.3.9 Trigger Operation.
I use this function. (More precisely the One shot function.)
I use the PWM function but in trigger mode!
With the trigger function the timer is held at 0. If a trigger event occurs, the OC2 pin goes high and the OC2 timer starts running.
If the timer value reaches the value of the OC2RS the OC2 pin goes low and the Trigstat bit is set to 0.
Trigger is with me comparator C2.
Generally the whole thing works, that means, each pulse coming from the comparator generates a fixed pulse at the output of OC2.
BUT, at init the OC2 pin goes high and generates a short circuit.
But only if Timer1 is operated in asynchronous mode. In synchronous mode the OC2 pin remains low. That's what surprises me.
Trigger function: DS70005159A-page 32:
"The TRIGSTAT bit (OCxCON2<6>) holds the timer in Reset or releases it to count. It controls the timer in the following manner:"
Trigmode: DS70005159A-page 6:
TRIGMODE: Trigger Status Mode Select bit
1 = TRIGSTAT (OCxCON2<6>) bit is cleared when OCxRS = OCxTMR or in software
0 = TRIGSTAT (OCxCON2<6>) bit is cleared only by software
Translated with www.DeepL.com/Translator (free version) |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Thu Mar 03, 2022 6:53 am |
|
|
re: BUT, at init the OC2 pin goes high and generates a short circuit
Sounds like the code sequence used to setup the PIC may need to be 'tweaked'. Some variables/registers may need to be cleared(or set). Usually you clear interrupt result registers before enabling those interrupts.
If it's a really fast PIC, maybe add a delay between the 'init' sequences and main() ?
If the interrupt is caused by an external device (push button,GPS, ??) be 100% sure THAT is in the proper state before main() runs... |
|
|
andresteff
Joined: 21 Mar 2020 Posts: 44
|
|
Posted: Thu Mar 03, 2022 8:49 am |
|
|
temtronic wrote: | re: BUT, at init the OC2 pin goes high and generates a short circuit
Sounds like the code sequence used to setup the PIC may need to be 'tweaked'. Some variables/registers may need to be cleared(or set). Usually you clear interrupt result registers before enabling those interrupts.
If it's a really fast PIC, maybe add a delay between the 'init' sequences and main() ?
If the interrupt is caused by an external device (push button,GPS, ??) be 100% sure THAT is in the proper state before main() runs... |
I haved config Output Compare, OC2 OFF-State with the MCC from Microchip.
It works! The OC2 Pin is low!
When i use the CCS code for Output Compare OC2 for OFF-State,
so "setup_compare(2, COMPARE_OFF );"
the OC2 Pin is high...
Code: |
#include <24F16KA301.h>
#device ADC=8
#device ICSP=3
#device CONST=READ_ONLY
#use delay(clock=500000)
#fuses LPFRC_DIV //Low-Power FRC oscillator with divide-by-N
#FUSES NOBROWNOUT //No brownout reset
#fuses MCLR //Master Clear pin enabled
#fuses PUT //Power Up Timer
#fuses SOSC_DIGITAL //SOSC pins set for Digital mode for use with external clock or Digital I/O
#fuses OSCIO //OSC2 is general purpose output
#WORD OC2CON1 = 0x019A
#WORD OC2CON2 = 0x019C
#bit TRIGSTAT = 0x192.6
void main()
{
setup_oscillator( OSC_LPFRC , 500000);
#use delay(clock=500000)
delay_us(100);
delay_ms(2000);
set_timer1(0);
setup_timer1( T1_EXTERNAL_T1CK | TMR_DIV_BY_1 ); // NOK
// setup_timer1( T1_EXTERNAL_T1CK | TMR_DIV_BY_1 | TMR_EXTERNAL_SYNC ); // OK
output_high(PIN_A4); // led
// OC2 = OFF do not works
//setup_compare(2, COMPARE_OFF );
// OC2 = OFF (config with MCC) WORKS!!! OC2 PIN=low
OC2CON1 = 0x1C08; // OCM Off; OCFLT1 disabled; OCTSEL FOSC/2; TRIGMODE Hardware or Software; and MORE...
OC2CON2 = 0x8099; // SYNCSEL CMP2; TRIGSTAT disabled; OCTRIG Trigger; and MORE...
set_compare_time(2, 3, 17);
OC2CON1 = 0x1C0F; // Center Alingned PWM Mode / OCSTSEL: FOSC/2
OC2CON2 = 0x99; // trigger Mode / source is Comparator C2 / Trigger source Mode: Hardware or Software
while(TRUE);
}
| |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Thu Mar 03, 2022 8:51 am |
|
|
if code is the same, I suspect a compiler 'bug'.
dump both listings and see what is different in the compiled machine code.
BTW...mighty slow PIC speed.... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Thu Mar 03, 2022 9:47 am |
|
|
Not surprised. COMPARE_OFF is the wrong command. You need to be
using COMPARE_CLR_ON_MATCH.
COMPARE_OFF turns off the compare function. You must always read
what the defines say. So:
Code: |
#define COMPARE_OFF 0x0000 // Compare OFF
#define COMPARE_SET_ON_MATCH 0x0001 // Pin from low to high on match
#define COMPARE_CLR_ON_MATCH 0x0002 // Pin from high to low on match
#define COMPARE_TOGGLE 0x0003 // Pin will toggle on every match occurrence
#define COMPARE_SINGLE_PULSE 0x0004 // Pin will generate single pulse on first match
#define COMPARE_CONT_PULSE 0x0005 // Pin will pulse for every match
#define COMPARE_PWM_EDGE 0x0006
#define COMPARE_PWM_CENTER 0x0007
|
|
|
|
andresteff
Joined: 21 Mar 2020 Posts: 44
|
|
Posted: Thu Mar 03, 2022 10:02 am |
|
|
temtronic wrote: | if code is the same, I suspect a compiler 'bug'.
dump both listings and see what is different in the compiled machine code.
BTW...mighty slow PIC speed.... |
The ccs code clear both OC2 registers, OC2CON1 and OC2CON2.
The MCC code clear only OCM Bits (000 = Output compare channel is disabled), but the OCx Mode is not cleared!
And the Fault Mode Select bit is high.
What a diferent!
Code: | ....................
.................... // OC2 = OFF do not works
.................... setup_compare(2, COMPARE_OFF );
0238: CLR 19A
023A: CLR 19C
....................
....................
....................
....................
.................... // OC2 = OFF (config with MCC) WORKS!!! OC2 PIN=low
.................... OC2CON1 = 0x1C08; // OCM Off; OCFLT1 disabled; OCTSEL FOSC/2; TRIGMODE Hardware or Software; and MORE...
023C: MOV #1C08,W4
023E: MOV W4,19A
.................... OC2CON2 = 0x8099; // SYNCSEL CMP2; TRIGSTAT disabled; OCTRIG Trigger; and MORE...
0240: MOV #8099,W4
0242: MOV W4,19C
.................... |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Thu Mar 03, 2022 10:22 am |
|
|
I've already said.
You are telling the compiler to turn off the compare functions. That is what
'COMPARE_OFF' does....
You want to use COMPARE_CLR_ON_MATCH |
|
|
andresteff
Joined: 21 Mar 2020 Posts: 44
|
|
Posted: Thu Mar 03, 2022 12:15 pm |
|
|
Ttelmah wrote: | I've already said.
You are telling the compiler to turn off the compare functions. That is what
'COMPARE_OFF' does....
You want to use COMPARE_CLR_ON_MATCH |
now I use "COMPARE_CLR_ON_MATCH", and indeed the OC2 pin is low, even with the command "setup_compare(2, COMPARE_OFF ); "
But now in the application there are no pulses on the OC2 pin when C2 pulses are fed to the comparator.
With the MCC code you can do exactly that!
Code: |
#include <24F16KA301.h>
#device ADC=8
#device ICSP=3
#device CONST=READ_ONLY
#use delay(clock=500000)
#fuses LPFRC_DIV //Low-Power FRC oscillator with divide-by-N
#FUSES NOBROWNOUT //No brownout reset
#fuses MCLR //Master Clear pin enabled
#fuses PUT //Power Up Timer
#fuses SOSC_DIGITAL //SOSC pins set for Digital mode for use with external clock or Digital I/O
#fuses OSCIO //OSC2 is general purpose output
#WORD OC2CON1 = 0x019A
#WORD OC2CON2 = 0x019C
#bit TRIGSTAT = 0x192.6
void main()
{
setup_oscillator( OSC_LPFRC , 500000);
#use delay(clock=500000)
delay_us(100);
delay_ms(2000);
set_timer1(0);
setup_timer1( T1_EXTERNAL_T1CK | TMR_DIV_BY_1 ); // NOK
// setup_timer1( T1_EXTERNAL_T1CK | TMR_DIV_BY_1 | TMR_EXTERNAL_SYNC ); // OK
output_high(PIN_A4); // led
// OC2 = OFF do not works
setup_compare(2, COMPARE_OFF );
set_compare_time(2, 3, 17);
setup_compare(2, COMPARE_SYSTEM_CLOCK | COMPARE_TRIGGER | COMPARE_TRIG_SYNC_COMP2 | COMPARE_CLR_ON_MATCH ); //OK OC2 is low, but no pulses in while...
// This code generate pulses on OC2
// set_compare_time(2, 3, 17);
// OC2CON1 = 0x1C0F; // Center Alingned PWM Mode / OCSTSEL: FOSC/2
// OC2CON2 = 0x99; // trigger Mode / source is Comparator C2 / Trigger source Mode: Hardware or Software
// external pulses on input comparator C2
setup_vref(VREF_VSS_VDD | 15);
setup_comparator(2, CXINC_VREF | COMP_OUTPUT | COMP_INTR );
// Compa. C2 generates event bit and triggers OC2, and then generates pulses on OC2 output, withfixed pulse width
while(TRUE)
{
C2ENV = 0; // event bit triggers OC2, must clear
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Thu Mar 03, 2022 12:25 pm |
|
|
humour me..don't use that PIC, but curios..
.
I don't use MCC so how did...
.................... // OC2 = OFF (config with MCC) WORKS!!! OC2 PIN=low
.................... OC2CON1 = 0x1C08; // OCM Off; OCFLT1 disabled; OCTSEL FOSC/2; TRIGMODE Hardware or Software; and MORE...
023C: MOV #1C08,W4
023E: MOV W4,19A
.................... OC2CON2 = 0x8099; // SYNCSEL CMP2; TRIGSTAT disabled; OCTRIG Trigger; and MORE...
0240: MOV #8099,W4
0242: MOV W4,19C
MCC decide OSCON1=0x1c08 ??
I have a feeling MCC 'defaults' are not the same as CCS 'defaults'.
If they were, the assembler would be identical ?? |
|
|
|