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

timer0 with 12f675

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



Joined: 17 Jun 2011
Posts: 12

View user's profile Send private message

timer0 with 12f675
PostPosted: Fri Jun 17, 2011 1:06 am     Reply with quote

Hi guys, I've got a problem that is really pissing me off! I'm trying to enable timer0 interruptions with pic 12f675, I've searched and tried all possible examples, but nothing seems to work. This is my code:
Code:

#include <12F675.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOMCLR                   //No Master Clear pin
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD   

#use delay(int=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_A1,rcv=PIN_A0,bits=8,stream=comPort)

#define LED   PIN_A2

#int_TIMER0


void  TIMER0_isr(void)
{
   disable_interrupts(INT_TIMER0);
   printf("working!");
   enable_interrupts(INT_TIMER0);
}

void main()
{
   delay_ms(100);
   setup_comparator(NC_NC);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4|RTCC_8_bit);      //1.0 ms
   printf("about to enable interrupt!");
   enable_interrupts(INT_TIMER0); // The program stops in this line!
   enable_interrupts(GLOBAL);
 
   char string[20]; // Buffer
   while(true)
   {
       if(kbhit()){ // check for new character
         gets(string);
         puts(string);
      }
   }
}

When I run the program I only see in my screen "about to enable interrupt!" over and over again. As far as I understand, the code inside "TIMER0_isr()" should be executed every 1 ms... right??

My other question is... how can I use "get_timer0()" ?? I'm really confused with this... I reckon I need a lot of help!


Thanks!
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Fri Jun 17, 2011 3:20 am     Reply with quote

First big problem. Don't print in the ISR. The PIC does not support re-entrant code. Printf, is using putc. Hence interrupts _will_ be disabled in all the external code wherever you output data.
Second (non important), generally, don't disable/enable interrupts in the ISR.
Third problem. Remember how long things take. 'Working!', at 9600bps, takes 8.33mSec to send.....
Fourth, remember this chip does not have a UART. 'kbhit', _must_ be called at least 20000 times per second, if characters are not to be missed. What is going to happen with interrupts taking 8+mSec are being called...
Are you sure your RS232 input line is being pulled high?. If not the code will loop forever.
You really need to use a chip with a hardware UART, to make what you show even begin to work, but as a crude 'near miss':
Code:

#include <12F675.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOMCLR                   //No Master Clear pin
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD   

#use delay(int=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_A1,rcv=PIN_A0,bits=8,DISABLE_INTS)

#define LED   PIN_A2

int16 tick=1000;
int1 one_sec=FALSE;

#int_TIMER0
void  TIMER0_isr(void) {
  if (tick) --tick;
  else {
    tick=1000;
    one_sec=TRUE;
  }
}

void main()
   char buffer[20];
   delay_ms(100);
   setup_comparator(NC_NC);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4|RTCC_8_bit);      //1.0 ms
 
   // Don't declare variables mid code - char string[20]; // Buffer

   while (input(PIN_A0)) {
      printf("Serial input is high - cannot continue/n/r");
      delay_ms(1000);
   }

   printf("about to enable interrupt!/n/r");
   enable_interrupts(INT_TIMER0); // The program stops in this line!
   enable_interrupts(GLOBAL);

   do {
       if(kbhit()){ // check for new character
         gets(string);
         puts(string);
      }
      if (one_sec) {
         one_sec=FALSE;
         printf("T");
      }
   } while(TRUE);
}

This will still miss characters on the input, if the 'T' display is called at the moment you type, but at least has a chance.....
Some parts are purely 'cosmetic'. The 'do while' construct avoids the compiler error message about condition always true.
Use of 'inline' variable declarations is 'borderline'. C does not support them. C++ does. CCS stopped complaining about them a while ago, _but_ they still cause problems in more complex code - better to stick to standard C practice here....
The disable_ints option on the RS232, will mean that the tick will be delayed till the end of each character when sending/receiving. Without this, characters _will_ be distorted by the interrupt.
Note the test for the RX line going high before starting.
Since you are not using streams in your I/O, don't declare them.

Best Wishes
alex323qp



Joined: 17 Jun 2011
Posts: 12

View user's profile Send private message

PostPosted: Wed Jun 22, 2011 5:07 am     Reply with quote

Hi Ttelmah, thanks for your reply and sorry for my delay...

All about rs232 and printf was just for give an example, the real problem is that the program doesn't continue after activating interrupts (enable_interrupts(INT_TIMER0);). Even your code seems to do the same...


However, I noticed that apparently the PIC is reseting itself over and over again, cos I get the same message continuously "about to enable interrupt!". So I wonder if it's because of not defined fuses or something like that.

Really appreciate any further help!
alex323qp



Joined: 17 Jun 2011
Posts: 12

View user's profile Send private message

PostPosted: Tue Jul 05, 2011 7:56 pm     Reply with quote

Guys, still having problems... nobody?? really?

I updated my code to check my theory about resetting...
Code:

void main()
{
   int8 t = restart_cause();
   switch (t)
   {
      case NORMAL_POWER_UP:
         puts("Starting...");
         break;
      case MCLR_FROM_RUN:
         puts ("from run!");
         break;
      case WDT_TIMEOUT:
         puts("Time out!");
         break;
      default:
         printf("Value: %d", t);
         break;
   }
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4|RTCC_8_bit);      //1.0 ms overflow
   setup_comparator(NC_NC);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   while(true);
   
}

And in fact, I'm getting: "Starting..." the first time, and "from run!" over and over again. It means the chip is resetting itself (I guess every 1 ms) and It is never reaching TIMER0_isr(void).

Please please, what am I doing wrong??
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 05, 2011 8:56 pm     Reply with quote

What is the Vdd voltage on the PIC ? Is it +5v ?
Is a clean, stable Vdd voltage ? Or does it have noise on it ?
alex323qp



Joined: 17 Jun 2011
Posts: 12

View user's profile Send private message

PostPosted: Tue Jul 05, 2011 9:03 pm     Reply with quote

Vdd is 3V, from 2 AA batteries... The only 2 devices connected are a xbee module and the pic itself. So I reckon it doesn't have any noise.

I also tested the circuit with 5V from a regulated power supply, but the result is the same.

Any ideas?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 05, 2011 9:25 pm     Reply with quote

1. What is your CCS compiler version ?

2. What are you using for a programmer ? ICD2 ? Pickit 2 ? ICD-U40 ?
Or something else ?

3. What Windows program are you using to run your programmer ?
MPLAB ? CCS IDE ? or something else ?

4. Read the 12F675 with your programmer and examine the Config bits
that it reports. What are they ? Is it possible that the WDT is enabled ?

5. After you read the 12F675 with your programmer, look at program
memory address 0x3FF. What is the value of the hex word that is
programmed at that address ?
alex323qp



Joined: 17 Jun 2011
Posts: 12

View user's profile Send private message

PostPosted: Tue Jul 05, 2011 10:19 pm     Reply with quote

PCM Programmer, this is my configuration:

1. PCM Compiler V4.114

2. I'm using a usb programmer compatible with K149, this is it:
http://www.ebay.com.au/itm/USB-Interface-PIC-Programmer-40-ZIF-Microchip-K149-JDM-/330579620150?pt=AU_B_I_Electrical_Test_Equipment&hash=item4cf814b136#ht_2703wt_907


3. I'm using DIY K149-BC PICmicro Programmer V141204

4. WDT=Disabled, MCLRE=Disabled, Code Protect ROM=Disabled, PWRTE=Enabled, Oscillator=INTOSC

5. 0x3FF = 3440


On the other hand, I added this to my program:

set_timer0(6);
while(true){
if(get_timer0() > 254){
set_timer0(6);
onTick();
}
}

and removed the line "enable_interrupts(INT_RTCC);"

It seems to be working properly, it calls "onTick()" every 1 ms... however, I would like to make it work as everybody else, I mean without asking for "get_timer0()".

Thanks for your help.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 05, 2011 10:59 pm     Reply with quote

Post your current test program that shows the failure. It should have
the #include for the PIC, #fuses, #use statements, variable declarations,
main(), etc.
alex323qp



Joined: 17 Jun 2011
Posts: 12

View user's profile Send private message

PostPosted: Wed Jul 06, 2011 2:02 am     Reply with quote

Ok, this is the original code without the modifications I mentioned before:
Code:

#include <12F675.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOMCLR                     //Master Clear pin enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection

#use delay(int=4000000)

#define XBEE_IN   PIN_A0
#define XBEE_OUT   PIN_A1
#define LED   PIN_A2
#define SW1   PIN_A3
#use rs232(baud=9600,parity=N,xmit=XBEE_OUT,rcv=XBEE_IN,bits=8,stream=xbee)


//test.c
#include <test.h>
#int_TIMER0
int16 time=0;

void TIMER0_isr()
{
    output_high(LED);
    time++;
}

void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4|RTCC_8_bit);      //1.0 ms overflow
   setup_comparator(NC_NC);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   
   while(true)
   {
      if(time > 1000)
         {
            time = 0;
            puts("1s");
         }
   }
}

After several tests, I'm sure TIMER0_isr is never called (LED is never ON). The pic is reseted after (I guess) 1ms. Thus, I never receive "1s".

Hope you can help me.
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Wed Jul 06, 2011 2:25 am     Reply with quote

A couple of things:
1) move the variable declaration above the INT declaration.
The #INT line, should be the line immediately above the function it applies to. Don't know if having a variable declaration between, will cause a problem, but better to be safe...
Code:

int16 time=0;

#int_TIMER0
void TIMER0_isr() {
    output_high(LED);
    time++;
}

2) You _have_ got a series resistor between the PIC and the LED?.
3) You have got a low ESR capacitor right by the PIC?.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jul 06, 2011 2:31 pm     Reply with quote

If you do the fix that Ttelmah suggested, I think it has a chance to work.

I was able to make your program work this morning, but it was painful.
First, I used Pickit2, and set it up so I could remotely power the board,
instead of having Pickit2 provide the Vdd power. When I did this, the
calibration word at address 0x3FF in the 12F675 was destroyed. I had
to re-program it with the ICD2, since Pickit2 has no ability to do this in
the programmer setup screen. This happened at least 2x.

Eventually, I got tired of wasting my time with trying to make Pickit2 work
with it. So I switched to ICD2. But ICD2 doesn't like the NOMCLR fuse.
It gives a warning. So I changed it to MCLR, and I have a 10K pullup on
the PIC's MCLR pin on the board, as required by ICD2.

Then I discovered that my nominal Calibration memory word of 0x3480
produced an internal oscillator frequency that was substantially off
frequency from the nominal 4.0 MHz. Just to make it run now, I changed
the baud rate in the #use rs232() statement to 9200 baud. Then it
started working. Later, I'll figure out what the correct calibration value
should be for this particular PIC. Here is the Terminal output:
Quote:

1s
1s
1s
1s
1s
1s
1s


Also, I didn't like your isr routine, where it turned the LED on if you get
an interrupt. I wanted more activity. So I changed it to toggle the LED
at approximately a rate of 1 second On, 1 second Off.
Code:

#int_TIMER0
void TIMER0_isr()
{
    if(time == 0)
       output_toggle(LED);
    time++;
}
 


These tests were done with your version, 4.114.
alex323qp



Joined: 17 Jun 2011
Posts: 12

View user's profile Send private message

PostPosted: Wed Jul 06, 2011 4:37 pm     Reply with quote

Guys, I really appreciate your help!

I haven't been able to test it, as I'm about to leave, I'll be back in a couple of hours and I'll let you know how is going.

Thanks again.
alex323qp



Joined: 17 Jun 2011
Posts: 12

View user's profile Send private message

PostPosted: Wed Jul 06, 2011 9:47 pm     Reply with quote

wow! I can't believe it was so simple!

You are my heroes guys!!!

It's finally working. I just moved the variable above the procedure (as Ttelmah suggested) and it worked.

I also noticed that with NOMCLR also works fine. However my rs232 communication stopped working, I guess is a speed problem, as you said PCM p.

Thanks, thanks, thanks!! Very Happy
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