Connect with us

Programming of MUC

Discussion in 'Microcontrollers, Programming and IoT' started by rabhishek91, Apr 4, 2013.

Scroll to continue with content
  1. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    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 ?:confused:
    Please help me.



    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;
    }
     
  2. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,496
    2,837
    Jan 21, 2010
    What does your program actually do (does it work)? Are there any bugs?
     
  3. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    Thanks for replying.:)
    Bro there was a mistake in if(PORTA&=1<<PINA0). I corrected it by changing to if(bit_is_clear(PINA,0)) //Check pin0 of portA.

    The program reads the values from input port. If it is high then message A is displayed else message B is displayed. The program now works.:)
    My doubt is since i am reading the value from a sensor in real-time continuously. Is this the best way to read the values or are there any other way like using interrupts etc ?
     
  4. Harald Kapp

    Harald Kapp Moderator Moderator

    11,513
    2,651
    Nov 17, 2011
    This is called polling. Not an unusual method and not bad if your µC has enough time for it.

    Whether you need to monitor the sensor continuously depends on your application. If you need to react very fast to a change in sensor signal, you need to poll often. If you can tolerate a small delay in the reaction to the sensor signal, you can reduce the poll rate and do other things in between.
    You could, for example, use a timer to trigger readout of the sensor every fes milliseconds. But then again that usually means you have the timer generate an interrupt to start the sensor-read routine. It is more logical to use the sensor as interrupt source in the first place.
    Using a direct interrupt is suitable if your sensor signal is digital (as it is here). Your µC can now perform any other operations and will be alerted to a change in the sensor signal by an interrupt. Good if you have to perform other tasks than monitoring the sensor.
    An interrupt would not be suitable if for example your sensor is analog and you need to A/D-convert the input signal. A change in analog level will generally not trigger an interrupt, so you need to poll. Unless, that is, your analog input has a programmable comparator (see e.g. here). This feature is not typically available.
     
    Last edited: Apr 4, 2013
  5. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    Thank you sir.:) This is what i wanted to know.
    My application is not crucial so delay of milliseconds won't bother me. I'll got with the easy method
     
  6. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    Bear in mind that you should not update the LCD from within an interrupt handler, for several reasons: it probably takes a significant amount of time to update the LCD, and interrupt handlers should take as little time as possible, and other parts of your program may need to update the LCD now or in the future, and interrupting them with other LCD programming commands will break the command in progress so when the interrupt handler returns, the LCD will be in the wrong state to continue the command that was being sent (that was interrupted).

    Beyond that, first, you should be initialising the DDR (and any other registers) for communicating with the LCD only at the start of your program; there's no need to repeat the initialisation within the conditional section of your code, and there is also no need to update the LCD if the input state hasn't changed. I would structure the program like this:

    main() {
    // initialise DDRs, etc
    while (1) {
    update_lcd_from_port_status();
    // do other stuff
    }//while
    }//main

    void update_lcd_from_port_status(void) {
    static int last_port_status = -1;
    int new_port_status;
    new_port_status = bit_is_set(PINA, 0);
    if (new_port_status != last_port_status) { // Port status has changed
    last_port_status = new_port_status;
    LCD_write_string(new_port_status ? "ABC" : "Thank you");
    }//new!=last
    }//update_lcd_from_port_status

    This design has a separate function, update_lcd_port_status(), which is called repeatedly from the while(1) loop in the mainline. This function keeps a record of the last known input port status in static variable last_port_status and only updates the LCD when the port status changes.
     
    Last edited: Apr 5, 2013
  7. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    Thanks a lot sir.:) I got the correction done. It worked. I added a line to clear the LCD on it's each update.

    void update_lcd_from_port_status(void) {
    static int last_port_status = -1;
    int new_port_status;
    new_port_status = bit_is_set(PINA, 0);
    if (new_port_status != last_port_status) { // Port status has changed
    LCD_cmd(0x01); //To clear the lcd
    last_port_status = new_port_status;
    LCD_write_string(new_port_status ? "ABC" : "Thank you");
    }//update_lcd_from_port_status

    Sir which command is used to clear the cursor on LCD ? I have attached the picture wherein i need to remove the cursor.
     

    Attached Files:

  8. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    I don't know. You haven't even told us the part number of the LCD display! My crystal ball is having its 10,000 km lube and oil change this week!

    You have the data sheet for it, right? You should be able to figure out what command to use, if there is one.
     
  9. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    Okay sir. I am new to these stuff so i didn't had much idea about it. I'll try to find it in datasheet.
     
  10. gorgon

    gorgon

    603
    24
    Jun 6, 2011
    To turn the cursor off you need to reset bit1 in the displaycontrol command to '0'

    The format for this command is 00001DCB - where bit0(B) is the blink control, bit1(C) is the cursor control, an bit2(D) is the display on/off control.

    I suppose this is done in the init_LCD(); function, so you need to look it up there.

    Note that this is the command for the HD44780 LCD controller, the one normally used for these displays.
     
  11. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    Thank you sir. I followed the same steps you mentioned . I got it.
     
  12. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    Sir what do you mean by
    static int last_port_status = -1;
    I could not understand that portion.I mean why have you assigned it to -1 ?
    Please reply.
     
  13. gorgon

    gorgon

    603
    24
    Jun 6, 2011
    -1 is the same as FFh.
    static tell you that it will only set this variable to -1 the first time, and then keep the current value, whatever it is.
     
    Last edited: Apr 9, 2013
  14. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    I assigned -1 (equal to 0xFFFF for a 16-bit integer) initially so that the first time update_lcd_from_port_status() is called, it will unconditionally update the LCD. This is guaranteed because the actual port status is 0 or 1 (FALSE or TRUE), and the first time the function is called, this will necessarily be different from the value in last_port_status, so the LCD will be updated.

    Once the function has been called once, last_port_status will be either 0 or 1 and the LCD will only be updated if the port status changes from its previous value.

    To put it another way, assigning -1 to last_port_status is equivalent to saying that the last known port status is "neither high nor low", so the first time the new port status is tested, it will always be detected as "different from the last port status" and the LCD will be necessarily be updated.

    I could have used 2 instead of -1. Any value that isn't 0 or 1 will ensure this behaviour.
     
  15. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    Thank you so much sir. That was clear to the point. I understood it.:)
     
  16. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    LCD update

    Sir i have got an issue now. I added another condition to be checked on Pin1 of PortA before checking Pin0 of PortA. So the very first time when the Pin1 goes high and the Pin0 goes high ,the LCD won't get updated.
    The code is as shown below.

    Code:
    while(1)
    	{
    		update_lcd_from_port_status();
    		if(bit_is_set(PINA,1))       [COLOR="DarkOrange"]//Check high on pin1 of portA[/COLOR]
    		{
    			if(bit_is_clear(PINA,0))	 [COLOR="DarkOrange"]//Check low on pin0 of portA[/COLOR]
    			{
    				PORTC&=~(1<<PINC0);      [COLOR="DarkOrange"]//Turn off buzzer[/COLOR]
    				update_lcd_from_port_status();
    				//LCD_write_string("Thank you");
       			 }
    			else
    			{
    				PORTC|= 1<<PINC0;    	 [COLOR="DarkOrange"]//Turn on buzzer[/COLOR]
    				update_lcd_from_port_status();
    				//LCD_write_string("Buckle up");
    			}
    		}
    		else
    		{
    		LCD_cmd(0x01);			[COLOR="DarkOrange"] //CLear the LCD[/COLOR]
    		PORTC&=~(1<<PINC0);     [COLOR="DarkOrange"] //Turn off buzzer[/COLOR]
    		}
    	}
    		 
    	return 0;
    }
    
    void update_lcd_from_port_status(void) 
    {
    	static int last_port_status = -1;
    	int new_port_status;
    	new_port_status = bit_is_set(PINA, 0);
    	if (new_port_status != last_port_status) 
    	{                               [COLOR="DarkOrange"]// Port status has changed[/COLOR]
    		LCD_cmd(0x01);
    		last_port_status = new_port_status;
    	LCD_write_string(new_port_status ? "Buckle up" : "Thank you");
    	}
    }									[COLOR="DarkOrange"]//Update_lcd_from_port_status
    [/COLOR]
     
  17. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    The purpose of keeping last_port_status is to avoid updating the LCD each time through the loop. The program remembers the last state of the input and detects whether the input has changed. If it has, it updates the "last known value" variable and updates the LCD to reflect the change.

    If you are now monitoring two pins of the port, you can still use the same idea to avoid updating the LCD continuously. In that case it's probably best to keep a variable that reflects the last information displayed on the LCD. You can use an enum to define the values for this variable:

    typedef enum {
    LCD_SHOWING_NOTHING,
    LCD_SHOWING_THANK_YOU,
    LCD_SHOWING_BUCKLE_UP
    };

    You initialise your "last known state" variable to LCD_SHOWING_NOTHING, because at program startup the LCD is blank or showing unknown text, then each time through the loop you calculate what the LCD _should_ say. After you've decided what the LCD should say, you compare that value to the last known LCD state variable. If they're different, update the last known state to the new state, and send the appropriate string to the LCD.

    All of those calculations should be done in the update_LCD_from_port_status function, which can then be called every time through the while (1) loop in main(). Each time it is called, it calculates what the LCD _should_ show, compares that to what the LCD _is_ showing, and updates if they're different.

    I hope that answers the question you have. If not, explain your question clearly.
     
  18. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    Thanks for helping me out sir.
    I followed your explanation and have understood the use of separate routine to update LCD. However, i am unable to work on the syntax. Also to give you a clear idea of my problem, i made a small video of 2 minutes. Below is the link to it please watch it sir.

     
  19. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,271
    Nov 28, 2011
    I'm at my partner's house and I don't have fast internet access, so I'm afraid I cannot watch your video until Tuesday. Can ANYONE ELSE help before then? Otherwise, I will reply on Tuesday.

    BTW, please don't call me sir!
     
  20. rabhishek91

    rabhishek91

    41
    0
    Feb 15, 2013
    No problem bro. I'll wait till tuesday. :)
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-