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

CCS C + PIC18F26K22 + Timer

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



Joined: 14 Aug 2011
Posts: 36
Location: Somerset, UK

View user's profile Send private message

CCS C + PIC18F26K22 + Timer
PostPosted: Sat Aug 20, 2011 9:18 am     Reply with quote

Hi Guys,

I am having issues trying to get a 1ms timer to work with CCS C, seems to be the higher I wait for, for example 5000ms (5 seconds) it clocks quicker, if I set it to 1000ms(1 second) it seems to delay for 1 second.

I used this:
Code:

#byte timer0low = 0xfd6

#int_RTCC
void RTCC_isr(void) {
timer0low = timer0low + 6;
one_millisecond = TRUE;
}


and also this:
Code:

setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);


64MHZ (16MHZ + 4XPLL).

I also tried Timer 1 instead, but that doesn't seem to work correctly either!

Am I missing something simple? I have read the datasheet, but cant seem to find any timer calcs.

Wilksey
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Aug 20, 2011 2:18 pm     Reply with quote

Quote:

64MHZ (16MHZ + 4XPLL).

RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);

You have Timer0 set as an 8-bit counter. That won't work to get a 1 ms
Timer0 period with a 64 MHz oscillator. Remove that parameter and try
again. Also be aware that Timer0 will clock at 1/4 of the Fosc, which will
be 16 MHz in your case.
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Sat Aug 20, 2011 3:11 pm     Reply with quote

I think the divisions would be OK with 8bit mode, except for the calculations being 'out' by the factor of 4. He is using the /256 prescaler, and adding six in the interrupt handler, to give division by 256*250*4 = 256000, so the interrupt frequency would ideally be 4mSec.
However there are a series of 'caveats':

1) The timing will never be accurate. When you write a timer register, it clears the prescaler, so the timer is going to run significantly slow. Section 9.3 in the data sheet. The effect of this will get larger, the faster you try to run the interrupt.
2) Why fiddle?. Use Timer2. Set it to /16 prescaler, 99 count (/100), and /10 postscaler. 1mSec interrupt without having to fiddle with writing values.

Best Wishes
Wilksey



Joined: 14 Aug 2011
Posts: 36
Location: Somerset, UK

View user's profile Send private message

PostPosted: Sat Aug 20, 2011 4:25 pm     Reply with quote

Thank you PCM and Ttelmah

I can get a 1ms timer, but when I try to count 5000ms it seems to be more like 500ms if that makes sense.

I dont think that register is correct for the PIC i'm using as when I removed that code it didn't make any difference, so I dont think it was writing that 6 to any register.

I got something hashed together with Timer0 (RTCC), it's not ideal though.

So can I only set up Timer2 as my 1ms timer? I understand the FOSC/4.

Would this be correct for Timer2:
setup_timer_2(T2_DIV_BY_16,99,10);

I want a reliable timer for counting and interrupting at 1ms intervals.
Could the same thing not be acheived with timer0,1,3,4,5 etc?

The only issue is that when I count to 1000ms it works as 1 second, but as I said before 5000ms (5 seconds) only counts half a second, is this a 8/16 bit thing?
Wilksey



Joined: 14 Aug 2011
Posts: 36
Location: Somerset, UK

View user's profile Send private message

PostPosted: Sat Aug 20, 2011 4:54 pm     Reply with quote

Ttelmah,

I just tried your Timer2 settings and it is way to fast, seems less than 1/2 a second!

main.c
Code:

#include <main.h>

#int_TIMER2
void rtcc_timer2(void)
{
   milliseconds++;
}
void main()
{
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);
   //setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_bit);      //1.0 ms overflow
   setup_timer_2(T2_DIV_BY_16,99,10);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_timer_4(T4_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
   delay_ms(50);
   while(1)
   {
      if(milliseconds == 1000)
      {
         printf("Output...\r\n");
         milliseconds = 0;
      }
   }
}

main.h
Code:

#include <18F26K22.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES PLLEN                  //4X HW PLL disabled, 4X PLL enabled in software
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#FUSES IESO                     //Internal External Switch Over mode disabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
#FUSES MCLR                     //Master Clear pin used for I/O
#FUSES NOSTVREN                 //Stack full/underflow will not cause reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=64MHz)

#use rs232(baud=38400,parity=N, UART1, bits=8)

int8 milliseconds = 0;


Wilksey
Wilksey



Joined: 14 Aug 2011
Posts: 36
Location: Somerset, UK

View user's profile Send private message

PostPosted: Sat Aug 20, 2011 4:59 pm     Reply with quote

PCM, just tried your suggestion of removing the RTCC_8_BIT flag, and the timer interrupt doesn't fire at all without this!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Aug 20, 2011 6:01 pm     Reply with quote

Quote:
int8 milliseconds = 0;

if(milliseconds == 1000)

What's wrong here ? Data types, data types, data types.

Download the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Look on page 43 (page 57 in the Acrobat reader). Look at this section:
Quote:
Basic and Special types

Note the range of each data type.
Wilksey



Joined: 14 Aug 2011
Posts: 36
Location: Somerset, UK

View user's profile Send private message

PostPosted: Sat Aug 20, 2011 6:40 pm     Reply with quote

Hmmm...I see what you're saying...i'm an idiot!!

So, I changed it to int16, and it still isn't giving me quite what I need.

The timer2 code still doesn't work, in fact it doesn't appear to fire at all!

If I remove the RTCC_8_BIT from timer0 code, I have to set RTCC_DIV_1 to get a 4/5 ms delay, but can't seem to acheive 1ms still.

Wilksey
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Sun Aug 21, 2011 2:27 am     Reply with quote

One thing I notice, you have the comment 'Master Clear pin used for I/O', but have the fuse 'MCLR' which means the master clear pin is enabled, and you must have a pull-up on the master clear pin.

I'd add:
setup_oscillator(OSC_64MHz);

as the first line of the main code. Some compiler versions don't turn the software PLL on, without this.

Don't enable the interrupts, until you have set them up. Won't matter really (just risks an extra trigger), but 'bad practice'.

One thing I notice, is you don't have the NOPBADEN fuse, which means port B will wake up as analog by default.

I rewrote the code to generate a 5 second time using a 1mSec tick on Timer2, as:
Code:

#include <18F25K22.h>
#FUSES NOWDT, WDT128, INTRC_IO, NOFCMEN, NOIESO, BORV42, WDT_NOSLEEP, NOPBADEN, NOLPT1OSC, NOHFOFST, NOMCLR, NOLVP, NOXINST
#use delay(clock=64000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1,errors)

int16 milliseconds=5000;
#int_timer2
void tick(void) {
   if (milliseconds) --milliseconds;
}

void main()
{
   setup_oscillator(OSC_64MHZ);
   setup_timer_4(T4_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_timer_2(T2_DIV_BY_16,99,10);
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);
   do {
      if (milliseconds==0) {
         milliseconds=5000;
         printf("5 seconds\n\r");
      }
   } while(TRUE);
}

and it merrily displays '5 seconds' on the serial, every 5 seconds exactly.

Using the 'countdown', makes it impossible for the value to be missed if the main loop takes too long (doesn't apply here).

Best Wishes
Wilksey



Joined: 14 Aug 2011
Posts: 36
Location: Somerset, UK

View user's profile Send private message

PostPosted: Sun Aug 21, 2011 5:07 pm     Reply with quote

Hi Ttelmah,

Thank you for your reply, I will check your code and see what it does on my board.

Can the code count up instead of down?

I tried adding the setup_oscillator to 64MHZ, but doesn't make any difference, both UARTS i have tried work fine, so im guessing the crystal setting is ok as if it wasn't i'd get garbage.

MCLR is pulled to +5V with a 10k pull up.

I dont think portb pullups are an issue, but I will add that fuse setting in for good practice!

Although, doesn't this override it?
Code:

setup_adc(ADC_OFF | NO_ANALOGS);


Wilksey
Wilksey



Joined: 14 Aug 2011
Posts: 36
Location: Somerset, UK

View user's profile Send private message

PostPosted: Sun Aug 21, 2011 6:08 pm     Reply with quote

Hi,

Just tried your code, changed the header to the 26K22, had to remove one of the fuses, cause it didn't exist on my chip, it just sits there and does nothing, I have tested the UART and it works ok, but your code just sits and does nothing?

Wilksey
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Mon Aug 22, 2011 1:47 am     Reply with quote

What compiler version have you got?.
The fuses should be right. The 25K, and the 26K are identical, except the 26K has more memory. The code ran exactly as it is on a 25K, and compiles with no changes at all to run on a 26K. I wonder if you have an early compiler for the 26K, which has problems setting the chip up....

Best Wishes
Wilksey



Joined: 14 Aug 2011
Posts: 36
Location: Somerset, UK

View user's profile Send private message

PostPosted: Mon Aug 22, 2011 10:08 am     Reply with quote

It was this fuse that caused errors:
NOLPT1OSC

I use 4.120

Thanks

Wilksey
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Aug 22, 2011 1:47 pm     Reply with quote

I was able to make Ttelmah's code work with vs. 4.120 with the following
changes (in various places below). This is the program output:
Quote:

Start:
5 seconds
5 seconds
5 seconds
5 seconds

Here is the test program:
Code:

#include <18F45K22.h>
#FUSES INTRC_IO, NOWDT, BROWNOUT, PUT, NOPBADEN, NOHFOFST
#use delay(clock=64M)
#use rs232(baud=9600, UART1, ERRORS)

#byte OSCCON2 = getenv("SFR:OSCCON2")
#bit PLLRDY = OSCCON2.7

int16 milliseconds=5000;

#int_timer2
void tick(void)
{
if(milliseconds)
   --milliseconds;
}

//=========================
void main()
{
while(!PLLRDY);  // Wait until 64 MHz osc is running OK

printf("\n\rStart: \n\r");

setup_timer_2(T2_DIV_BY_16,99,10);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);

do{
   if(milliseconds==0)
     {
      milliseconds=5000;
      printf("5 seconds\n\r");
     }
   }while(TRUE);

}

Note that testing the PLLRDY bit at the start of main() was the only way
I could get the program to display "Start" correctly at the beginning
of the program. I tried other methods and they didn't work.
Wilksey



Joined: 14 Aug 2011
Posts: 36
Location: Somerset, UK

View user's profile Send private message

PostPosted: Mon Aug 22, 2011 4:00 pm     Reply with quote

Thanks PCM

I will try that code on my board tomorrow!

Thanks to both of you for all of your patience and help so far!!

Wilksey
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