Software > Software

char - programming problem in C

(1/2) > >>

Admin:
Im having trouble passing PORTD over to my servo() function. I figured the best way to do this is as a char string . . . but im getting two errors that I dont understand:

SoR_Utils.h:106: error: invalid operands to binary |
SoR_Utils.h:108: error: invalid operands to binary &

I assume I need to do some pointer stuff or something . . .


--- Code: ---#include <string.h>//is this required for char?!

//define port functions; example: PORT_ON( PORTD, 6);
#define PORT_ON( port_letter, number ) port_letter |= (1<<number)
#define PORT_OFF( port_letter, number ) port_letter &= ~(1<<number)

//define electronics/ribs/motors to specific hardware pins
#define RIB_1_Fin_Left( position ) servo("PORTD",6,position)
#define RIB_2_Fin_Left( position ) servo("PORTD",5,position)

//run servo based on pin hardware definition
void servo(char port[], int port_number, unsigned int cycles)
{
PORT_ON(port, port_number); // line 106
delay_cycles(cycles);
PORT_OFF(port, port_number); // line 108
}

in main:
RIB_1_Fin_Left(35);

--- End code ---

The code compiles without error if I remove the quotes off of "PORTD" and remove the brackets from char port[], but the servos dont work so I assume that this code is wrong in some way . . .

Ill be doing some heavy programming for the next few weeks so expect more such 'im-a-meche-and-cant-program' questions . . . next up, uart and rs232 done wirelessly . . .

Liang:
hi
It is a pointer problem. by default, C or C++ will pass the char array's address to your function.
try to use a for loop,
for(int i=0;i<port_letter's length;i++)
{
         //here is a way to access the array value use a pointer
         *(port_letter+i) |=(1<<number);
         *(port_letter+i) &=~(1<<number);
}

iNFINITE:
See if the following modification works:

--- Code: ---//define port functions; example: PORT_ON( PORTD, 6);
#define PORT_ON( port_letter, number ) port_letter |= (1<<number)
#define PORT_OFF( port_letter, number ) port_letter &= ~(1<<number)

//define the servo function macro
#define servo(port,number,position)   (PORT_ON(port,number), delay_cycles(position), PORT_OFF(port,number))

//define electronics/ribs/motors to specific hardware pins
#define RIB_1_Fin_Left( position ) servo(PORTD,6,position)
#define RIB_2_Fin_Left( position ) servo(PORTD,5,position)


in main:
RIB_1_Fin_Left(35);
--- End code ---

The problem was in the Servo() function.
In line 106 compiler would see it as port|=(1<<port_number); now u have declared port as a char pointer currently pointing to the string "PORTD". you cannot do the binary | (OR) with a char pointer..thats what the error is.

Now when you remove the quotes off of "PORTD" and remove the brackets from char port[] the program is compiling because now port is a declared as a char variable, & the |(OR) operation can be done with it. To understand why it is not working u have to understand few things.  PORTD is actually defined in the avr library as
#define PORTD   _SFR_IO8(0x12) (for Atmega16 say), So when ur passing PORTD as a parameter to the servo function.. this _SFR_IO8() macro is not called so ur code is not working.

Am i able to explain it?

Admin:
iNFINITE, your code fixed it.

But I dont really understand why . . . :-\

Admin:
So Im having another problem that uses the same code as above. The problem is that some of the pins are producing the proper square wave from the servo() command, but four of them on PORTC just stay high (measured with oscope). I am assuming that I am not doing the port configuration stuff properly, which is why I posted that part of the code . . . Suggestions?


--- Code: ---//define port functions; example: PORT_ON( PORTD, 6);
#define PORT_ON( port_letter, number ) port_letter |= (1<<number)
#define PORT_OFF( port_letter, number ) port_letter &= ~(1<<number)

//define the servo function macro
#define servo(port,number,position)   (PORT_ON(port,number), delay_cycles(position), PORT_OFF(port,number))

//************CONFIGURE PORTS************
//configure ports for input or output - specific to ATmega8
void configure_ports(void)
{
//configure ports for input or output
DDRA = 0x00;  //configure all A ports for input
PORTA = 0x00; //make sure pull-up resistors are turned off
DDRB = 0x1F;  //configure B ports 0->4 for output (google search '0b00011111 to hex')
DDRC = 0xFF;  //configure all C ports for output
DDRD = 0xFC;  //configure all D ports for output, except 0 and 1 (RX/TX) FC
};
//***************************************

in main:
servo(PORTC,0,45);//works
servo(PORTC,1,45);//works
servo(PORTC,2,45);//pin stays high
servo(PORTC,3,45);//pin stays high
servo(PORTC,4,45);//pin stays high
servo(PORTC,5,45);//pin stays high
servo(PORTC,6,45);//works
servo(PORTC,7,45);//works
servo(PORTD,7,45);//works

--- End code ---

Looking at the ATmega644 datasheet made me a bit more confused, but I think I just need to add some additional lines for PORT or DDR . . . see attached image for the chart I think concerns my problem . . .

Navigation

[0] Message Index

[#] Next page

Go to full version