How to pass parameter ?

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

Guys,

I tried to pass a parameter into a function but can't do it until now,

Do you have ideas why ??
when I do simulation it's working,

And I tested the board without passing the parameter, it's working, but by the time I put the variable via parameter, it's not working.

The code :

#define rs(a)  (PORTC = (PORTC & ~_BV(PC0)) | ((a) << PC0))
#define rw(b)  (PORTC = (PORTC & ~_BV(PC1)) | ((b) << PC1))
#define en(c)  (PORTC = (PORTC & ~_BV(PC2)) | ((c) << PC2))

#define lcd_data_pin PORTD
DDRD=0XFF; //all pins of PORTD declared as output
DDRC = _BV(0);
DDRC = _BV(1);
DDRC = _BV(2);

void lcd_command(uint8_t comm) // function to send command to LCD
{
lcd_data_pin=comm;
en(1);
rs(0);
rw(0);
_delay_ms(50);
en(0);

}
main()
{
 while(1)
 {
   lcd_command(0x38);
 }
}

I'm using AVR studio 4,

Thanks for helping...

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

Describe more about " it's not working."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
DDRC = _BV(0); 
DDRC = _BV(1); 
DDRC = _BV(2);

This is wrong. After these three statements, only PC2 is set to output, the other two have been set back to input.

And by the way, this is the wrong forum for this post as it has nothing to do with AVR Studio.

Regards,
Steve A.

The Board helps those that help themselves.

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

clawson wrote:
Describe more about " it's not working."

I tried to pass the variable into :
void lcd_command(uint8_t comm)

for example lcd_command(0x38);

but 0x38 is not passed into the function,
can you let me know why ?
thanks

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

I change the code :

#include 
#include 

// Define the bits in the port 
typedef struct 
{ 
   unsigned char bit0 : 1, 
                 bit1 : 1, 
                 bit2 : 1, 
                 bit3 : 1, 
                 bit4 : 1, 
                 bit5 : 1, 
                 bit6 : 1, 
                 bit7 : 1; 
} bit_field; 

// Define macro to get the value of each bit 
#define GET_BIT(port) (*(volatile bit_field *) (_SFR_ADDR(port))) 

// Define functions for each bit of the I/O ports in the program 


#define rs  GET_BIT(PORTC).bit0
#define rw  GET_BIT(PORTC).bit1
#define en  GET_BIT(PORTC).bit2
#define data_port PORTD
void test(unsigned char data1);

void test(unsigned char data1)
{
	data_port = data1;
	en = 1;
	_delay_ms(50);
	rs = 0;
	_delay_ms(50);
	rw = 0;
	_delay_ms(80);
	en = 0;
}

int main (void)
{
  	DDRC = 0xFF;
	DDRD = 0xFF;
   while(1)
    {
	
		PORTD = 0x38;
		_delay_ms(50);
		PORTD = 0x01;
		_delay_ms(50);
		/*
		test(0x38);
		_delay_ms(50);
		test(0x01);
        */

    }
}

I tested with

		PORTD = 0x38;
		_delay_ms(50);
		PORTD = 0x01;
		_delay_ms(50);

it's working but with

		test(0x38);
		_delay_ms(50);
		test(0x01);

it's not working......do you have idea ? thanks

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

I built that code (BTW your GET_PORT macro is wrong - though it works) and find:

  a2:	d8 e3       	ldi	r29, 0x38	; 56
...
      test(0x38);
  c2:	8d 2f       	mov	r24, r29
  c4:	0e 94 36 00 	call	0x6c	; 0x6c 

So there's no question that this code is passing 0x38 into the function (GCC uses R24 for the first parameter). If it's not working it's something else - the parameter is passed.

Oh and I cleared the warnings from the GET_PORT macro with:

// Define macro to get the value of each bit
#define GET_BIT(port) (*(volatile bit_field *) (&port))

(that is I replaced _SFR_ADDR with & ).

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

clawson wrote:
I built that code (BTW your GET_PORT macro is wrong - though it works) and find:

  a2:	d8 e3       	ldi	r29, 0x38	; 56
...
      test(0x38);
  c2:	8d 2f       	mov	r24, r29
  c4:	0e 94 36 00 	call	0x6c	; 0x6c 

So there's no question that this code is passing 0x38 into the function (GCC uses R24 for the first parameter). If it's not working it's something else - the parameter is passed.

Oh and I cleared the warnings from the GET_PORT macro with:

// Define macro to get the value of each bit
#define GET_BIT(port) (*(volatile bit_field *) (&port))

(that is I replaced _SFR_ADDR with & ).

so what's wrong with it ??
how can you debug like this ?

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

the complete code, I don't understand why is it freezing ??
May be you guys have a clue ? thanks

#include 
#include 

//Mention Clock frequency here
#define _XTAL_FREQ 8000000

// structure to allow bit field operations, name conversions: PORTA.0 -> PORT_A.b0  PORTB.7 -> PORT_B.b7
typedef struct{ uint8_t b0:1;
	uint8_t b1:1;
	uint8_t b2:1;
	uint8_t b3:1;
	uint8_t b4:1;
	uint8_t b5:1;
	uint8_t b6:1;
uint8_t b7:1; } bits;

// define all the ports of your microcontroller, add more ports depending on the available mcu ports
#define PORT_A (* (volatile bits *) &PORTA)
#define PIN_A (* (volatile bits *) &PINA)
#define DDR_A (* (volatile bits *) &DDRA)

#define PORT_B (* (volatile bits *) &PORTB)
#define PIN_B (* (volatile bits *) &PINB)
#define DDR_B (* (volatile bits *) &DDRB)

#define lcd_data_pin  PORTD
#define en  PORT_A.b0
#define rs  PORT_A.b1
//#define rw  PORT_A.b2


void lcd_init();
void lcd_data(unsigned char data1);
void lcd_cmd(unsigned char cmd);
void lcd_control(unsigned char cmdordata);
void lcd_string(unsigned char *str);




void lcd_data(unsigned char data1)
{
	
	lcd_data_pin = data1;
	lcd_control(2);
	
	
}

void lcd_cmd(unsigned char cmd){
	
	lcd_data_pin = cmd;
	lcd_control(1);
}

void lcd_control(unsigned char cmdordata){
	
	if(cmdordata == 1){
		rs=0;
		//rw=0;
		en=1;
		_delay_ms(150);
		en=0;
	}
	else if(cmdordata == 2){
		rs=1;
		//rw=0;
		en=1;
		_delay_ms(150);
		en=0;
	}
}

void lcd_init(){
	
	lcd_cmd(0x38);
	_delay_ms(500);
	lcd_cmd(0x0E);
	_delay_ms(500);
	lcd_cmd(0x01);
	_delay_ms(500);
	lcd_cmd(0x06);
	_delay_ms(500);
	lcd_cmd(0x0C);
	_delay_ms(500);
	lcd_cmd(0x80);
	
}

void lcd_string(unsigned char *str){
	
	while(*str){
		lcd_data(*str++);
	}
	
}

test_port()
{
	rs=0;
	_delay_ms(100);
	rs=1;
	en=0;
	_delay_ms(100);
	en=1;
	_delay_ms(100);
	lcd_data_pin = 0xFF;
	_delay_ms(100);
	lcd_data_pin = 0x00;
	_delay_ms(100);
}

unsigned char msg[20] = "Working?";

int main(){
	
	
	
	DDRA = 0xFF;
	DDRD = 0xFF;
	PORTA = 0x00;
	PORTD = 0x00;
	
	
	lcd_init();
	
	while(1){
		
		
		lcd_cmd(0x01);
		lcd_cmd(0x80);
		lcd_data('A');
		lcd_cmd(0xC0);
		lcd_string(msg);
		
	}
	
	return (0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

try single stepping through the code in the disassembly window with the simulator.

99.99999% of the time there will be a really simple and obvious answer.... at least in retrospect.

regards
Greg

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

@bianchi77,

Please don't cross post. You now seem to be asking about this same code in threads both here and in AVR Forum.

Moderator

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

gregd99 wrote:
try single stepping through the code in the disassembly window with the simulator.

99.99999% of the time there will be a really simple and obvious answer.... at least in retrospect.

Thanks for your suggestion,
it works on simulation but on the board, it's not working allright, I have tested the port one by one, and it's ok....

but by the time I combine port A and port D working together, it's freezing.....I do not understand it.....weird...

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

Have a look on PORTD testing without PORTA:
http://youtu.be/8bxD9wj81yw

#include 
#include 

// structure to allow bit field operations, name conversions: PORTA.0 -> PORT_A.b0  PORTB.7 -> PORT_B.b7
typedef struct{ uint8_t b0:1;
                uint8_t b1:1;
                uint8_t b2:1;
                uint8_t b3:1;
                uint8_t b4:1;
                uint8_t b5:1;
                uint8_t b6:1;
                uint8_t b7:1; } bits;
 
// define all the ports of your microcontroller, add more ports depending on the available mcu ports
#define PORT_A (* (volatile bits *) &PORTA)
#define PIN_A (* (volatile bits *) &PINA)
#define DDR_A (* (volatile bits *) &DDRA)
 
#define PORT_B (* (volatile bits *) &PORTB)
#define PIN_B (* (volatile bits *) &PINB)
#define DDR_B (* (volatile bits *) &DDRB)
 
//Mention Clock frequency here
#define _XTAL_FREQ 8000000 
 
#define lcd_data_pin PORTD

#define en PORT_A.b0
#define rs PORT_A.b1
#define rw PORT_A.b2
 


 
void lcd_init();
void lcd_data(unsigned char data1);
void lcd_cmd(unsigned char cmd);
void lcd_control(unsigned char cmdordata);
void lcd_string(unsigned char *str);
 
 
void lcd_init(){
    /*
    lcd_cmd(0x02);      
    lcd_cmd(0x28);      
    lcd_cmd(0x0C);
    lcd_cmd(0x06);
 	lcd_cmd(0x80);
	*/
	lcd_data_pin = 0x02;
	_delay_ms(50);
	lcd_data_pin = 0x28;
	_delay_ms(50);
	lcd_data_pin = 0x0C;
	_delay_ms(50);
	lcd_data_pin = 0x06;
	_delay_ms(50);
	lcd_data_pin = 0x80;
	_delay_ms(50);
 
}
 
void lcd_data(unsigned char data1)
{
     
    
    lcd_data_pin = data1;// & 0x0F;
    lcd_control(2);
/*
	lcd_data_pin = (data1>> 4) & 0x0F;
    lcd_control(2);
*/    
        
}
 
void lcd_cmd(unsigned char cmd){
    DDRD = 0xFF;
    lcd_data_pin = cmd ;//& 0x0F;
    //lcd_control(1);
 /*
    lcd_data_pin = (cmd >> 4) & 0x0F;
    lcd_control(1);
 */
 
}
 
void lcd_control(unsigned char cmdordata){
 
    if(cmdordata == 1){
        en=1;
        rs=0;
        rw=0;
        _delay_ms(1);       
        en=0;
    }
    else if(cmdordata == 2){
        en=1;
        rs=1;
        rw=0;
        _delay_ms(1);
        en=0;
    }
}
 
void lcd_string(unsigned char *str){
 
    while(*str){
        lcd_data(*str++);       
    }
 
}
 
 
 
 
int main(){
 
    DDRA = 0xFF;
    DDRD = 0xFF;
 
    //lcd_init();
    //lcd_data('A');
    
    
    while(1){
         //lcd_cmd(0xFF);
		 //_delay_ms(50);
         //lcd_cmd(0x00);
		 _delay_ms(50);
		 lcd_init();

        //lcd_string("Working?");
 
    }
    
    return (0);
}

it's freezing by the time I combine with PORTA ( LCD control)

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

Quote:
it's freezing
What do you mean by "freezing"?
Quote:
LCD control
If you mean the function lcd_control(), the code as written never gets to that function. Any code that might call that function is commented out.

lcd_data_pin = 0x02; 
_delay_ms(50); 
lcd_data_pin = 0x28; 
_delay_ms(50); 
lcd_data_pin = 0x0C; 
_delay_ms(50); 
lcd_data_pin = 0x06; 
_delay_ms(50); 
lcd_data_pin = 0x80; 
_delay_ms(50);

This code accomplishes nothing. You need to toggle the E pin for the LCD to pay any attention to anything that you send to it.

Regards,
Steve A.

The Board helps those that help themselves.

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

it works on ATMEGA32, but not working on ATMEGA128
Please see the video :
http://www.youtube.com/watch?v=7...

#include 
#include 

// structure to allow bit field operations, name conversions: PORTA.0 -> PORT_A.b0  PORTB.7 -> PORT_B.b7
typedef struct{ uint8_t b0:1;
                uint8_t b1:1;
                uint8_t b2:1;
                uint8_t b3:1;
                uint8_t b4:1;
                uint8_t b5:1;
                uint8_t b6:1;
                uint8_t b7:1; } bits;
 
// define all the ports of your microcontroller, add more ports depending on the available mcu ports
#define PORT_D (* (volatile bits *) &PORTD)
#define PIN_D (* (volatile bits *) &PIND)
#define DDR_D (* (volatile bits *) &DDRD)
 
#define PORT_G (* (volatile bits *) &PORTG)
#define PIN_G (* (volatile bits *) &PING)
#define DDR_G (* (volatile bits *) &DDRG)
 
//Mention Clock frequency here
#define _XTAL_FREQ 8000000 
 
#define lcd_data_pin PORTA

#define en PORT_D.b0
#define rs PORT_D.b1
#define rw PORT_D.b2
 

void lcd_init();
void lcd_data(unsigned char data1);
void lcd_cmd(unsigned char cmd);
void lcd_control(unsigned char cmdordata);
void lcd_string(unsigned char *str);
 

void lcd_init(){
    
    lcd_cmd(0x30);
	_delay_ms(100);      
    lcd_cmd(0x38);
	_delay_ms(100);      
    lcd_cmd(0x0F);
	_delay_ms(100);
   	lcd_cmd(0x80);
	_delay_ms(100);

}
 
void lcd_data(unsigned char data1)
{
     
    
    lcd_data_pin = data1;// & 0x0F;
     	en=1;
        rs=1;
        rw=0;
        _delay_ms(10);
        en=0;
        
}
 
void lcd_cmd(unsigned char cmd){
    lcd_data_pin = cmd ;
	    en=1;
        rs=0;
        rw=0;
        _delay_ms(10);       
        en=0;
 
}
	

 
void lcd_string(unsigned char *str){
 
    while(*str){
        lcd_data(*str++);       
    }
 
}
 
 
 
 
int main(){
 
    DDR_D.b0 = 1;
	DDR_D.b1 = 1;
	DDR_D.b2 = 1;
    DDRA = 0xFF;
 
    lcd_init();
    
    
    while(1){
 	  _delay_ms (200);
		lcd_cmd(0x80);//put the cursor into the first row
        _delay_ms (300);
        lcd_cmd(0x01);//Clear display
	    _delay_ms (300);
        lcd_cmd(0xC0);//goto second row
        _delay_ms (300); 
       lcd_cmd(0x01); //Clear display
       
	   lcd_string("HELLO ATMEGA32");
 
    }
    
    return (0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

but not working on ATMEGA128

9 times out of 10 on this board when something doesn't work on mega128 (or mega64) it's because of the M103C compatibility fuse (which is enabled by default).

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

clawson wrote:
Quote:

but not working on ATMEGA128

9 times out of 10 on this board when something doesn't work on mega128 (or mega64) it's because of the M103C compatibility fuse (which is enabled by default).

Clawson,

Do you have any ideas on fixing this issue ?
thanks

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

What did your datasheet say when you searched for "M103C"?

(as you'll read there it's one of the fuse bits and is changed using your ISP programmer).

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

It works by the time I write it as ATMEGA16...abit weird...doesn't it ??

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

I get the answer,
Set M103C bit fuse to 1,
Now it's working as ATMEGA128 smoothly,

Thanks guys :D