Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Programming of MUC

Status
Not open for further replies.

rabhishek91

New Member
Hi everyone. :)
I am working on a code where i need to display messages on LCD depending on the input to MUC(Atmega32A).

Below is the program where i need to display messages based on PortA input.

First. i'll read the pin0 of PORTA (continously). Depending on the value of that pin i'll control LCD messages. I know i have made lot of mistakes in programming. This is my first program so i am unaware of what to use.
Is this programming method correct ? or do i need to use some other method ?
Please help me.



C:
int main()
{
   DDRA = 0x00; //configure portA as input
   while(1) // To run the program continuously
   {
      if(PORTA&=1<<PINA0)//Check high on pin0 of portA
      {
         DDRB=0xff; // Configure PORTB as output for data bus
         DDRD=0x07; //Configure PORTD as output for control lines
         init_LCD(); // initialization of LCD
        _delay_ms(50); // delay of 50 mili seconds
        LCD_write_string("ABC");
      }
   else
     {
         DDRB=0xff; 
         DDRD=0x07; 
         init_LCD(); 
         _delay_ms(50); 
         LCD_write_string("Thank you");
      }

}

return 0;
}
 
Last edited by a moderator:
Only "completely" wrong is the first if "//Check high on pin0 of portA". You are assigning a value 0x01 to PORTA and therefore the statement is always true. The correct way is to do bitwise AND with a bitmask and the port value.

When reading port A value, you read from the register PINA (no from PORTA).
Below is the right code. I assume that PINA0 is just a macro for the pin number.

/* Check high on pin0 of portA */
if(PINA & (1<<PINA0))


You should take initializations out from the while loop and call them only once at the beginning of the program:

C:
int main()
{
   DDRB=0xff; // Configure PORTB as output for data bus
   DDRD=0x07; //Configure PORTD as output for control lines
   DDRA = 0x00; //configure portA as input
   init_LCD(); // initialization of LCD
   while(1) // To run the program continuously
   {
      if(PINA & (1<<PINA0))//Check high on pin0 of portA
      {
        _delay_ms(50); // delay of 50 mili seconds
        LCD_write_string("ABC");
      }
   else
     {
         
         _delay_ms(50); 
         LCD_write_string("Thank you");
      }
 
}
 
return 0;
}

What programming environment are you using? Are you using avr-gcc and avr-libc?
 
Last edited:
Only "completely" wrong is the first if "//Check high on pin0 of portA". You are assigning a value 0x01 to PORTA and therefore the statement is always true. The correct way is to do bitwise AND with a bitmask and the port value.

When reading port A value, you read from the register PINA (no from PORTA).
Below is the right code. I assume that PINA0 is just a macro for the pin number.

/* Check high on pin0 of portA */
if(PINA & (1<<PINA0))


You should take initializations out from the while loop and call them only once at the beginning of the program:

What programming environment are you using? Are you using avr-gcc and avr-libc?

Thanks for your reply sir. :)
I corrected the program statement to if(bit_is_clear(PINA,0)) //Check pin0 of portA
It worked sir.

"You should take initializations out from the while loop and call them only once at the beginning of the program"- Sir before it worked normally but after i removed initialization out of loop i am getting weird results on LCD display. I have attached the pictures of before and after display of LCD.
Picture-1 represents the LCD initialization done outside the loop and Picture-2 represents the LCD initialization done inside the loop.

Between i use AVR GCC sir.
 

Attachments

  • LCD-(Initialisation done outside).JPG
    LCD-(Initialisation done outside).JPG
    151.3 KB · Views: 328
  • LCD-(Initialisation done inside loop).JPG
    LCD-(Initialisation done inside loop).JPG
    110.9 KB · Views: 364
Last edited:
Sir before it worked normally but after i removed initialization out of loop i am getting weird results on LCD display. I have attached the pictures of before and after display of LCD.
Picture-1 represents the LCD initialization done outside the loop and Picture-2 represents the LCD initialization done inside the loop.

When you write to the LCD the cursor stays at the end of last string you wrote.. in this case at the end of "Than you". Next time you write to the LCD the text is written starting from the place where you left the cursor.. in this case "Thank youThank you". You need to clear the LCD before each write. Clearing the LCD also moves the cursor at the beginning. Initializing the LCD clears it and moves the cursor at the beginnin, but also does some other stuff which are unnecessary.

Try something like:

C:
int main()
{
   DDRB=0xff; // Configure PORTB as output for data bus
   DDRD=0x07; //Configure PORTD as output for control lines
   DDRA = 0x00; //configure portA as input
   init_LCD(); // initialization of LCD
   while(1) // To run the program continuously
   {
      if(bit_is_clear(PINA,0)) //Check pin0 of portA
      {
        _delay_ms(50); // delay of 50 mili seconds
        LCD_clear(); // Clear the LCD and move cursor to position (0,0)
        LCD_write_string("ABC");
      }
   else
     {
         
         _delay_ms(50); 
         LCD_clear(); // Clear the LCD and move cursor to position (0,0)
         LCD_write_string("Thank you");
      }
 
}
 
return 0;
}

The LCD_clear() function can be named differently.. check your LCD library for correct function.
 
Last edited:
When you write to the LCD the cursor stays at the end of last string you wrote.. in this case at the end of "Than you". Next time you write to the LCD the text is written starting from the place where you left the cursor.. in this case "Thank youThank you". You need to clear the LCD before each write. Clearing the LCD also moves the cursor at the beginning. Initializing the LCD clears it and moves the cursor at the beginnin, but also does some other stuff which are unnecessary.

The LCD_clear() function can be named differently.. check your LCD library for correct function.

Thank you so much sir. :)
I got the output correctly.
However while building the program i got 3 warnings . Does it matters ?
I have posted the warnings along with the code below. Please let me know the changes if possible.


../Test3-lcd.c:37: warning: implicit declaration of function 'LCD_write_string'
../Test3-lcd.c:89: warning: conflicting types for 'LCD_write_string'
../Test3-lcd.c:37: warning: previous implicit declaration of 'LCD_write_string' was here



Code

//LCD Program/*
//LCD DATA port----PORT B
//signal port------PORT D
// rs-------PD0
// rw-------PD1
// en-------PD2 */

#define F_CPU 16000000UL
#include<avr/io.h>
#include<util/delay.h>

#define LCD_DATA PORTB //LCD data port

#define ctrl PORTD
#define en PD2 // enable signal
#define rw PD1 // read/write signal
#define rs PD0 // register select signal


void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);

int main()
{
DDRA = 0b00000000; //configure portA as input
DDRC= 0xff; //Configure portC as output
DDRB=0xff; // Configure PORTB as output for data bus
DDRD=0x07; //Configure PORTD as output for control lines
init_LCD(); // initialization of LCD
while(1)
{
if(bit_is_clear(PINA,0)) //Check high on pin0 of portC
{
PORTC&=~(1<<PINC0); // turn off buzzer
_delay_ms(50); // delay of 50 mili seconds
LCD_cmd(0x01); // clear LCD
LCD_write_string("Thank you");
}
else
{
PORTC|= 1<<PINC0; //Turn on buzzer

_delay_ms(50); // delay of 50 mili seconds
LCD_cmd(0x01); // clear LCD
LCD_write_string("Buckle up");
}

}

return 0;
}

void init_LCD(void)
{
LCD_cmd(0x38); // initialization of 16X2 LCD in 8bit mode
_delay_ms(1);

LCD_cmd(0x01); // clear LCD
_delay_ms(1);

LCD_cmd(0x0E); // cursor ON
_delay_ms(1);

LCD_cmd(0x80); // ---8 go to first line and --0 is for 0th position
_delay_ms(1);
return;
}

void LCD_cmd(unsigned char cmd)
{
LCD_DATA=cmd;
ctrl =(0<<rs)|(0<<rw)|(1<<en);
_delay_ms(1);
ctrl =(0<<rs)|(0<<rw)|(0<<en);
_delay_ms(50);
return;
}

void LCD_write(unsigned char data)
{
LCD_DATA= data;
ctrl = (1<<rs)|(0<<rw)|(1<<en);
_delay_ms(1);
ctrl = (1<<rs)|(0<<rw)|(0<<en);
_delay_ms(50);
return ;
}

void LCD_write_string(unsigned char *str) //store address value of the string in pointer *str
{
int i=0;
while(str!='\0') // loop will go on till the NULL character in the string
{
LCD_write(str); // sending data on LCD byte by byte
i++;
}
return;
}
 
You have to declare all your functions. After these lines:

void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);

add the missing function declaration:

void LCD_write_string(unsigned char *str);
 
You have to declare all your functions. After these lines:

void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);

add the missing function declaration:

void LCD_write_string(unsigned char *str);

Sir i am very new to these stuff. If you don't mind could you please elaborate ?
 
This part of the code:

C:
void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);

int main()
{
...etc

should be:
C:
void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);
void LCD_write_string(unsigned char *str);  // ADD THIS LINE

int main()
{
...etc

Those lines are called "function declarations" and they tell the compiler that these functions are somewhere.. simply put, I hope.
 
This part of the code:

C:
void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);

int main()
{
...etc

should be:
C:
void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);
void LCD_write_string(unsigned char *str);  // ADD THIS LINE

int main()
{
...etc

Those lines are called "function declarations" and they tell the compiler that these functions are somewhere.. simply put, I hope.

Thanks for the info sir.
Sir i got that problem solved but got two new warnings at

../Test3-lcd.c:37: warning: pointer targets in passing argument 1 of 'LCD_write_string' differ in signedness
../Test3-lcd.c:45: warning: pointer targets in passing argument 1 of 'LCD_write_string' differ in signedness



if(bit_is_clear(PINA,0)) //Check high on pin0 of portC
{
PORTC&=~(1<<PINC0); // turn off buzzer
_delay_ms(50);
LCD_cmd(0x01); // This line warning
LCD_write_string("Thank you");
}
else
{
PORTC|= 1<<PINC0; //Turn on buzzer

_delay_ms(50);
LCD_cmd(0x01); // This line warning
LCD_write_string("Buckle up");
}
 
You marked the wrong lines red. The warning come from the lines where you call the function LCD_write_string("Thank you"); and LCD_write_string("Buckle up");.

You can fix this by changing the input parameter of that function to char *str
void LCD_write_string(char *str);

Make the change to the declaration and to the function definiton itself.

C:
/* Declaration of the function */
void LCD_write_string(char *str); //CHANGE THIS

/* Definition of the function */
void LCD_write_string(char *str)	//CHANGE THIS
{
    int i=0;
    while(str[i]!='\0')	 // loop will go on till the NULL character in the string 
    {
        LCD_write(str[i]);	 // sending data on LCD byte by byte
        i++;
    }
    return;
}
 
You marked the wrong lines red. The warning come from the lines where you call the function LCD_write_string("Thank you"); and LCD_write_string("Buckle up");.

You can fix this by changing the input parameter of that function to char *str
void LCD_write_string(char *str);

Make the change to the declaration and to the function itself.

C:
/* Declaration of the function */
void LCD_write_string(char *str);

/* Implementation of the function */
void LCD_write_string(char *str)	//CHANGE THIS
{
    int i=0;
    while(str[i]!='\0')	 // loop will go on till the NULL character in the string 
    {
        LCD_write(str[i]);	 // sending data on LCD byte by byte
        i++;
    }
    return;
}

It worked sir.Thanks a ton .:) You really helped me a lot.
Sir i have very little knowledge about this and can't always trouble everyone in this forum.
Can you suggest me a link where i can learn about these stuff i.e. programming?
 
It worked sir.Thanks a ton .:) You really helped me a lot.
Sir i have very little knowledge about this and can't always trouble everyone in this forum.
Can you suggest me a link where i can learn about these stuff i.e. programming?

It is hard to find really good stuff for learning C for microcontrollers.. All the good books and websites are for desktop computers. But it still is the same language. You just can't use some features in a microcontroller (like dynamic memory allocation etc.)

Here is a pretty good site.. well organized.
**broken link removed**
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top