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

It's a simple problem......

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



Joined: 03 Jan 2004
Posts: 19
Location: UK - Brighton

View user's profile Send private message

It's a simple problem......
PostPosted: Thu Jan 29, 2004 9:21 am     Reply with quote

For those who know what they're doing....unlike me!


Hello people,

If i compile this simple bit of code

Code:


//SerialServo.c
//----------------
#include <SerialServo.h>

#define PinServo0 PIN_B4

 
 

#int_TIMER0
TIMER0_isr()
 

void main()
{
int x;

x=12;

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);
enable_interrupts(INT_TIMER0);
enable_interrupts(global);

byte data_byte = 0;


while (TRUE)
   {
   if (kbhit())
      {
      data_byte = getc();
       // the byte will be between 0x10 and 0x5F

      data_byte = data_byte - 0x10;

      // data_byte will now be between 0 and 4F

      output_high(PinServo0);

      delay_ms(1); // the minimum on time for servo

      // this loop will delay for a number of microseconds in data_byte 12 times
      // which will give a delay between approx. 0 to 1 ms

         do
         {
              delay_us(data_byte);
             }
         while(--x);

      // now the output pulse will be on for 1 - 2 ms

      output_low(PinServo0);
   
      }
   }

}



Why does it give me this error message

Code:


Building 628SERVO.HEX...

Compiling 628SERVO.C:
Command line: "C:\PROGRA~1\PICC\CCSC.EXE +FM C:\PROGRA~1\MPLAB\628SERVO.C"
Error[29]   C:\PROGRA~1\MPLAB\628SERVO.C 14 : Function definition different from previous definition 

MPLAB is unable to find output file "628SERVO.HEX". This may be due to a compile, assemble, or link process failure.

Build failed.



the serialservo.h header is just -->


Code:

//Serialservo.h
//---------------
#include <16F628.h>
#use delay(clock=4000000)

#fuses HS,NOWDT,NOPUT,NOPROTECT,NOBROWNOUT,MCLR,NOLVP,NOCPD
#use rs232(baud=9600,bits=8,parity=N,xmit=PIN_B2,rcv=PIN_B1,ERRORS,RESTART_WDT)


It's got to be something simple, Very Happy but being a bit new to all this i can't see the damn problem!!

Help please....... Confused
_________________
There are 10 kinds of people who understand binary, those who do and those who don't
Ttelmah
Guest







Re: It's a simple problem......
PostPosted: Thu Jan 29, 2004 9:31 am     Reply with quote

johnh wrote:
For those who know what they're doing....unlike me!


Hello people,

If i compile this simple bit of code

[code]

//SerialServo.c
//----------------
#include <SerialServo.h>

#define PinServo0 PIN_B4




#int_TIMER0
TIMER0_isr()


I'd guess the problem is that you actually have not got a function here...
You either need:
TIMER();

to 'terminate' the definition, or:

TIMER0_isr() {

}

With the code that you want to run (or just a blank for now). The compiler knows that you have said you are going to have an interrupt subroutine, but then sees no subroutine (and hence the 'function definition differs').

Best Wishes
SteveS



Joined: 27 Oct 2003
Posts: 126

View user's profile Send private message

PostPosted: Thu Jan 29, 2004 9:34 am     Reply with quote

By inspection I think it's this:

You defined a timer interrupt service routine, but it is not complete:

#int_TIMER0
TIMER0_isr()

is what you have. You need at least:

#int_TIMER0
TIMER0_isr()
{
}

to make it compile. You need to add whatever code in there to accomlish what you want to have happen during the interrupt (reload timer, etc).
johnh



Joined: 03 Jan 2004
Posts: 19
Location: UK - Brighton

View user's profile Send private message

PostPosted: Thu Jan 29, 2004 9:53 am     Reply with quote

Excellent, thanks people..

Suspect my project will kick out a few more problems yet!!

Be back soon...

John
_________________
There are 10 kinds of people who understand binary, those who do and those who don't
johnh



Joined: 03 Jan 2004
Posts: 19
Location: UK - Brighton

View user's profile Send private message

PostPosted: Thu Jan 29, 2004 11:07 am     Reply with quote

next problem...... Very Happy

i want the RTCC to interrupt every ~17ms

at the moment the setup of the timer0 is
Code:

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);


in the device file it says

#define RTCC_INTERNAL 0

#define RTCC_DIV_256 7

I am using a 4Mhz crystal and a 16F628

any ideas

John
_________________
There are 10 kinds of people who understand binary, those who do and those who don't
johnh



Joined: 03 Jan 2004
Posts: 19
Location: UK - Brighton

View user's profile Send private message

PostPosted: Thu Jan 29, 2004 11:31 am     Reply with quote

for completeness - this is my actual code inside the isr


Code:
#int_TIMER0
TIMER0_isr(){

   output_high(PinServo0);

      delay_ms(1); // the minimum on time for servo
      data_test = data_test + data_dir; //testing
      
      if (data_test <= 0)  data_dir = 1; //testing
         
   
      // this loop will delay for a number of microseconds in data_byte 12 times
      // which will give a delay between approx. 0 to 1 ms


      x=12;
         do
         {
              delay_us(data_test); //testing
             }
         while(--x);

      //now the output pulse will be on for 1 - 2 ms

      output_low(PinServo0);
}


Do i need to include something in there to reset the timer?? Like what?

John
_________________
There are 10 kinds of people who understand binary, those who do and those who don't
neil



Joined: 08 Sep 2003
Posts: 128

View user's profile Send private message

oh-oh!
PostPosted: Thu Jan 29, 2004 1:24 pm     Reply with quote

Hi John,
There's a few no-no's in that code I'm afraid!

1) *Never* put CCS's delays in an interrupt. An interrupt needs to be kept short. I know the delay only looks like one command, but it creates a loop which ties up the processor for that duration. This kinda spoils the original intention of using interrupts!

2) Don't use 'while' loops in an interrupt, again for the same reason as above. Depending on the while() condition, this will tie up the processor for the duration it is true.

What is the "while(--x)" supposed to do? That looks to me like it would just continue to decrement 'x' forever, as it is not an operation which returns a true or false. 'x' will just wrap around from 0 to 255. I could be wrong here though.

Finally, you are testing if "data_test <= 0". Unless this is declared as a signed number, it can never be <0.

The best advice I can give is not to put any sort of loop in an interrupt. You can use an interrupt to trigger an event which takes a long time to execute by setting a 1-bit flag in the interrupt, then polling for it in main(). If it is true, make it false, then do whatever you want to do.

I always keep my main loop as a series of flag tests which don't do anything until required, so the poll time is very short. It is only when an event is triggered that the time-consuming bit needs to be done.
Any time based events can be triggered by postscale variables inside an interrupt, so no software delays need to be used. This then (dare I say it) makes your program start to look like a multi-tasking system!

I like your quote by the way! Laughing I saw another one yesterday on someone's website: "The thing I like about standards is that there are so many to choose from" Exclamation

All the best,
Neil.
neil



Joined: 08 Sep 2003
Posts: 128

View user's profile Send private message

interrupt period calculation
PostPosted: Thu Jan 29, 2004 1:54 pm     Reply with quote

Hi John, me again.

To calculate the interrupt period, remember that inside the PIC, the xtal frequency is divided by 4; so at 4MHz, your 'instruction clock' is at 1MHz, or 1MIPS.

For Timer0, you have a prescaler, so if you assign the prescaler to the watchdog timer (timer0 div by 1) it increments every micrsecond. The timer0 is an 8-bit register, so it will roll-over when it reaches 255, back to 0 and trigger the interrupt. Therefore, the interrupt period is 256us.

If you set the prescaler to divide by 256, you interrupt every 256^2, or 65536us -> 65.536ms. To get your desired ball-park interrupt rate, look in the datasheet for the possible values the prescaler can be set to, and choose one which fits best. Some people have produced spreadsheet charts for quick reference. I think Neutone is one.

To get multiples of that rep. rate, you can create a variable and increment or decrement it inside the ISR, then test for either zero, or a certain value. When true, set a flag ready to be picked up in main(), or do 'something', provided it is *short*!

Example. Provides an event every 10ms approx.
Code:


setup_counters(RTCC_INTERNAL,RTCC_DIV_8); // 4MHz/4 give 1us period. 1us * 8 = 8us bit resolution.
int postscale=0;
short event_trig=0;
....

#int_timer0
RTCC_ISR(){  // This occurs every 8us * 256 = 2.048ms.
postscale--;                // Decrement your scale factor.
if(postscale==0){       // Test it.
     postscale = 5;       // Re-initialise it for next cycle.
     event_trig = TRUE;  // Set a flag to trigger an event, or do stuff here. True every 10.024ms.
     }
}


Until recently I have been getting (what I thought were) more accurate time intervals by presetting the timer0 register in each interrupt to give varying multiples of the bit rate, rather than 256 times the bit rate. I have been advised against this though. (See:http://www.ccsinfo.com/forum/viewtopic.php?t=18175 for details).

Whoa, time to crack a beer, and watch TV!
Cheers,
Neil.
Pete Smith



Joined: 17 Sep 2003
Posts: 55
Location: Chester, UK

View user's profile Send private message Visit poster's website MSN Messenger ICQ Number

Re: oh-oh!
PostPosted: Fri Jan 30, 2004 3:49 am     Reply with quote

neil wrote:
Hi John,
What is the "while(--x)" supposed to do? That looks to me like it would just continue to decrement 'x' forever, as it is not an operation which returns a true or false. 'x' will just wrap around from 0 to 255. I could be wrong here though.

do
{}
While (--x) will keep going so long as X is not zero.

As soon as it _is_ zero, it'll exit the loop.

Pete.
neil



Joined: 08 Sep 2003
Posts: 128

View user's profile Send private message

ah
PostPosted: Fri Jan 30, 2004 3:54 am     Reply with quote

Oh well, the code looks shorter. I'll use that in future. Maybe I should get the old Kernaghan & Ritchie book out again! Laughing

Neil.
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