View previous topic :: View next topic |
Author |
Message |
dmitrboristuk
Joined: 26 Sep 2020 Posts: 51
|
PIC16F1719 The influence of the Timer1 on comparator |
Posted: Sun Apr 04, 2021 6:57 am |
|
|
Hello!
I ran into such a problem that the settings of Timer 1 and CCP1 affect the comparator interrupts. My simplified code.
When I remove the lines from the code
Code: | // SETUP_TIMER_1(T1_FOSC | T1_DIV_BY_8);
// SETUP_CCP1(CCP_COMPARE_INT); |
The delayed signal from the comparator interrupt on pin B1 is working normally
If I remove the line from the code
Code: | // SETUP_CCP1(CCP_COMPARE_INT); |
The signal on pin B1 is delayed for more than 1 second
What could be the reason for this behavior?
Code: |
#include <1719_comparator.h>
#bit C1OUT = 0x111.6
#pin_select C1OUT = PIN_A6
int1 mm = 0;
#INT_COMP
void isrCOMP()
{
output_high(PIN_B1);
mm = 1;
}
#INT_CCP1
void isrccp1()
{
}
void main()
{
setup_oscillator( OSC_16MHZ |
OSC_INTRC |
OSC_PLL_OFF );
setup_comparator(
CP1_FVR_A2
| CP1_INT_L2H
// | CP1_INT_H2L
// | CP1_INVERT
// | CP1_FILTER
// | CP1_FAST
// | CP1_HYST
// | CP1_SYNC
);
setup_vref ( VREF_ON
| VREF_ADC_1v024
| VREF_COMP_DAC_2v048
| TEMPERATURE_INDICATOR_DISABLED
);
SETUP_TIMER_1(T1_FOSC | T1_DIV_BY_8);
SETUP_CCP1(CCP_COMPARE_INT);
enable_interrupts(INT_CCP1);
enable_interrupts(INT_COMP);
// clear_interrupt (INT_COMP);
enable_interrupts(GLOBAL);
while(TRUE)
{
if ( mm == 1 && C1OUT == 0)
{
delay_ms (1000);
output_low(PIN_B1);
mm = 0;
}
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 04, 2021 10:41 pm |
|
|
What's your CCS compiler version ? If it's old enough the register
addresses could be incorrect. With the version number, this can be
checked. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Mon Apr 05, 2021 1:27 am |
|
|
There are though 'issues' with what he is trying to do.
He sets up the CCP to interrupt on all events, but has not programmed
the CCP1 input pin. Generally any peripheral that 'supports' PPS, even
if you want to use the 'default' pin, you should explicitly set it with CCS.
Then he sets up C1OUT, two different ways. The compiler will complain
there is a duplicate locate for this. He should not use the compiler defined
name for the read of this pin.
Then, the chip requires that the clock source for timer1 is synchronous
if it is used with the CCP. Now Fosc does not guarantee this. The sync
source uses FOSC/2, so an Fosc clock could change half way through the
cycle. So change this to:
SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_2);
This gives exactly the same resultant rate (/4/2), but the clock source
is then guaranteed to be synchronous to the instruction clock.
Now one would 'instinctively' think that the /8 prescaler would guarantee
synchronisation, but I can't see anywhere which actual clock edge is
used by the prescaler, so it is possible it doesn't.....
So I'd try:
Code: |
#bit C1RDOUT = getenv("BIT:C1OUT")
#PIN_SELECT CCP1 = PIN_C2
#pin_select C1OUT = PIN_A6
int1 mm = 0;
#INT_COMP
void isrCOMP()
{
output_high(PIN_B1);
mm = 1;
}
#INT_CCP1
void isrccp1()
{
}
void main()
{
setup_oscillator( OSC_16MHZ |
OSC_INTRC |
OSC_PLL_OFF );
setup_comparator(
CP1_FVR_A2
| CP1_INT_L2H
// | CP1_INT_H2L
// | CP1_INVERT
// | CP1_FILTER
// | CP1_FAST
// | CP1_HYST
// | CP1_SYNC
);
setup_vref ( VREF_ON
| VREF_ADC_1v024
| VREF_COMP_DAC_2v048
| TEMPERATURE_INDICATOR_DISABLED
);
SETUP_TIMER_1(T1_FOSC | T1_DIV_BY_8);
SETUP_CCP1(CCP_COMPARE_INT);
enable_interrupts(INT_CCP1);
enable_interrupts(INT_COMP);
// clear_interrupt (INT_COMP);
enable_interrupts(GLOBAL);
while(TRUE)
{
if ( mm == 1 && C1RDOUT == 0)
{
delay_ms (1000);
output_low(PIN_B1);
mm = 0;
}
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
dmitrboristuk
Joined: 26 Sep 2020 Posts: 51
|
|
Posted: Mon Apr 05, 2021 2:25 am |
|
|
Thanks for answers!
I tried the code it didn't give me the expected effect. I will look for new ways to fix this problem. Perhaps this is due to the fact that CCP1 begins to randomly generate interrupts because it is not fully configured. Compiler version 5.093. |
|
![](templates/subSilver/images/spacer.gif) |
dmitrboristuk
Joined: 26 Sep 2020 Posts: 51
|
|
Posted: Thu Apr 22, 2021 2:38 am |
|
|
There was another problem in v5.93
It is not possible to output the COGB, COGC, COGD signal to port D and output the PWM3 signal to port E. When viewing the assembly code, blank lines are visible there. Tell me how to do it manually
Code: |
C
#pin_select COGD = PIN_D0
ASM
0024: MOVLW 55
0025: MOVLB 1C
0026: MOVWF PPSLOCK
0027: MOVLW AA
0028: MOVWF PPSLOCK
0029: BCF PPSLOCK.PPSLOCKED
002A: MOVLW 55
002B: MOVWF PPSLOCK
002C: MOVLW AA
002D: MOVWF PPSLOCK
002E: BSF PPSLOCK.PPSLOCKED
|
Code: |
#pin_select PWM3OUT = PIN_E1
error: Invalid Pre-Processor directive Invalid Pin
|
What is the point of writing to the PPSLOCK register 01010101 and 10101010 if there is only one bit in this register? What was the idea of the developers? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Thu Apr 22, 2021 3:34 am |
|
|
Switch to using the inline pin_select command, rather than the # version.
So near the start of your main code:
pin_select("COGD", PIN_D0);
You'll find that this adds the lines to actually make the selection.
Now the portE one is interesting. For PPS inputs, PortE, is not supported at
all, yet the data sheet does show it as available for output selection. It
looks as if the compiler thinks it is not available for output selection.
This shows a crude routine to put a particular value to the E1 PPS:
Code: |
#byte PPSLOCK=getenv("SFR:PPSLOCK")
#bit PPSLOCKED=getenv("BIT:PPSLOCKED")
#bit GIE=getenv("BIT:GIE")
#byte RE0PPS=getenv("SFR:RE0PPS")
#byte RE1PPS=getenv("SFR:RE1PPS")
#byte RE2PPS=getenv("SFR:RE2PPS")
#define PWM3OP 0b01110 //PPS value for this selection - different name to avoid clash
void val_to_ppsE1(int8 val)
{
//feed a specific selection value to a PPS port
//Global interrupts must be disabled for this, and NOPPS1WAY will need to be
//selected.
int1 INT_ENABLED;
INT_ENABLED=GIE; //save GIE bit
disable_interrupts(GLOBAL);
PPSLOCK=0x55;
PPSLOCK=0xAA;
PPSLOCKED=FALSE; //unlock PPS
RE1PPS=val; //send to E1
PPSLOCK=0x55;
PPSLOCK=0xAA;
PPSLOCKED=TRUE; //lock PPS
if (INT_ENABLED)
enable_interrupts(GLOBAL); //re enable interrupts if needed
}
void main()
{
pin_select("COGD", PIN_D0);
val_to_ppsE1(PWM3OP);
while(TRUE)
{
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
dmitrboristuk
Joined: 26 Sep 2020 Posts: 51
|
|
Posted: Thu Apr 22, 2021 3:39 am |
|
|
Ttelmah, Thanks, I will try this.
Port E is not even in the driver at 16f1719.h
According to the datasheet, port E is only for PWM3
For SOG(B-D) port B and port D |
|
![](templates/subSilver/images/spacer.gif) |
dmitrboristuk
Joined: 26 Sep 2020 Posts: 51
|
|
Posted: Fri Apr 23, 2021 12:05 am |
|
|
I tried pin_select(), it does not work on this controller. For COG and PWM3. I've tried assigning pin to port B and port D. There is no effect. The function to assign PWM3 pin to port E also does not work. I asked to check your code for v5.101, the received firmware also did not work. #pin_select is worked only for port B (and port C for COGA).
Device is real. Also I was manipulating with PPS1Way / noPPS1WAY |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
PPS and CCS |
Posted: Mon Apr 26, 2021 5:45 pm |
|
|
I spent a few bad days struggling with PPS setups on that very same chip two months ago, because a client requested it- all with up to date versions of the compiler. Finally packed it in and moved the code to an 18f46k22 since i didn't actually need any of the peripheral features, and power consumption didn't matter. I like running the core at 64mhz for floating point calcs too- all starting with an 8.388608 MHz clock/rock. PPS still feels like a work in progress for CCS and avoiding it is now mission one for me. |
|
![](templates/subSilver/images/spacer.gif) |
|