M48,RTC and LCD

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

Hi Freaks,
I have limped along to a project that uses an HD44780 LCD and M48 with 8MHz external crystal. I am trying to display time on my LCD. I am starting with the seconds display to see if it works. The LCD code is Johann's code. Here is the program:


#include 

#include 

#include 

#include 


volatile unsigned char seconds,minutes,hours,days,months,years;



#define LCD_DATA_PORT PORTD

#define LCD_DATA_DDR  DDRD

 

/* Here are some defines for the control connections

 * (RS, R/W and E on the LCD display module). These can be wired

 * to any pins on any port A..D (all to the same port though).

 * You need to alter these to fit your wire up of your display.

 */

#define LCD_CTRL_PORT PORTD

#define LCD_CTRL_DDR  DDRD

#define LCD_RS        PD0 //2

#define LCD_RW        PD1//3

#define LCD_E         PD2//4

#define LCD_FUNCTION_SET      0x38 // 0b00110000

#define LCD_FUNCTION_SET_4BIT 0x28 // 0b00101000

#define LCD_DISPLAY_OFF       0x08 // 0b00001000

#define LCD_DISPLAY_ON        0x0F // 0b00001111

#define LCD_DISPLAY_CLEAR     0x01 // 0b00000001

#define LCD_ENTRY_MODE_SET    0x06 // 0b00000110

#define LCD_CURSOR_HOME       0x02 // 0b00000010


volatile unsigned char seconds,minutes,hours,days,months,years;

//volatile unsigned char transmit_time[10];


void LcdSendNibble( uint8_t nibble )

{

   _delay_ms(20);

 

   // Output upper nibble on the data ports upper bits

   LCD_DATA_PORT = (nibble & 0xF0) | (LCD_DATA_PORT & 0x0F);

 

   // Toggle the E line

   LCD_CTRL_PORT |= (1<<LCD_E);   // Going up..

   LCD_CTRL_PORT &= ~(1<<LCD_E);  // ..and down.

}

void LcdSendByte(uint8_t theByte)

{

   // Send the high nibble

   LcdSendNibble(theByte);

 

   // Shift theByte to get lower nibble in upper part...

   theByte = theByte << 4;

   // ...and send it

   LcdSendNibble(theByte);

}


void LcdSendInstruction( uint8_t theInstruction )

{

   // RS low for instructions

   LCD_CTRL_PORT &= ~(1<<LCD_RS);

 

   // Send the instruction

   LcdSendByte(theInstruction);

}



void LcdSendCharacter(uint8_t theChar)

{

   // RS high for characters to display

   LCD_CTRL_PORT |= (1<<LCD_RS);

 

   // Send the command

   LcdSendByte(theChar);

}


void LcdInitialize(void)

{

   // initialize LCD control lines

   LCD_CTRL_PORT &= ~(1<<LCD_RS);    // RS low

   LCD_CTRL_PORT &= ~(1<<LCD_RW);    // R/W low

   LCD_CTRL_PORT &= ~(1<<LCD_E);    // E low

 

   // initialize LCD control lines to output

   LCD_CTRL_DDR |= (1<<LCD_RS);

   LCD_CTRL_DDR |= (1<<LCD_RW);

   LCD_CTRL_DDR |= (1<<LCD_E);

 

   // initialize LCD data port to input

   LCD_DATA_DDR |= 0xF0;      // Data on high four bits of port for now...

    _delay_ms(15);

   LcdSendNibble( LCD_FUNCTION_SET );

   _delay_ms(5);

   LcdSendNibble( LCD_FUNCTION_SET );

   _delay_us(100);

   LcdSendNibble( LCD_FUNCTION_SET );

 

   // Now, still in 8-bit mode, set the display to 4-bit mode

   LcdSendNibble( LCD_FUNCTION_SET_4BIT );

 

   // We are now in 4-bit mode.

   // Do the rest of the init sequence.

   LcdSendInstruction( LCD_FUNCTION_SET_4BIT );

   _delay_ms(500);

   LcdSendInstruction( LCD_DISPLAY_OFF );

   _delay_ms(500);

   LcdSendInstruction( LCD_DISPLAY_CLEAR );

   _delay_ms(500);

   LcdSendInstruction( LCD_ENTRY_MODE_SET );

   _delay_ms(500);

   LcdSendInstruction( LCD_DISPLAY_ON );

   _delay_ms(500);

}

void timer_init()

   {

   TIMSK1 |= (1 << OCIE1A); //enable channel 1A interrupt

   sei(); //enable global interrupts


   TCCR1B |= (1 << CS12) | (0 << CS10) | ( 0 << CS11); //start timer at Fcpu/256


   TCCR1B |= (1 << WGM12);//set up for CTC mode
 

   OCR1A = 2000; //Value that the micro will compare with current count; THIS HAS BEEN ADJUSTED FOR M48 WITH external 8MHz crystal with NO CAP FOR A BREADBOARD

   }


void rtc_op()

   {
     seconds++;

	 PORTB ^= (1 << PB0);

	  LcdSendCharacter(seconds);
	  LcdSendInstruction(LCD_CURSOR_HOME);

     if (seconds == 60) 

      {

        seconds = 0;

        minutes++;

       }

        if (minutes == 60)

        {

          minutes=0;

          hours++;

        }

         if(hours == 24)

          {

            hours = 0;

            days++;

          }


  

   }

 

void go_to_sleep()

 {

   sleep_cpu();

 }








int main(void)

{
 
   
   DDRB = 0xFF;
   LcdInitialize();
   timer_init();  


 
for(;;)

    { 


     }



   return 0;

}

ISR(TIMER1_COMPA_vect)


   {  

      rtc_op();

   }



I have an LED on PB0 pin for troubleshooting. The LED is blinking at 1s intervals.

Here is what I see on the LCD:
When I turn the power on, the LCD starts before the LED.
Then from 0 - 9 blinks, there is one dark cursor block on the first location (upper left) on the LCD. This does not appear to blink. I am also seeing a very faint cursor on the second location which blinks.

Then after 9 counts (which I am measuring based on the LED blinking), the cursor in first position starts blinking but shows a dark block blinking and no numbers. After 9 counts, the same cursor starts showing some random characters like +,/ and so on.
After 9 counts it then shows numbers from 0 - 9 but it shows 2,4,6,8 skipping the odd numbers. Then this cycle repeats.

I am sending chars to the LCD. Do I need to convert this into integers? I understand that I am displaying only numbers from 0-9 with one digit on the LCD, but why do I get this random behavior? Is this an LCD delay issue?

Thanks for any help.

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

Quote:

I am sending chars to the LCD. Do I need to convert this into integers?

That's exactly your problem. If you use:

seconds = 35;
LcdSendCharacter(seconds);

I would predict that what you will see is a '#' character on the display. That's because 35 here is a "binary" value. You need to get this converted to a human readable ASCII representation for it to display OK. As you are using GCC the most obvious function to use to make this conversion is itoa() (the reason I mention GCC is that this particular library function is not standard and not all C compilers will necessarily have it or if they do it may work in a different way). So before outputting to the LCD try:
char buffer[8];

itoa(seconds, buffer, 10);

which says "take the binary value in 'seconds' convert it in base 10 (i.e. decimal) to a string of ASCII characters and place them in the array called 'buffer'". After this function has run you will find that:

buffer[0] = '3' (that is 51 or 0x33)
buffer[1] = '5' (that is 53 or 0x35)
buffer[2] = 0

The small problem you now face is that you have more than one character to be passed to LcdSendCharacter(). Now you may already have an LcdSendString() function but if you don't then add in a function such as:

void LcdSendString(char * str) {
  while(*str) {
    LcdSendCharacter(*str++);
  }
}

Now you can simply use:

LcdSendString(buffer);

to have the "35" string printed to the LCD. The fact that buffer[2]=0 is quite important in this as the SendString function steps along the given array ('buffer') printing each character it comes to until it finds an array entry holding 0 (that is the while(*str) which will be false when *str==0)

Cliff

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

That worked.Thanks a bunch Cliff. I have similar code for a UART program and I should have used the same code.

Now I can see the seconds displaying but when it rolls over i.e. it counts 58,59,60,10,20,30,40,50,60,70,80,90,10,11, and so on.So it retains the 0 after 60 all the way till 10.

I am trying to figure out how I can right justify my character.

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

Show the code you've actually used. One simplistic fix would be before the itoa() do:

memset(buffer, 0x00, sizeof(buffer));

but this is just papering over the cracks. I'd want to know why the itoa() is not zero-terminating after a single digit.

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

I'll start by saying I don't know C.

It looks like somewhere in your processing path your routine(s) are dropping the leading zero.

You can always loop with:
Get/Calc new data
Position cursor where you want it
Overwrite with Space Space
Position cursor where you want it, again
Write data
Delay a bit
Loop

Note that the next step is to only UPDATE the display IF the seconds have changed.

If you tight loop too quickly, your display will be very dim, because as soon as you write to it you are overwriting it with blanks, (spaces).

Google ASCII table, also, to see what the Char LCD wants data wise

JC

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

Well spotted JC - that sounds like the explanation - it's not buffer[] that's holding the previous 0 but the display itself. Either printing a line of ' ' or left-padding the string to right justify the display should do it. As only two digits are involved it'd be enough to say:

if (strlen(buffer) == 1) {
 LcdSendCharacter(' '); // pad before
}
LcdSendString(buffer);

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

Quote:

I am trying to figure out how I can right justify my character.

All you can eat here:
https://www.avrfreaks.net/index.p...

I posted my utoa() that has right-justification and leading-zero-supression features. There are also smaller and faster approaches posted.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Thanks Lee, Cliff and JC.

@Lee,

That is a nice link with lots of useful info.

@Cliff
The strlen idea worked.Thanks.

@JC,
At present I am sending my LCD character only when seconds have updated i.e. when the ISR has fired.However, I am doing all this in my ISR which I am planning to move out of ISR and send in main. I just wanted to try proof of concept before trimming down the fat from my program.

It's nice to get help from all you gurus.:)
Thanks a lot.

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

Quote:
It's nice to get help from all you gurus.

Or at least two Super Freaks and a meddleing tinkerer.

JC

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

Ok one last thing:
I am now trying to display an ADC return value on the second line on my LCD. I know on one of my previous post, there was a suggestion to play with the LCD DDRAM addressing to position the character on a specific X-Y location on the display so I am trying to do something like this:

#define LCD_HOME_FOR_TEMP     0x88

void rtc_op()

   {
     
	 
	 LcdSendInstruction(LCD_CURSOR_HOME);
	 char transmit_time[10];
	 

	 seconds++;

//	 PORTB ^= (1 << PB0);//for debugging can be removed in final application

  
      
     if (seconds == 60) 

      {



        
		    
        seconds = 0;
		

        minutes++;


 
       }

        if (minutes == 60)

        {

          minutes=0;

          hours++;

        }

         if(hours == 24)

          {

            hours = 0;

            days++;

          }


//itoa(seconds,buffer,10);

		  if(strlen(transmit_time)== 1)
		   {
		    
			 LcdSendCharacter(' '); //pad the character, right justify the display for single digit
			 }


	        

	        LcdSendInstruction(LCD_CURSOR_BLINK_OFF); //REMOVE BLINKING OF CURSOR
	        LcdSendInstruction(LCD_CURSOR_HOME);

  sprintf(transmit_time,"%02d:%02d:%02d", hours, minutes,seconds);
 transmit_time[9] = '\0';
 //transmit_time[9] = '\n';
 transmit_time[8]= '\r';
 LCDString(transmit_time);
LcdSendInstruction(LCD_HOME_FOR_TEMP);

   }

ISR(ADC_vect)

{

  ADC_value = ADC;

  if(ADC_value > 510) //temperature is > 65 deg C

   {

      
	  PORTB = 0x01; // Turn on LED2

	  //define new home
	  //return to home    
   
        LcdSendInstruction(LCD_HOME_FOR_TEMP);
        LcdSendCharacter('N');
         LcdSendInstruction(LCD_CURSOR_HOME);

    }
     

   else // LED normally off for room temperature

     {

         PORTB = 0x00; // Turn off LED2
        LcdSendInstruction(LCD_HOME_FOR_TEMP);
        LcdSendCharacter('Y');
         LcdSendInstruction(LCD_CURSOR_HOME);
     }
 

  }

So when the timer interrupt fires,the AVR makes the LCD cursor return to home in the tiner ISR and then it updates my timer value and displays it on the first row of my LCD. Before it gets out of the timer ISR it sets the cursor position for the ADC display on the LCD with the LcdSendInstruction(LCD_HOME_FOR_TEMP) instruction.

Then if there is any change on the ADC, it fires the ADC ISR and it should display the ADC value on the second row. Before it leaves the ADC ISR, it sets the cursor home position which is the first character on the first row for the timer display.

So in other words, I am trying to control both rows of the LCD independently (top row : Timer) and bottom row : ADC.

However, when I run this code, the LCD is displaying only the first row with the timer value but not the ADC. Is this doable? Can I independently control both rows of the LCD? Thanks again.

The command I am using is from my LCD datasheet and is attached.

Attachment(s): 

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

Make people interested in reading your code, and make it more readable to yourself, by keeping it structured. Remove un-necessary empty lines, be meticolous about keeping the indentation correct, remove unused code etc. Maybe like this:

#define LCD_HOME_FOR_TEMP     0x88

void rtc_op()
{
    LcdSendInstruction(LCD_CURSOR_HOME);
    char transmit_time[10];

    seconds++;

    if (seconds == 60)
    {
        seconds = 0;
        minutes++;
    }

    if (minutes == 60)
    {
        minutes=0;
        hours++;
    }

    if(hours == 24)
    {
        hours = 0;
        days++;
    }

    if(strlen(transmit_time)== 1)
    {
        LcdSendCharacter(' '); //pad the character, right justify the display for single digit
    }

    LcdSendInstruction(LCD_CURSOR_BLINK_OFF); //REMOVE BLINKING OF CURSOR
    LcdSendInstruction(LCD_CURSOR_HOME);

    sprintf(transmit_time,"%02d:%02d:%02d", hours, minutes,seconds);
    transmit_time[9] = '\0';
    transmit_time[8]= '\r';
    LCDString(transmit_time);
    LcdSendInstruction(LCD_HOME_FOR_TEMP);
}

ISR(ADC_vect)
{
    ADC_value = ADC;

    if(ADC_value > 510) //temperature is > 65 deg C
    {
        PORTB = 0x01; // Turn on LED2
        //define new home
        //return to home   
        LcdSendInstruction(LCD_HOME_FOR_TEMP);
        LcdSendCharacter('N');
        LcdSendInstruction(LCD_CURSOR_HOME);
    }
    else // LED normally off for room temperature
    {
        PORTB = 0x00; // Turn off LED2
        LcdSendInstruction(LCD_HOME_FOR_TEMP);
        LcdSendCharacter('Y');
        LcdSendInstruction(LCD_CURSOR_HOME);
    }
}

Anyhow, you now should try to determine if your problem is one of interaction between the two LCD updates or if the update of line 2 fails independently of the update of line 1. Letting both ISRs still run, but making first one and then the other return immediately without doing anything should might gve you some hints.

Also: This

    transmit_time[8]= '\r';

will spill over onto the second line, won't it?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Thanks,Johann. Sorry about the unstructured code posted.

I had tried exactly what you suggested. Without any cursor positioning commands, I am getting something like this on the LCD:

Y0:00:00

And the last two digits of my counter/clock do increment every second. The first "Y" is the ADC ISR return value. It have confirmed that it does change to "N" with a change in the NTC.

So this means that both ISR's work and the value is updated to the LCD.
The key thing (I think) is to get the ADC update on the next row. It does seem like the cursor positioning commands are not working.
Also the '\r' does not put the cursor on the next line. Maybe it is because of the HOME command at the beginning of the timer ISR?

Does the LCD_HOME_FOR_TEMP value of 0x88 look right? I have used it based on the datasheet but maybe I am addressing the wrong memory?

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

It seems that your LCD code is something that started out as my short LCD demo that I have posted here. (Eg, the names of functions are identical.)

As we've not seen the complete program this is a shot in the dark:

You are aware that doing a "cursor home" is a relatively time-consuming operation for the LCD. 1.5 milliseconds might seem like nothing, but if you do a "cursor home" and then send subsequent data or instructions to the LCD too fast it will simply ignore them. The proper trick to avoid this is to read out the Busy flag from the LCD, something that my code does not. The quick-and-dirty thing to do is to insert a

_delay_ms(2)

right after the "cursor home" instruction is sent.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Yes, Johann it is from your short LCD demo. I have just added a few things like sending strings, controlling cursor position, etc. I will try adding the delay statement after the cursor home command.Thanks.

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

I tried adding delays as you mentioned but there was no difference in the LCD output. Here is my entire code for your reference:


/*****************HEADERS ***********************/
#include 
#include 
#include 
#include 
#include 
#include 
#include 

volatile unsigned char seconds,minutes,hours;
volatile int ADC_value = 0;

/*******************BEGIN LCD code******************/

#define LCD_DATA_PORT PORTD
#define LCD_DATA_DDR  DDRD
#define LCD_CTRL_PORT PORTD
#define LCD_CTRL_DDR  DDRD
#define LCD_RS        PD0 //2
#define LCD_RW        PD1//3
#define LCD_E         PD2//4
#define LCD_FUNCTION_SET      0x38 // 0b00110000
#define LCD_FUNCTION_SET_4BIT 0x28 // 0b00101000
#define LCD_DISPLAY_OFF       0x08 // 0b00001000
#define LCD_DISPLAY_ON        0x0F // 0b00001111
#define LCD_DISPLAY_CLEAR     0x01 // 0b00000001
#define LCD_ENTRY_MODE_SET    0x06 // 0b00000110
#define LCD_CURSOR_HOME       0x02 // 0b00000010
#define LCD_CURSOR_BLINK_OFF  0x0E 
#define LCD_HOME_FOR_TEMP     0x88


void LcdSendNibble( uint8_t nibble )

{

   _delay_ms(20);

   // Output upper nibble on the data ports upper bits

   LCD_DATA_PORT = (nibble & 0xF0) | (LCD_DATA_PORT & 0x0F);

 

   // Toggle the E line

   LCD_CTRL_PORT |= (1<<LCD_E);   // Going up..

   LCD_CTRL_PORT &= ~(1<<LCD_E);  // ..and down.

}

void LcdSendByte(uint8_t theByte)

{

   // Send the high nibble

   LcdSendNibble(theByte);

 

   // Shift theByte to get lower nibble in upper part...

   theByte = theByte << 4;

   // ...and send it

   LcdSendNibble(theByte);

}


void LcdSendInstruction( uint8_t theInstruction )

{

   // RS low for instructions

   LCD_CTRL_PORT &= ~(1<<LCD_RS);

 

   // Send the instruction

   LcdSendByte(theInstruction);

}



void LcdSendCharacter(uint8_t theChar)

{

   // RS high for characters to display

   LCD_CTRL_PORT |= (1<<LCD_RS);

 

   // Send the command

   LcdSendByte(theChar);

}


void LcdInitialize(void)

{

   // initialize LCD control lines

   LCD_CTRL_PORT &= ~(1<<LCD_RS);    // RS low

   LCD_CTRL_PORT &= ~(1<<LCD_RW);    // R/W low

   LCD_CTRL_PORT &= ~(1<<LCD_E);    // E low

 

   // initialize LCD control lines to output

   LCD_CTRL_DDR |= (1<<LCD_RS);

   LCD_CTRL_DDR |= (1<<LCD_RW);

   LCD_CTRL_DDR |= (1<<LCD_E);

 

   // initialize LCD data port to input

   LCD_DATA_DDR |= 0xF0;      // Data on high four bits of port for now...

    _delay_ms(15);

   LcdSendNibble( LCD_FUNCTION_SET );

   _delay_ms(5);

   LcdSendNibble( LCD_FUNCTION_SET );

   _delay_us(100);

   LcdSendNibble( LCD_FUNCTION_SET );

 

   // Now, still in 8-bit mode, set the display to 4-bit mode

   LcdSendNibble( LCD_FUNCTION_SET_4BIT );

 

   // We are now in 4-bit mode.

   // Do the rest of the init sequence.

   LcdSendInstruction( LCD_FUNCTION_SET_4BIT );

   _delay_ms(500);

   LcdSendInstruction( LCD_DISPLAY_OFF );

   _delay_ms(500);

   LcdSendInstruction( LCD_DISPLAY_CLEAR );

   _delay_ms(500);

   LcdSendInstruction( LCD_ENTRY_MODE_SET );

   _delay_ms(500);

   LcdSendInstruction( LCD_DISPLAY_ON );

   _delay_ms(500);

}

void LCDString(char *str) //New function to send string to LCD

 {

   while(*str)

     LcdSendCharacter(*str++);
 }
/****************END LCD CODE**************************/


/****************TIMER INIT FUNCTION*****************/

void timer_init()

   {

       TIMSK1 |= (1 << OCIE1A); //enable channel 1A interrupt

      sei(); //enable global interrupts


      TCCR1B |= (1 << CS12) | (0 << CS10) | ( 0 << CS11); //start timer at Fcpu/256


       TCCR1B |= (1 << WGM12);//set up for CTC mode
 

       OCR1A = 3800; //Value that the micro will compare with current count; THIS HAS BEEN ADJUSTED FOR M48 WITH external 8MHz crystal with NO CAP FOR A BREADBOARD 

   }


/********************ADC INIT FUNCTION***************/
void ADC_init()

{
   DDRB = 0xFF;
   PORTB = 0x00;
   ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) | (1 << ADATE); // Set ADC prescaler to 128 - 125KHz sample rate @ 16MHz
   ADMUX |= (1 << REFS0); // Set ADC reference to AVCC
   //using all 10 bit of ADC; so do not left justify the ADC value
   DIDR0 = (1 << ADC0D); //turn off the digital driver
   // No MUX values needed to be changed to use ADC0
   ADCSRA |= (1 << ADEN);  // Enable ADC
   ADCSRA |= (1 << ADIE);  // Enable ADC Interrupt
   sei();   // Enable Global Interrupts
   ADCSRA |= (1 << ADSC);  // Start A2D Conversions; make sure the ADC is turned on after all the init functions are completed
 
}


/**************RTC UPDATE FUNCTION*******************/
void rtc_op() 
{ 
    LcdSendInstruction(LCD_CURSOR_HOME); 
    char transmit_time[10]; 

    seconds++; 

    if (seconds == 60) 
    { 
        seconds = 0; 
        minutes++; 
    } 

    if (minutes == 60) 
    { 
        minutes=0; 
        hours++; 
    } 

    if(hours == 24) 
    { 
        hours = 0; 
        days++; 
    } 

    if(strlen(transmit_time)== 1) 
    { 
        LcdSendCharacter(' '); //pad the character, right justify the display for single digit 
    } 

    LcdSendInstruction(LCD_CURSOR_BLINK_OFF); //REMOVE BLINKING OF CURSOR 
    LcdSendInstruction(LCD_CURSOR_HOME); 

    sprintf(transmit_time,"%02d:%02d:%02d", hours, minutes,seconds); 
    transmit_time[9] = '\0'; 
    transmit_time[8]= '\r'; 
    LCDString(transmit_time); 
    LcdSendInstruction(LCD_HOME_FOR_TEMP); 
} 


/******************TIMER 1 ISR *************************/

ISR(TIMER1_COMPA_vect)
   {  
      rtc_op();
   }


/***************ADC ISR*****************************/
ISR(ADC_vect) 
{ 
    ADC_value = ADC; 

    if(ADC_value > 510) //temperature is > 65 deg C 
    { 
        PORTB = 0x01; // Turn on LED2 
        //define new home 
        //return to home    
        LcdSendInstruction(LCD_HOME_FOR_TEMP); 
        LcdSendCharacter('N'); 
        LcdSendInstruction(LCD_CURSOR_HOME); 

/**************TRIED DELAY HERE AND IT DID NOT WORK***********/
        //_delay_ms(2); Tried delay here;it did not work

    } 
    else // LED normally off for room temperature 
    { 
        PORTB = 0x00; // Turn off LED2 
        LcdSendInstruction(LCD_HOME_FOR_TEMP); 
        LcdSendCharacter('Y'); 
        LcdSendInstruction(LCD_CURSOR_HOME); 
/**************TRIED DELAY HERE AND IT DID NOT WORK***********/
        //_delay_ms(2); Tried delay here;it did not work


    } 
} 

/***************MAIN*****************************/
int main(void)

{
   DDRB = 0xFF;
   LcdInitialize();
   timer_init();  
   ADC_init();
       
        for(;;)

             { 
               }

     return 0;

}

Am I adding delay at the right place in the code? Or do I need to explicitly start checking the busy flag?

The LCD does not update between two seconds. So does that mean this is the only time I can use to display my ADC value?

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

Does that LCD_HOME_FOR_TEMP look ok? I am using 0x88 as the command to send to the LCD for positioning the cursor on the first position in the second row. That is location 08 as shown in the attached figure above. I tried to display the clock ticks on row two with this command and the display blanked out.

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

Anybody?