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 CCS Technical Support

Timer 0 with PIC16LF18326

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



Joined: 01 Apr 2007
Posts: 212

View user's profile Send private message

Timer 0 with PIC16LF18326
PostPosted: Wed Jun 10, 2026 2:25 pm     Reply with quote

PCWHD V5.071
Windows 11 Pro

I have a project working with a PIC16LF1825 that I'm migrating to a PIC16LF18326. Getting more RAM space.

My timer 0 is used as a heartbeat and toggling pin A4 for an LED. It works with the PIC16LF1825 but is not with the PIC16LF18326.

My serial port routine is working correctly so the processor appears to be running at the correct speed. I'm including my test code:

Any suggestions as what I'm doing wrong? Thanks.

Code:

#include <16LF18326.h>

#device adc=10       // 10-bit ADC => 1024 steps
#device *=16

#FUSES NODEBUG       // No Debug mode for ICD
#FUSES WDT_SW        // Watch Dog Timer controlled through setup_wdt()
#FUSES HS            // High speed osc
#FUSES NOPROTECT     // Code not protected from reading
#FUSES NOBROWNOUT    // No brownout reset
#FUSES STVREN        // Stack full/underflow will cause reset
#FUSES NOLVP         // No low volt prgm, B3(PIC16) or B5(PIC18) used for I/O
#FUSES MCLR          // Master Clear pin enabled

#define clk_freq 16000000
#use delay(internal=clk_freq)

#pin_select TX1=PIN_C4
#pin_select RX1=PIN_C5
#use rs232(baud=38400, xmit=PIN_C4, rcv=PIN_C5, parity=N, bits=8)

#define INTS_PER_SEC 61    // clk_freq / (4 * 256 * 256)

// ---- state definitions ----
#define CMD_STATE 0        // command state for serial interface
#define DATA_STATE 1       // data state for serial interface

// ---- define I/O default port data and TRIS parameters ----
#define PA_DEF 0b11001111
#define PA_TRIS 0b11001111
   // 7 : -- : I : NA on 14-pin PIC
   // 6 : -- : I : NA on 14-pin PIC
   // 5 :  2 : O : unused
   // 4 :  3 : O : Heartbeat output
   // 3 :  4 : I : MClr
   // 2 : 11 : I : Int / unused
   // 1 : 12 : I : PClk / unused
   // 0 : 13 : I : PDat / unused

#define HEARTBEAT PIN_A4

#define PC_DEF 0b11100011
#define PC_TRIS 0b11100011
   // 7 : -- : I : NA on 14-pin PIC
   // 6 : -- : I : NA on 14-pin PIC
   // 5 :  5 : I : RXD input from com
   // 4 :  6 : O : TXD output to com
   // 3 :  7 : O : unused
   // 2 :  8 : O : unused
   // 1 :  9 : I : I2C SDA
   // 0 : 10 : I : I2C SCL

#use fast_io(A)
#use fast_io(C)

// ---- variable definitions ----
int1 sFlag;          // TRUE=serial command input ready

char sCmd;           // current serial command
char sState;         // serial input state
char sBuf[20];       // serial data buffer for input command

unsigned int8 sCh;     // terminal serial character value
unsigned int8 sIndex;  // terminal serial buffer index
unsigned int8 secCnt;  // one-second timer counter

unsigned int32 secondsTotal;  // running time, in seconds


// ---- init system variables ----
void InitSys(void)
{
   // init system flags and variables...
   output_a(PA_DEF);
   output_c(PC_DEF);

   secCnt = INTS_PER_SEC;
   sState = CMD_STATE;
   sFlag = FALSE;

   secondsTotal = 0;

   delay_ms(250);                //OLED takes time to wake
}


// ---- serial port interrupt service ----
//  S$     send status
//  H$     display commands / help
#int_RDA
void SerialISR(void)
{
   sCh = toupper(getc());

   if(sState == CMD_STATE)
   {
      sCmd = sCh;              // save the command code
      sIndex = 0;              // init data index
      sState = DATA_STATE;
   }
   else
   {
      sBuf[sIndex++] = sCh;
      if(sCh == '$')           // save character to buffer
      {
         sBuf[sIndex] = '\0';  // overwrite '$' char with null
         sFlag = TRUE;
      }
   }
}


// ---- system clock one-second interrupt routine ----
#int_TIMER0
void ClockISR(void)
{
   secCnt--;
   if(secCnt == 0)
   {
      secCnt = INTS_PER_SEC;     // reinit timer ints per second
      secondsTotal++;            // bump total running time count
     
      output_toggle(HEARTBEAT);
   }
}


// ---- main background routine ----
#zero_ram
void main(void)
{
   setup_adc(ADC_OFF);

   set_tris_a(PA_TRIS);
   set_tris_c(PC_TRIS);

   set_rtcc(0);
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED, 0, 1);

   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   InitSys();

   delay_ms(100);                // system stability time
   
   clear_interrupt(INT_TIMER0);     // clear any pending interrupt
   enable_interrupts(INT_TIMER0);   // enable timer interrupts
   clear_interrupt(INT_RDA);        // clear any pending serial port int
   enable_interrupts(INT_RDA);      // enable the serial port int
   enable_interrupts(GLOBAL);       // global activation of enabled ints
   
   printf("Startup message... Init OK\r\n\r\n");

   while(TRUE) // background
   {
      if(sFlag)
      {
         disable_interrupts(INT_RDA);  // no more serial ints when processing
           
         switch(sCmd)
         {
         case 'S':             // status request command
            printf("PIC16LF18326 Testbed... Init OK\r\n");
            printf("runtime: %lu\r\n\r\n", secondsTotal);
            break;

         case 'H':            // help command
            printf("S$    status\r\n");
            printf("H$    help\r\n\r\n");
            break;
         }

         clear_interrupt(INT_RDA);
         enable_interrupts(INT_RDA);   // reenable serial interrupts

         sFlag = FALSE;
         sState = CMD_STATE;
      }
   }
}
newguy



Joined: 24 Jun 2004
Posts: 1938

View user's profile Send private message

PostPosted: Wed Jun 10, 2026 5:45 pm     Reply with quote

In the pin allocation table that pin's default is to be the CLKOUT for OSC2. Have you tried explicitly disabling OSC2?
starfire151



Joined: 01 Apr 2007
Posts: 212

View user's profile Send private message

PostPosted: Wed Jun 10, 2026 9:02 pm     Reply with quote

Thanks for the response.

How do I tell it to disable OSC2? I didn't see an OSC2 under #FUSES to disable it.

How would I #pin_select A4 as a standard output pin?
Ttelmah



Joined: 11 Mar 2010
Posts: 20089

View user's profile Send private message

PostPosted: Thu Jun 11, 2026 2:27 am     Reply with quote

First, use UART1, rather than the pins in the UART setup.

Then add the line:
SETUP_ADC_PORTS(NO_ANALOGS);
after you disable the ADC

Currently, you are turning off the ADC, but the pins will still be set as
analog.
I suspect this is actually the problem. This chip is one that has ANSEL
bits for every analog pin. Unlike the older PIC's where there is a single
setup to say which pins are analog, on the later chips you need to
specify input pins as analog/digital. By default they are all analog.
The setup_adc_ports command controls the ANSEL bits.

Then add NO_CLOCK_OUT to your #use delay. This should be the default,
but better to be safe.

Get rid of your HS fuse. This is wrong with the internal oscillator.

As a general comment, use The T0 defines for controlling the timer, rather
than the RTCC ones. The latter are obsolete, and are usually still there, but
are advised against now.

There is a slight problem with your clear_interrupt for the INT_RDA.
This interrupt cannot be cleared!.... It is cleared when the character
is read. So if a character has come, this will result in the interrupt
being cleared, and then immediately set again since there is still a
character waiting. If a couple of characters have arrived, you will
then get an error being set in the UART. This won't be cleared.
So add ERRORS to the #USE RS232 setup, which will then mean that
get, will clear an error if one happens.
starfire151



Joined: 01 Apr 2007
Posts: 212

View user's profile Send private message

PostPosted: Thu Jun 11, 2026 5:30 am     Reply with quote

Thanks, very much, for the reply!

I walked down through all your corrections/recommendations one at a time until the problem was resolved. Apparently there was some issue when I was using the older RTCC values in the setup_timer_0(). When I changed them to the newer T0_xx values, the A4 output started toggling, as desired. Specifying no analogs in the setup_adc_ports() was probably also a contributing factor.

After adding setup_adc_ports(NO_ANALOGS); and setup_timer_0(T0_INTERNAL | T0_DIV_256 | T0_8_BIT); in the main() code, the timer 0 ISR started working.

I also removed the line clearing the INT_RDA and specified to use UART1, per your suggestion.

In trying to add NO_CLOCK_OUT in the #use delay(), though, the compiler complai8ned it was not a valid option. This didn't appear to affect operation, though.

Thanks again for the help!
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