Using Functions

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include 
#include 
#include 
#include 

//Definitions
#define Trigger (PINC&_BV(PINC2))
#define Gearbox_Sensor (PINC&_BV(PINC0))
#define Turn_On_SW2 (PORTD |= _BV(PIND2)) 
#define Turn_Off_SW2 (PORTD &= ~_BV(PIND2)) 
#define Turn_On_SW3 (PORTD |= _BV(PIND3)) 
#define Turn_Off_SW3 (PORTD &= ~_BV(PIND3)) 
#define Turn_On_SW4 (PORTD |= _BV(PIND4)) 
#define Turn_Off_SW4 (PORTD &= ~_BV(PIND4)) 
#define Turn_On_Motor (PORTD |= _BV(PIND6)) 
#define Turn_Off_Motor (PORTD &= ~_BV(PIND6)) 

//Global Variables
volatile static bool gearbox_sensor_flag;
volatile static uint8_t value;

//Fucntion Prototypes
bool Fire(bool tf);
bool Stop_Firing(bool tf);
bool Count_Gearbox_Cycles(bool gccf, bool gsf, volatile uint8_t value);

int main(){
	//Sets pin direction, PD6 Motor Drive, PB1 Motor Brake
	DDRD |= 0x40;
	DDRB |=	0x02;	

	//Sets initial state of PD6 and PB1
	PORTD &= ~0x40;	//Motor Drive off
	PORTB &= ~0x02;	//Motor Brake off

	//Enable Pull Up Resistors
	PORTC |= 0x05;	//PC0(Gbx. Pos.),PC2(Trig.) 
	PORTD |= 0xA0;	//PD5,PD7	
	PORTB |= 0x05;	//PB0,PB2

	//Enable Global Interrupts and PCINT8
	sei();				
	PCICR  |= 0x02;		
	PCMSK1 |= 0x01;			

	//Sets TC0 for Phase Correct PWM on PIND6, Non-Inverted
	TCCR0A |= 0x81;	//WGM00:Mode 5 and COMO bits to 2
	TCCR0B |= 0x08;	//WGM02:Mode 5
	OCR0A = 100;

	//Local Variables
	volatile uint8_t value;
	static bool trigger_flag;

		//Main Loop
		while(1){
			trigger_flag = Fire(trigger_flag);

			trigger_flag = Stop_Firing(trigger_flag);

			gearbox_sensor_flag = Count_Gearbox_Cycles(gearbox_sensor_flag);

			if( value > 3 ){
				Turn_On_SW2;
			}
			else{
				Turn_Off_SW2;
			}
		}//End Main Loop		
}

//Main Interrupt
ISR(PCINT1_vect){	
	gearbox_sensor_flag = (Gearbox_Sensor != 0) ? true : false; 
}//End Main Interrupt

//Function Deifinitions--------------------------------------------------------------------------
bool Fire(bool t_flag){	
	if( t_flag ){
		if( Trigger == 0 )
		{
			TCCR0B |= 0x01;	//turn on PWM on OC0A by turning on clock by setting divider to 1x
			t_flag = false;
		}
	}
	return t_flag;
}//End Fire

bool Stop_Firing(bool t_flag){
	if( Trigger != 0 )
	{
		TCCR0B &= ~0x01;	//turn off PWM on OC0A by turning off clock by setting divider to 0x
		Turn_Off_Motor;	//turn off PD6
		t_flag = true;
	}
	return t_flag;
}//End Stop Firing

bool Count_Gearbox_Cycles(bool gccf, bool gsf, volatile uint8_t value){
	if( gccf != gsf )
	{
		if( gsf )
			value++;
		gccf = gsf;
	}
	return gsf;
}//End Gearbox Cycle Counter

I realize there's a lot of code in there for 1 post, but hey, that's the entire program at this point. Now the problem I am having is I'm getting a compile error for the Count_Gearbox_cycle function, the error is 63: error: too few arguments to function 'Count_Gearbox_Cycles'. I am just learning the rules of functions in C, so bear with me on this. The error occurs right at the call for Count_Gearbox_Cycles. I also am not sure if value needs to be in the parameter declaration since it is a global value?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is telling you the problem.

your function is declared with 3 parameters. you only call it with one. you must supply all three parameters each time you call it

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, now since I am incrementing value within that function, and value is a global variable, do I need to declair it as a one of the parameters?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ThEThInG wrote:
I also am not sure if value needs to be in the parameter declaration since it is a global value?
If you put it in the parameter list (like now), then inside the function value is a completely different variable that has nothing to do with the global one. Therefore in your current version of the function the "value++" does not do what you expect.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, I think I understand the rules of functions clearly now.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you sure about that - to pass a parm but modify the variable it was taken from you actually need to switch to passing by reference rather than value using a pointer - see function3() below:

int globaln;

void function1(int localn) {
  localn++; // does not affect 'globaln'
}

void function2(void) {
  globaln++; // globaln can be "seen" everywhere
}

void function3(int * addr_of_globaln) {
  *addr_of_globaln++; // increment what addr_of_globaln is pointing at
}

int main(void) {
 function1(globaln); // globaln not changed
 function2(); // globaln is incremented
 function3(&globaln); // globaln is incremented
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are also returning gaf, but since you never change gaf within the function this is useless. I would think that it would be more logical to return gccf. This is an alternative to sending gccf in as a pointer (assuming that you assign the return value of the function to gearbox_sensor_flag as you have).

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Or this can be done without the function inside the while loop.
if( gccf != gsf && gsf ){
value++;
gccf = gsf;
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is a great reference:

[url]
http://www.amazon.com/Programmin...
[/url]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include 
#include 
#include 
#include 

//Definitions
#define Trigger (PINC&_BV(PINC2))
#define Gearbox_Sensor (PINC&_BV(PINC0))
#define Turn_On_SW2 (PORTD |= _BV(PIND2)) 
#define Turn_Off_SW2 (PORTD &= ~_BV(PIND2)) 
#define Turn_On_SW3 (PORTD |= _BV(PIND3)) 
#define Turn_Off_SW3 (PORTD &= ~_BV(PIND3)) 
#define Turn_On_SW4 (PORTD |= _BV(PIND4)) 
#define Turn_Off_SW4 (PORTD &= ~_BV(PIND4)) 
#define Turn_On_Motor (PORTD |= _BV(PIND6)) 
#define Turn_Off_Motor (PORTD &= ~_BV(PIND6)) 
#define Set_CSxx TCCR0B |= 0x01
#define Clear_CSxx TCCR0B &= ~0x01

//Global Variables
volatile static bool gearbox_sensor_flag;
volatile static uint8_t value;

//Fucntion Prototypes
bool Fire(bool t_flag);
bool Stop_Firing(bool t_flag);
void Count_Gearbox_Cycles(bool gs_flag);

int main(){
	//Sets pin direction, PD6 Motor Drive, PB1 Motor Brake
	DDRD |= 0x40;
	DDRB |=	0x02;	

	//Sets initial state of PD6 and PB1
	PORTD &= ~0x40;	//Motor Drive off
	PORTB &= ~0x02;	//Motor Brake off

	//Enable Pull Up Resistors
	PORTC |= 0x05;	//PC0(Gbx. Pos.),PC2(Trig.) 
	PORTD |= 0xA0;	//PD5,PD7	
	PORTB |= 0x05;	//PB0,PB2

	//Enable Global Interrupts and PCINT8
	sei();				
	PCICR  |= 0x02;		
	PCMSK1 |= 0x01;			

	//Sets TC0 for Phase Correct PWM on PIND6, Non-Inverted
	TCCR0A |= 0x81;	//WGM00:Mode 5 and COMO bits to 2
	TCCR0B |= 0x08;	//WGM02:Mode 5
	OCR0A = 100;

	//Local Variables
	volatile uint8_t value;
	static bool trigger_flag;

		//Main Loop
		while(1){
			trigger_flag = Fire(trigger_flag);

			trigger_flag = Stop_Firing(trigger_flag);

			Count_Gearbox_Cycles(gearbox_sensor_flag);

			if( value > 3 ){
				Turn_On_SW2;
			}
			else{
				Turn_Off_SW2;
			}
		}//End Main Loop		
}

//Main Interrupt
ISR(PCINT1_vect){	
	gearbox_sensor_flag = (Gearbox_Sensor != 0) ? true : false; 
}//End Main Interrupt

//Function Deifinitions--------------------------------------------------------------------------
bool Fire(bool t_flag){	
	if( t_flag ){
		if( Trigger == 0 )
		{
			Set_CSxx;	//turn on PWM on OC0A by turning on clock by setting divider to 1x
			t_flag = false;
		}
	}
	return t_flag;
}//End Fire

bool Stop_Firing(bool t_flag){
	if( Trigger != 0 )
	{
		Clear_CSxx;	//turn off PWM on OC0A by turning off clock by setting divider to 0x
		Turn_Off_Motor;	
		t_flag = true;
	}
	return t_flag;
}//End Stop Firing

void Count_Gearbox_Cycles(bool gs_flag){
	static bool cgc_flag;
	if( cgc_flag != gs_flag )
	{
		if( gs_flag )
			value++;
		cgc_flag = gs_flag;
	}
}//End Gearbox Cycle Counter

The count gearbox cycles subroutine increments "value" by one each time the gearbox sensor goes high. As you can see gearbox_sensor_flag is set true or false in the main ISR. Its value(aka a copy) is then passed into Count_Gearbox_Cycles subroutine as Count_Gearbox_Cycles does not need to modify gearbox_sensor_flag, only value needs to be incremented and cgc_flag needs to retain its values between calls, which is why I declared it as static. I also changed some of the names so they better represent the function they are used in, so just look at this code for reference.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BTW npat, I have that book sitting in front of me right now, although I've just started to read through it.