 |
 |
| View previous topic :: View next topic |
| Author |
Message |
starfire151
Joined: 01 Apr 2007 Posts: 212
|
| Timer 0 with PIC16LF18326 |
Posted: Wed Jun 10, 2026 2:25 pm |
|
|
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
|
|
Posted: Wed Jun 10, 2026 5:45 pm |
|
|
| 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
|
|
Posted: Wed Jun 10, 2026 9:02 pm |
|
|
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
|
|
Posted: Thu Jun 11, 2026 2:27 am |
|
|
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
|
|
Posted: Thu Jun 11, 2026 5:30 am |
|
|
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! |
|
 |
|
|
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
|