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 support@ccsinfo.com

Another newbie question

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



Joined: 07 May 2005
Posts: 28
Location: Campbell, CA

View user's profile Send private message

Another newbie question
PostPosted: Thu May 12, 2005 11:57 pm     Reply with quote

I have to apologize for my lack of understanding. I think all I need is
a little "shove" to get me started. I'm very familiar with PicBasic Pro, and
I think that my knowledge of that language is almost a hindrance to my 'C' education.

I tried to write a very small program that would toggle a pin
every millisecond in an ISR.

A couple of questions:

Do I have to clear TMR0 (RTCC) before I enable interrupts, or is
this done for me automatically?

Do I have to set the TRIS register to force portb_0 and portb_1 as outputs?

Why won't the following program toggle portsb.0 and b.1?





#include "C:\Program Files\PICC\Charles Code\Test2.h"
#ZERO_RAM
#int_RTCC

int8 a,b,d,e;
char c;



RTCC_isr()
{
output_toggle(PIN_B0);
}



void main()
{

port_b_pullups(TRUE);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4|RTCC_8_bit);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);

a = 0;

while (a = 0);
{ output_toggle(PIN_B1); }


return;
newguy



Joined: 24 Jun 2004
Posts: 1904

View user's profile Send private message

PostPosted: Fri May 13, 2005 12:04 am     Reply with quote

Just a couple things....

Usually where you start the declaration of the interrupt and the interrupt code itself comes right after. You have a bunch of variable declarations in the way.

The critical error is in the while loop.

while (a = 0) {}

will never run. The way any test (a while, if, etc. loop) runs is if the test condition evaluates to true (1), the loop runs. By saying "while (a = 0)", you are telling the compiler to set a equal to 0, then test a to see if it is 1, which it isn't. What you need is "while (a == 0)", which means "see if a is zero" - if it is, the test evaluates to true (1), and the while loop executes.

Long story short, if you're testing something, you need two equals (==). If you're assigning a variable a value, you need one (=). Little mistake, big difference in how it runs.

Hope this helps.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri May 13, 2005 1:30 am     Reply with quote

Some more things....

When posting code please use the 'code' button, this will ensure the formatting of your code is preserved in this forum.

Please post complete code examples that we can compile. In your code the #fuses line and the include for your processor are missing. And what is test2.h containing???

Quote:
while (a = 0);
{ output_toggle(PIN_B1); }
The ';' at the end of your while is interpreted as an empty statement and causing your while-loop to execute a loop of 'nothing'. This is a common error and I think the designers of the C-language should have chosen another construct.

In CCS you must declare an interrupt function with a special preprocessor command indicating for which interrupt it's used, for example #int_timer0 or #int_ext.

Quote:
Do I have to clear TMR0 (RTCC) before I enable interrupts, or is
this done for me automatically?
Timer0 is not cleared automatically, you can do so with the set_timer0(value) function. Thing is, do you really care? Not setting the timer in your program will cause the first interrupt to fire sooner than the 1ms, but your program is starting at an undefined time interval anyway. It would only be important to reset the timer when meassuring the time between two events.

Quote:
Do I have to set the TRIS register to force portb_0 and portb_1 as outputs?
No, the CCS compiler will do this for you. In special cases where you want to be in control because of memory or speed optimizations you can study the #use fast_io and #use fixed_io commands.

Your modified program:
Code:
#include <18F458.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP

#use delay(clock=4000000) // 4MHz clock

#int_rtcc
RTCC_isr()
{
  output_toggle(PIN_B0);
}


void main()
{
  int8 a;
 
  port_b_pullups(TRUE);
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  setup_psp(PSP_DISABLED);
  setup_spi(FALSE);
  setup_wdt(WDT_OFF);
  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4|RTCC_8_bit);
  setup_timer_1(T1_DISABLED);
  setup_timer_2(T2_DISABLED,0,1);
  setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
  enable_interrupts(INT_RTCC);
  enable_interrupts(GLOBAL);

  a = 0;

  while (a == 0)    // Note the '==' and no ';' here !!!
  {
    output_toggle(PIN_B1);
    delay_ms(500);   // Added a delay so you can visually see the changes (LED or voltmeter)
  }
}
Charles Linquist



Joined: 07 May 2005
Posts: 28
Location: Campbell, CA

View user's profile Send private message

PostPosted: Fri May 13, 2005 6:44 am     Reply with quote

Thanks so much for your explanation and help. I'm trying to slowly convert my 4000+ lines of a PicBasic Pro program to C. My 8720 is very nearly full. It will be interesting to see if C is more code efficient in such a large program.

I have my work cut out for me.

Thanks again,
Charles Linquist
Charles Linquist



Joined: 07 May 2005
Posts: 28
Location: Campbell, CA

View user's profile Send private message

PostPosted: Fri May 13, 2005 12:46 pm     Reply with quote

Your code works. But I see two strange things:

1. I "told" the wizard that I wanted to use a "Resistor/Capacitor oscillator"
What I wanted was to use the INTERNAL oscillator of the '452. Apparently,
the chip is set up for an external R/C network, because nothing happened
until I fed an external oscillator into the CLK in pin.

Is there a way to use the Wizard and use the internal oscillator of the newer parts?


2. On RB0, I noticed that the rise time was nice and fast, but the fall time
was extremely long (> 500uSec). It seems like the chip had no drive in the negative direction. I set up RB0 as an output in the Wizard.

Is this typical, or am I doing something wrong?
Ttelmah
Guest







PostPosted: Fri May 13, 2005 2:10 pm     Reply with quote

The answer here is to read the manufacturers data sheet for the chip....
The oscillator modes for the 18F452, are:
LP
HS
HS+PLL
RC
RCIO
EC
ECIO

These correspond to an external low frequency crystal, external high frequency crystal, external crystal with PLL, external resistor/capacitot, external resistor/capacitor with the second oscillator pin as IO, external clock, and external closk with the second pin as IO.
You will see there is no mention of an internal oscillator option.
The 452, does not have an internal oscillator, hence the compiler has no option for this...
Generally, most of the chips supporting the 4*PLL, do not have internal oscillators.

Best Wishes
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