Jump to content

Recommended Posts

Hi Guys,

 

I am new to c programming. I am only familiar with PIC basic and bascom.

Since boost c compiler is very affordable compared to most other compiler i wanted to start learning c.

 

I have a small program, which does a binary progression and displays on portb.

the problem is that my pogram does not jump to the check subroutine or function that i call from the main program.

Please help.

 

#include <system.h>

#pragma CLOCK_FREQ 4000000

// Set configuration word

#pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF

void check()
{
if(portb=0)
{
portb=1;
delay_ms(500);
}
  }
  
void main()
{
 trisb=0;
 portb=0;
 while(1)
{
 check();
 portb *= 2;
 delay_ms(500);
 }
   }

 

Can the check routine be placed after the main routine? when i tried it , it gives a compilation error, " not able to find label check" or some thing like that.

Link to post
Share on other sites

As a basic example template you declair your functions before main and then define them after.

Most C compilers(not C++) need to know that something exists before you can use it.

 

#include <system.h>

void check(void);

void main(void)
{
  blah;
}

void check(void)
{
  blah;
}

 

As for your code there are quite a few ways to approach this, but as a convention i'll suggest

"write to the Lat (latch), read from the Port". The biggest issue i see myself is the fact you never change PortB to input, yet your trying to read from it. Without trying to disrupt your code too much

i'd like to suggest:

void check()
{
   trisb = 0xFF;   /* Set port B to input */
   if(latb=0)
  {
      trisb = 0x00;   /* Set port B to output */
      portb=1;
     delay_ms(500);
  }
 trisb = 0x00;   /* Set port B to output  incase it did not enter test */
}

 

 

As something to think about, instead of your approach, you could try bit shifting which will be a bit

more efficient for what your doing but requires a variable holder: portb << i; This will "shift" the values from 0x00 to 0xFF unless you handle it to make it reverse.

 

I have a very simular program that i use to "live debug" that i can show you if you still have problems.

Link to post
Share on other sites
fact you never change PortB to input, yet your trying to read from it. Without trying to disrupt your code too much

i'd like to suggest:

void check()

{

    trisb = 0xFF;  /* Set port B to input */

    if(latb=0)

  {

      trisb = 0x00;  /* Set port B to output */

      portb=1;

      delay_ms(500);

  }

  trisb = 0x00;  /* Set port B to output  incase it did not enter test */

}

Hi Emte,

i tried just as you said and checked it using the simulator but the code does not jump to the check routine.

on using latb it gives the following error.

 

Building...

BoostC Optimizing C Compiler Version 6.55 (for PIC16 architecture)

http://www.sourceboost.com

Copyright© 2004-2006 Pavel Baranov

Copyright© 2004-2006 David Hobday

 

Single user Lite License (Unregistered) for 0 node(s)

Limitations: PIC12,PIC16 max code size:2048 words, max RAM banks:2, Non commercial use only

 

 

button test.c

 

failure

D:\Program Files\SourceBoost\Samples\C\BoostC\my test files\button test.c(26:5): error: unknown identifier 'latb'

D:\Program Files\SourceBoost\Samples\C\BoostC\my test files\button test.c(26:5): error: invalid operand 'latb'

D:\Program Files\SourceBoost\Samples\C\BoostC\my test files\button test.c(26:9): error: failed to generate expression

D:\Program Files\SourceBoost\Samples\C\BoostC\my test files\button test.c(26:9): internal error: failed to generate 'if' expression

"D:\Program Files\SourceBoost\boostc.pic16.exe" "button test.c" -t PIC16F84A

Exit code was 1.

Removing target: button test.obj

Done

 

Iam only comparing the portb register value in the if statement and not reading any pin state.

Raghunathan.

Link to post
Share on other sites

This is not exactly what you are trying to do but should be close enough for you to alter:

#include <system.h>

//Set clock frequency
#pragma CLOCK_FREQ	4000000

/* hmm is this how we set globals? */
#define Flashy PORTB
#define FlashyL LATB
#define FlashyT TRISB
volatile unsigned char flashy @Flashy;
volatile unsigned char flashyL @FlashyL;
volatile unsigned char flashyT @FlashyT;

#define _delayTime  100

/* simple bit shift function on a port as defined above */
void portTest(void);

void main( void )
{
/* Endless loop */
while( 1 )
{
	portTest();

}
}

/* simple bit shift function 
*  uses: flashyT and flashyL for selected port access
*/
void portTest(void)
{
bit flip = 1;                  /* holder for direction */
unsigned char i = 0;     /* place counter */

/* we want outputs */
flashyT = 0x00; 

/* live forever ... barring WDT */
while(1)
{
	/* if flip is true increment, false decrement */
	(flip)?(i++):(i--); 
	/* Shift our bits over */
	flashyL = 1 << i;
	/* generous delay */
	delay_ms(_delayTime);
	/* test for our barriers */
	if((i>=7)||(i<=0))
	{
		/* change direction */
		(flip)?(flip=0):(flip=1);
	}
}
}

 

This is from the first time i tried it on a 18F452 and it still works. Hope that helps.

Link to post
Share on other sites

Thanks very much for your help.

Really my first code was compiling. Can you guess what was wrong in the code?

 

i wrote if (portb=0), instead of if (portb==0).

 

My main reason to migrate from basic compiler is that most rtos supports only c and am bent on implementing rtos in my robot projects which i have been constructing using pic basic.

Raghunathan.

Link to post
Share on other sites
Some compilers issue a warning when they come across this! Perhaps we could ask Dave about adding a warning.

 

i wrote if (portb=0), instead of if (portb==0).

 

 

 

I was just wanting to say that. Hi lighting the error in code and suggesting the right syntax will be of great help.

Raghunathan

Link to post
Share on other sites
Some compilers issue a warning when they come across this! Perhaps we could ask Dave about adding a warning.

 

i wrote if (portb=0), instead of if (portb==0).

 

 

 

 

Technically its not really wrong ... i don't think ...

 

i am curious though if a value assignment for a port/register has a return value associated with it...

 

If that is the case... then you could actually deal with a situation in a case where your port directions

are wrong or being used by something else and handle it that way ... hmm, interesting idea that

could be useful for various things. But its probably better for the average user if it gives a warning

about a test on an L-value.

Link to post
Share on other sites
Hi there

 

Personally I use:

 

if (0==portb), instead of if (portb==0)

 

If I don't use the double assignment it allways flags an error.

 

That this actually works seems strange to me, which compilers accept that?

... on second thought, the lvalue assignment method is probably by convention

from the way one defines variables with values, eg. char i = 3; ...

hmm thinking about coding in assembly it does indeed use your method, eg. movlw 0xff;

 

If i were to look at your code i suspect i might be very confused by your

convention if you had not brought it up here, now i'll have to keep it in mind.

Is there any performance difference assigning to the rvalue? aside from more warnings?

Link to post
Share on other sites

Hi Guys,

Thanks very much for keeping this thread active with your suggestions and ideas. I thought i can come up with all my doubts in this thread and finally post the successfuly working and tested codes ( only on boostc compiler) on another new thread by name say " sample code for beginners ". It is intended for those with with very little or no knowledge of c programming. Do you guys support this? I think, i might also require the consent of the forum administrator (Pavel & Dave).

Thanks,

Rahunathan.

Link to post
Share on other sites
Hi there

 

Personally I use:

 

if (0==portb), instead of if (portb==0)

 

If I don't use the double assignment it allways flags an error.

 

That this actually works seems strange to me, which compilers accept that?

... on second thought, the lvalue assignment method is probably by convention

from the way one defines variables with values, eg. char i = 3; ...

hmm thinking about coding in assembly it does indeed use your method, eg. movlw 0xff;

 

If i were to look at your code i suspect i might be very confused by your

convention if you had not brought it up here, now i'll have to keep it in mind.

Is there any performance difference assigning to the rvalue? aside from more warnings?

 

Any compiler will react the same, you can't assign a value to a constant!

Link to post
Share on other sites
  • 2 months later...

Thanks Dave,

 

But I need something even more basic. Like what exactly does a #pragma directive do and what directives I should use for my application.

 

I've copy-pasted some of pragmas i found on this forum but the system didn't recognize them. I guess I have to go over the processors datasheet and the header.

 

By the way, do you know any internet site where I can find good introduction and concepts in pic programming.

Link to post
Share on other sites
  • 3 weeks later...
  • 4 weeks later...
Use bit masking.

Got it,

 

The value in those two registers:

(CCPR1L:CCP1CON<5:4>)

should be an outcome of a calculation (PID feedback if you have to know).

 

I'm thinking of declaring a new variable for the calculation results and then copying its two LSB into CCP1CON<5:4> and then the rest 8 MSB into CCPR1L. It's awkward but it should work with about 5 code lines! :) .

Is there a better method which I'm missing out?

Link to post
Share on other sites
The one that you understand is the best one for you to use,

you can always improve your code later.

Clumsy me, :huh:

retrieving the 2 LSB of 'X' is done by X%0b100

the rest of the MSB is X/0b100.

 

That's just 2 commands. B)

(I just hope that BoostC recognizes even numbered operation and just shifts the register rather than going through all the calculations)

Link to post
Share on other sites
The one that you understand is the best one for you to use,

you can always improve your code later.

Clumsy me, :huh:

retrieving the 2 LSB of 'X' is done by X%0b100

the rest of the MSB is X/0b100.

 

That's just 2 commands. B)

(I just hope that BoostC recognizes even numbered operation and just shifts the register rather than going through all the calculations)

 

That may or may not depend if your using the agressive optimization flag.

You can always look at the compiled disassembly to check.

Link to post
Share on other sites
  • 2 weeks later...

I wish to calculate frequency using the CCP2 module. I need to pass the two registers CCPR2L and CCPR2H into one variable.

If I define that variable as integer will that work:

 

Frequency = getFreq(ccpr2);

 

where

int getFreq(int reg)
{
      //       calculate frequency according to value captured in CCPR2 register
      //	period between captures = 4/Fosc  x CCPR2 (=FreqCapture_Reg)
  
  if reg < 0xFF;
     return Fosc/4/reg; // frequency = 1/period
  else 
     return 0;
}

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...