View previous topic :: View next topic |
Author |
Message |
PAPA
Joined: 27 Jun 2019 Posts: 5 Location: Portugal
|
PIC16F18875 - Strange Problem with TIMER 1 setup |
Posted: Thu Jun 27, 2019 12:52 pm |
|
|
Hello All,
I need some help.
I have a problem when I try to setup the timer 1 using the SETUP_TIMER1() function and also when I try to write the memory register.
When I start the PIC microcontroller the CPU blocks and the code inside the while(true) is not executed. If I comment the Setup_Timer1() the CPU doesn´t block but the timer interrupt is not executed as I wanted.
CCS compiler version: 5.073
Code using the SETUP_TIMER1:
Code: |
#include <16F18875.h>
#device ADC=10
#FUSES NOBROWNOUT
#FUSES NOLVP
#FUSES HS
#FUSES NOWDT
#use delay(crystal=10000000)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#pin_select U1TX=PIN_C6
#pin_select U1RX=PIN_C7
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)
#define LEDRED PIN_C1
int aux=0;
#INT_RDA
void trata_INT_RDA()
{
output_toggle(LEDYEL);
}
#INT_TIMER1
void trata_1()
{
aux++;
if(aux>10)
{
output_toggle(LEDRED);
aux=0;
}
set_timer1(3036);
}
void main()
{
set_tris_a(0b10110011);
set_tris_b(0b00110010);
set_tris_c(0b10101100);
set_tris_d(0b10001011);
set_tris_e(0b00000110);
setup_adc(ADC_CLOCK_DIV_8);
setup_adc_ports(sAN0 | sAN1 | sAN9 | sAN12 | sAN13 | sAN21 | 0x00000008 | 0x00000080); //A0 A1 B1 B4 B5 C5 D3 D7
SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_4);
SET_TIMER1(3036);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_RDA);
enable_interrupts(global);
while(TRUE)
{
output_toggle(LEDYEL);
delay_ms(500);
//TODO: User Code
}
|
Code for configure the Timer1 writing the memory register
Code: |
#include <16F18875.h>
#device ADC=10
#FUSES NOBROWNOUT
#FUSES NOLVP
#FUSES HS
#FUSES NOWDT
#use delay(crystal=10000000)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#pin_select U1TX=PIN_C6
#pin_select U1RX=PIN_C7
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)
#byte T1CON = 0x20E //For Register configuration
#byte T1CLK = 0x211
#define LEDRED PIN_C1
int aux=0;
#INT_RDA
void trata_INT_RDA()
{
output_toggle(LEDYEL);
}
#INT_TIMER1
void trata_1()
{
aux++;
if(aux>10)
{
output_toggle(LEDRED);
aux=0;
}
set_timer1(3036);
}
void main()
{
set_tris_a(0b10110011);
set_tris_b(0b00110010);
set_tris_c(0b10101100);
set_tris_d(0b10001011);
set_tris_e(0b00000110);
setup_adc(ADC_CLOCK_DIV_8);
setup_adc_ports(sAN0 | sAN1 | sAN9 | sAN12 | sAN13 | sAN21 | 0x00000008 | 0x00000080); //A0 A1 B1 B4 B5 C5 D3 D7
T1CON = 0b00100011; // T1_INTERNAL | T1_DIV_BY_4
T1CLK = 0b00000001; //Fosc/4
SET_TIMER1(3036);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_RDA);
enable_interrupts(global);
while(TRUE)
{
output_toggle(LEDYEL);
delay_ms(500);
//TODO: User Code
}
|
Thanks in advanced _________________ Always looking to the future |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 27, 2019 5:47 pm |
|
|
You need to fix this:
Quote: | #INT_RDA
void trata_INT_RDA()
{
output_toggle(LEDYEL);
} |
You must get the character in the interrupt.
As a bare minimum, you need to do this:
Code: |
void trata_INT_RDA()
{
int8 c;
c = fgetc(PORT1);
output_toggle(LEDYEL);
}
|
This will throw away the character after getting it, but at least your
program will not lock up.
Also, you should add the ERRORS parameter to your #use rs232()
statement. |
|
|
PAPA
Joined: 27 Jun 2019 Posts: 5 Location: Portugal
|
|
Posted: Fri Jun 28, 2019 1:52 am |
|
|
PCM programmer wrote: | You need to fix this:
Quote: | #INT_RDA
void trata_INT_RDA()
{
output_toggle(LEDYEL);
} |
You must get the character in the interrupt.
As a bare minimum, you need to do this:
Code: |
void trata_INT_RDA()
{
int8 c;
c = fgetc(PORT1);
output_toggle(LEDYEL);
}
|
This will throw away the character after getting it, but at least your
program will not lock up.
Also, you should add the ERRORS parameter to your #use rs232()
statement. |
Hello,
I noticed that mistakes but the main problem is relate with the timer 1 setup that after configuration the PIC blocks and nothing happen, the function inside the while (true) is not executed.
Code: |
output_toggle(LEDYEL);
delay_ms(500);
|
Are there any special bits configuration for the timer 1 in this PIC? _________________ Always looking to the future |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 28, 2019 2:28 am |
|
|
I would have install your version, 5.073, which is about 2 years old and
look at the .LST file. I can do that tomorrow. |
|
|
PAPA
Joined: 27 Jun 2019 Posts: 5 Location: Portugal
|
|
Posted: Fri Jun 28, 2019 5:04 am |
|
|
PCM programmer wrote: | I would have install your version, 5.073, which is about 2 years old and
look at the .LST file. I can do that tomorrow. |
I've tested the timer 0, and to put it works properly I needed to enable interrupts Peripheral.
But with timer1 the problem persist.
I don´t know if it can help, but below you can see some of the .lst output
Code: |
.................... setup_timer_1(T1_INTERNAL | T1_DIV_BY_4 ); //16bits
086B: MOVLW 01
086C: MOVLB 04
086D: MOVWF 11
086E: MOVLW 27
086F: MOVWF 0E
0870: CLRF 0F
0871: CLRF 10
.................... SET_TIMER1(3036);
0872: CLRF 0C
0873: MOVLW 0B
0874: MOVWF 0D
0875: MOVLW DC
0876: MOVWF 0C
....................
.................... enable_interrupts(INT_TIMER1);
0877: MOVLB 0E
0878: BSF 1A.0
.................... enable_interrupts(INT_RDA);
0879: BSF 19.5
.................... enable_interrupts(global);
087A: MOVLW C0
087B: IORWF 0B,F
....................
.................... enable_interrupts(PERIPH);
087C: BSF 0B.6
|
Thanks _________________ Always looking to the future |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Fri Jun 28, 2019 7:51 am |
|
|
sigh...
this ... enable interrupts Peripheral...
... must be a 'new' PIC thing.
gets me wondering if there's more than one 'enable interrupts Peripheral.' command needed, as an SFR holds 8 bit , what if there's 10 peripherals ?
guess I'm getting cynical in my old age...
Jay |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Fri Jun 28, 2019 8:18 am |
|
|
Hmmm, I don't recall ever doing any enable_interrupts(PERIPH). I assume that's the PEIE bit in INTCON. Looks like it's a "global peripherals enable" kind of bit.
I used PIC16F1939 and PIC16F19175/76 which at a cursory glance appears to have the same interrupt structure. It appears to need PEIE = 1 even though I never set that bit before. It could be that the compiler automatically sets that, so I never paid attention. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 28, 2019 4:07 pm |
|
|
I installed CCS vs. 5.085 and compiled the first program posted.
It works. It blinks the two LEDs at different rates. The Timer1 blinks
at an apparent rate of about 1/2 Hz. It's on for roughly 1 second and off
for roughly 1 second.
I will now check it with vs. 5.073. This is a 2-year old version of the compiler. |
|
|
PAPA
Joined: 27 Jun 2019 Posts: 5 Location: Portugal
|
|
Posted: Fri Jun 28, 2019 5:28 pm |
|
|
PCM programmer wrote: | I installed CCS vs. 5.085 and compiled the first program posted.
It works. It blinks the two LEDs at different rates. The Timer1 blinks
at an apparent rate of about 1/2 Hz. It's on for roughly 1 second and off
for roughly 1 second.
I will now check it with vs. 5.073. This is a 2-year old version of the compiler. |
yes, that is how the program works.
It seems to be some problem with the compiler version, I look forward your test results and possible solutions to handle it.
Thanks _________________ Always looking to the future |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jun 29, 2019 3:12 am |
|
|
Vs. 5.073 doesn't clear the Timer1 interrupt flag when it exits the isr.
Instead it clears bit 0 in PortE. This is caused by an incorrect bank
selection. To fix it, you can add the line shown below. But the CCS code
will still be write a 0 to bit 0 of Port E. That bug is still there.
Quote: | #INT_TIMER1
void trata_1()
{
aux++;
if(aux>10)
{
output_toggle(LEDRED);
aux=0;
}
set_timer1(3036);
clear_interrupt(INT_TIMER1);
}
|
There are probably more bugs. I suggest you upgrade your compiler. |
|
|
PAPA
Joined: 27 Jun 2019 Posts: 5 Location: Portugal
|
|
Posted: Sat Jun 29, 2019 6:43 am |
|
|
PCM programmer wrote: | Vs. 5.073 doesn't clear the Timer1 interrupt flag when it exits the isr.
Instead it clears bit 0 in PortE. This is caused by an incorrect bank
selection. To fix it, you can add the line shown below. But the CCS code
will still be write a 0 to bit 0 of Port E. That bug is still there.
Quote: | #INT_TIMER1
void trata_1()
{
aux++;
if(aux>10)
{
output_toggle(LEDRED);
aux=0;
}
set_timer1(3036);
clear_interrupt(INT_TIMER1);
}
|
There are probably more bugs. I suggest you upgrade your compiler. |
Thank you for your help, I'll consider your suggestion. _________________ Always looking to the future |
|
|
|