Author Topic: char - programming problem in C  (Read 6922 times)

0 Members and 1 Guest are viewing this topic.

Offline AdminTopic starter

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,703
  • Helpful? 173
    • Society of Robots
char - programming problem in C
« on: May 11, 2007, 10:23:16 AM »
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: [Select]
#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);

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

Offline Liang

  • Beginner
  • *
  • Posts: 2
  • Helpful? 0
Re: char - programming problem in C
« Reply #1 on: May 11, 2007, 11:33:19 AM »
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);
}

Offline iNFINITE

  • Jr. Member
  • **
  • Posts: 21
  • Helpful? 0
    • iNTBOTS.iNFO | My Homepage
Re: char - programming problem in C
« Reply #2 on: May 12, 2007, 04:48:14 PM »
See if the following modification works:
Code: [Select]
//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);

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?
« Last Edit: May 14, 2007, 12:56:08 AM by iNFINITE »

Offline AdminTopic starter

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,703
  • Helpful? 173
    • Society of Robots
Re: char - programming problem in C
« Reply #3 on: May 14, 2007, 09:18:15 AM »
iNFINITE, your code fixed it.

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

Offline AdminTopic starter

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,703
  • Helpful? 173
    • Society of Robots
Re: char - programming problem in C
« Reply #4 on: May 14, 2007, 01:13:51 PM »
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: [Select]
//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

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

Offline iNFINITE

  • Jr. Member
  • **
  • Posts: 21
  • Helpful? 0
    • iNTBOTS.iNFO | My Homepage
Re: char - programming problem in C
« Reply #5 on: May 14, 2007, 02:15:11 PM »
pins PC2,PC3,PC4,PC5  are used for the JTAG interface. JTAG interface is enabled in default factory settings. For using these pins as normal i/o pins you have to change the fusebits :'(. Refer to the corresponding datasheet for the exact fusebits.


You did all the port configurations perfectly. No need to add any more line.

Regards,
Abhijit

Offline AdminTopic starter

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,703
  • Helpful? 173
    • Society of Robots
Re: char - programming problem in C
« Reply #6 on: May 14, 2007, 02:39:41 PM »
Ok I just want to verify with you on this . . . Ive 'fried' a few AVR's in my day cause I do stupid things with the fuses . . .

see attachment . . . I just uncheck that JTAG Interface Enabled box and it will work, right?

Offline iNFINITE

  • Jr. Member
  • **
  • Posts: 21
  • Helpful? 0
    • iNTBOTS.iNFO | My Homepage
Re: char - programming problem in C
« Reply #7 on: May 14, 2007, 03:17:26 PM »
to disable JTAG u have to make the JTAGEN bit 1.
you should change the the fuse High byte only. it should be made 0xD9 instead of 0x99
So the final fuse setting should be 0xFF, 0xD9, 0x62

i haven't used the AVRISP programmer. But i think just simply unchecking the JTAG Interface Enabled box will do.
In the confirmation dialog that will comes up( i hope) make sure the fuse bytes are as mentioned above.


Regards,
Abhijit

Offline AdminTopic starter

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,703
  • Helpful? 173
    • Society of Robots
Re: char - programming problem in C
« Reply #8 on: May 15, 2007, 07:20:41 AM »
thanks! it works now! :)

After unchecking the JTAG box and clicking program, all it did was give me a 'are you sure?' type warning.

 


Get Your Ad Here

data_list