CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PIC16F18875 - Strange Problem with TIMER 1 setup

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PAPA



Joined: 27 Jun 2019
Posts: 5
Location: Portugal

View user's profile Send private message

PIC16F18875 - Strange Problem with TIMER 1 setup
PostPosted: Thu Jun 27, 2019 12:52 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jun 27, 2019 5:47 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 28, 2019 1:52 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 28, 2019 2:28 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 28, 2019 5:04 am     Reply with quote

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: 9097
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jun 28, 2019 7:51 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Fri Jun 28, 2019 8:18 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 28, 2019 4:07 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 28, 2019 5:28 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 29, 2019 3:12 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 29, 2019 6:43 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group