Functions would not execute!

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

Hi y'all out there!

I am building input selector switch based on Atmega8A and relays.Relay part works fine and is being used every day.Now i am trying to add lcd to it.

Why i am here?I am stuck.Watching videos, reading tutorials but i can't find out why my functions are not executed!

Code works fine without functions, but when i start using functions i get some gibberish on lcd.Been trying many ways to write the code,

change delays, F_cpu nothing so far.

and,yeah,i can get only 8 signs on lcd.I've red on this, but that's another story.It's just a matter of telling the lcd how to work which i am yet to discover.

I'd really appreciate if you'd even point me in right direction.

I've been here before, i know you know a lot and this whole thing this forum helps willing to learn people become smarter.

Amega8A U (as stated on mcu it self) currently running at 8Mhz defined in project options

https://uk.farnell.com/microchip...

IDE Codeblocks running on Q4OS

LCD : 16x1 powerd by DC 5V

https://www.buydisplay.com/black...

 

#include <avr/io.h>
#include <util/delay.h>

unsigned int data;
void lcd_command(unsigned int);

int main()
{
  DDRD = 0xff;                  //PORTD output
  DDRC |= (1 << PC0) | (1 << PC1) | (1 << PC5);  //PORTC PIN0; PIN1 output

  PORTC |= (1 << PC5); //test LED
  PORTC |= (1<<PC1); //E=1

  data = 0b00110000; // Function set

  lcd_command(data);

  data = 0b00001100; // Display on, cursor off

  lcd_command(data);

  return 0;

}

void lcd_command(unsigned int data)
{
  PORTC &= ~(1 << PC0); //RS=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1 << PC1); //E=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);

  return;
}

 

Have a nice weekend ya'll out there!

Attachment(s): 

This topic has a solution.

Andy

Last Edited: Sat. Aug 7, 2021 - 06:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Try this commands, add 10ms after each:

    8  Display off
    1  Display clear

 

Edit: Your LCD init code looks poor, can you find a better template.

Also in Main, the while loop is missing.

Last Edited: Sat. Jul 31, 2021 - 08:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What do you mean by 8 display off.What is this?I do not understand.

I was following lcd datasheet a SPLC780 to be precise provided by the seller.And these are only first steps to turn it on

as you see.

As i said, it works without functions.

And why do i need while loop?I mean in this particular case.

Andy

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

Means:

 

data = 0b00001000; // Display off
lcd_command(data);
_delay_ms(5);
data = 0b00000001; // Display clear
lcd_command(data);
_delay_ms(10);

Both commands should be executed before of // Display on, cursor off

 

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

andyoclover wrote:
Code works fine without functions, but when i start using functions i get some gibberish on lcd.Been trying many ways to write the code,

What on earth does that mean ?

Show us the code that "works fine without functions". The missing while loop & Display_Off; Display_Clear commands are a distraction.

 

BTW: Your photo shows the type of pattern expected on an uninitialised LCD right after power-up.

 

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

#include <avr/io.h>
#include <util/delay.h>

 unsigned int data;

int main(void)
{

 

  DDRD = 0xff;                  //PORTD output
  DDRC |= (1 << PC0) | (1 << PC1) | (1 << PC5);  //PORTC PIN0; PIN1 output

  PORTC |= (1 << PC5); //test LED
  PORTC |= (1<<PC1); //E=1

    data = 0b00110000; // Function set

  PORTC &= ~(1 << PC0); //RS=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1 << PC1); //E=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);

    data = 0b00001100; // Display on, cursor off

  PORTC &= ~(1 << PC0); //RS=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1 << PC1); //E=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);

  data = 0b00000001; //Clear display

  PORTC &= ~(1 << PC0); //RS=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1 << PC1); //E=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);

  data = 0b01000101; //E

  PORTC |= (1<<PC0); //RS=1
  _delay_ms(1);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(1);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(1);

  data = 0b01010101; //U

  PORTC |= (1<<PC0); //RS=1
  _delay_ms(3);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(3);
  PORTD = data;
  _delay_ms(3);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(3);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(3);

  data = 0b01010010; //R

  PORTC |= (1<<PC0); //RS=1
  _delay_ms(3);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(3);
  PORTD = data;
  _delay_ms(3);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(3);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(3);

  data = 0b01001001; //I

  PORTC |= (1<<PC0); //RS=1
  _delay_ms(3);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(3);
  PORTD = data;
  _delay_ms(3);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(3);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(3);

  data = 0b01001011; //K

  PORTC |= (1<<PC0); //RS=1
  _delay_ms(3);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(3);
  PORTD = data;
  _delay_ms(3);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(3);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(3);

  data = 0b01000001;

  PORTC |= (1<<PC0); //RS=1
  _delay_ms(3);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(3);
  PORTD = data;
  _delay_ms(3);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(3);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(3);

  data = 0b00100000;

  PORTC |= (1<<PC0); //RS=1
  _delay_ms(3);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(3);
  PORTD = data;
  _delay_ms(3);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(3);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(3);

  data = 0b01000010;

  PORTC |= (1<<PC0); //RS=1
  _delay_ms(3);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(3);
  PORTD = data;
  _delay_ms(3);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(3);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(3);

  data = 0b01000011;

  PORTC |= (1<<PC0); //RS=1
  _delay_ms(3);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(3);
  PORTD = data;
  _delay_ms(3);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(3);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(3);

  data = 0b00110010;

  PORTC |= (1<<PC0); //RS=1
  _delay_ms(3);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(3);
  PORTD = data;
  _delay_ms(3);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(3);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(3);

}

 

This way every single time i cen get on lcd every character, clear lcd, cursor appear etc. as in datasheet tabs.

Attachment(s): 

Andy

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

Following your suggestions i've tried this:

#include <avr/io.h>
#include <util/delay.h>

unsigned int data;
void lcd_command(unsigned int);
void lcd_data(unsigned int);

int main()
{

  DDRD = 0xff;                  //PORTD output
  DDRC |= (1 << PC0) | (1 << PC1) | (1 << PC5);  //PORTC PIN0; PIN1 output

  PORTC |= (1 << PC5); //test LED
  PORTC |= (1<<PC1); //E=1

  data = 0b00001000; // Display off
  lcd_command(data);
  _delay_ms(5);

  data = 0b00000001; // Display clear
  lcd_command(data);
  _delay_ms(10);

  data = 0b00110000; // Function set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00001100; // Display on, cursor off
  lcd_command(data);
  _delay_ms(10);

  data = 0b01010111; //Character "E"
  lcd_data(data);
  _delay_ms(10);

  return 0;

}

void lcd_command(unsigned int data)
{
  PORTC &= ~(1 << PC0); //RS=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1 << PC1); //E=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);

  return;
}

void lcd_data(unsigned int data)
{
  PORTC |= (1<<PC0); //RS=1
  _delay_ms(1);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(1);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(1);

  return;
}

If I use while(1) character "W" is blinking!

Looks like that is it.I could not understand why i have to turn the lcd off before it even has not beet turned on?

Well, i guess i still don't understand...

Anyway, if you got any clue how to get 16 characters on i'd really appreciate that.

I did some reading on that and what i've got is that some 16x1 lcd's need  to be approached like 8x2.

Could not figure it out from the SPLC780 datasheet.

 

Many thanks for your help so far!

Attachment(s): 

Andy

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

Glad to hear that it works /without distraction/.

Do try, please, Function set before of Display off/Display clear, and if that works, 

next you can try is 4-bits LCD. It is what 99% of LCD projects do have.

 

Edit: 0b00110000; // Function set  is responsible for char number, according to Datasheet

Last Edited: Sat. Jul 31, 2021 - 10:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah! I see what you mean by "without functions" code.

 

Well the "without functions" code includes a Clear_Display command whereas the "With Functions" code does not.

You seem to have corrected that in your #7. (and got it somewhat working)

 

BTW: From the look of the Power-up pattern I'm wondering if your LCD; despite looking like a 1-line display is actualy wired internally as a 2-line. (The FunctonSet would control that)

 

lcd_command(0x38); // function set for 2-line

 

Last Edited: Sat. Jul 31, 2021 - 10:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, function set tells lcd that it is going to receive data in 4 or 8 bit mode.Also it tells lcd how many lines and character dimensions.As i understand it has nothing to do with

character amount on screen...

I've red this article http://web.alfredstate.edu/facul... and trying to figure it all out.

It has something to do with address, locations where characters can be displayed.Also it deals with cursor placemen.

So somehow i have to send/write those say 9-16 characters to the other half of those locations, addresses if you will.

Lcd is like split in two parts by 8 characters.Each part has 8 locations so to say.Somehow i have to figure out how to

target those other 8 locations.After spending some time on internet it does seem to be common problem for them who are new to this like me.

Has it something to do with the page 13 in datasheet?I've looked at it but don't understand really...

Attachment(s): 

Andy

Last Edited: Sun. Aug 1, 2021 - 08:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

andyoclover wrote:

As i understand it has nothing to do with

character amount on screen...

 

Because the product photos show only one controller on the PCB for your LCD; I'm fairly sure I'm correct.

If you want a second opinion; check out the https://www.buydisplay.com/download/democode/ERM1601-2_DemoCode.txt  linked on the buydisplay page you linked.

 

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

Let's see your compile/link commands. I suspect you don't have a -mmcu on the link (so the wrong CRT will be linked with the wrong SP setting so CALLs can't RET) 

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

I guess you mean this: -mmcu=atmega8
-Wl,-Map=$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).map,--cref

Attachment(s): 

Andy

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

I took a look at this code.The only thing i can see it is pretty complicated.

I am no arguing but i can't see anything about Function set saying it is responsible for amount of charcaters on lcd

Attachment(s): 

Andy

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

andyoclover wrote:
I guess you mean this: -mmcu=atmega8
-Wl,-Map=$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).map,--cref
That *looks* right but I don't know how C::B uses the values you enter there. Presumably when it builds there is an "output" window of some kind that shows all the build commands and there output as the code is built? Can you show that?

 

(preferably a text cut/paste rather than a picture if possible?)

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

Nice one!Reinstalled PC and now i've got this.Such fun...

 

-------------- Build file: Release in lcd_input_selector (compiler: GNU GCC Compiler for AVR)---------------

avr-gcc -Wall -mmcu=atmega8 -DF_CPU=10000000UL -Os -I/usr/include -c main.c -o obj/Release/main.o
In file included from /usr/include/math.h:43:0,
                 from /usr/lib/avr/include/util/delay.h:46,
                 from main.c:5:
/usr/include/bits/floatn.h:75:1: error: unknown machine mode ‘__TC__’
 typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
 ^
/usr/include/bits/floatn.h:87:9: error: unknown type name ‘__float128’
 typedef __float128 _Float128;

Andy

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why are you adding your system include path to avr-gcc... 

:: Morten

 

(yes, I work for Microchip, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

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

Is that not what Clawson ask me for?

Andy

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

Morten already told you what is wrong in #17. Have you fixed that? Because you've given a path to host system headers it's going to try and use functionality of your x86/x64 PC  compiler such as the __float128 that the build is objecting to. AVRs unlike PCs don't do stuff like 128bit floats!

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

That floatn.h error is on debian as i have experienced.On other distributions like linux mint or q4os i have not seen it.But this is not important.

Who is Morten and what about that line #17?

#include <avr/io.h>
#include <util/delay.h>

unsigned int data;
void lcd_command(unsigned int);
void lcd_data(unsigned int);


int main()
{

  DDRD = 0xff;                  //PORTD output
  DDRC |= (1 << PC0) | (1 << PC1) | (1 << PC5);  //PORTC PIN0; PIN1 output

  PORTC |= (1 << PC5); //test LED
  PORTC |= (1<<PC1); //E=1
  _delay_ms(100);

  data = 0b00110000; // Function set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00110000; // Function set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00110000; // Function set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00111000; // Function set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00001000; // Display off
  lcd_command(data);
  _delay_ms(5);

  data = 0b00000001; // Display clear
  lcd_command(data);
  _delay_ms(10);

  data = 0b00000110; // Entry mode set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00001100; // Display on, cursor off
  lcd_command(data);
  _delay_ms(10);

  data = 0b01010111; // Character "W"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01000101; // Character "E"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01001100; // Character "L"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01000011; // Character "C"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01001111; // Character "O"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01001101; // Character "M"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01000101; // Character "E"
  lcd_data(data);
  _delay_ms(10);


  return 0;

}

void lcd_command(unsigned int data)
{
  PORTC &= ~(1 << PC0); //RS=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1 << PC1); //E=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);

  return;
}

void lcd_data(unsigned int data)
{
  PORTC |= (1<<PC0); //RS=1
  _delay_ms(1);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(1);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(1);

  return;
}

After i red an article about LCD initialization the code looks like that.All works fine except i still cant get more than 8 characters on.

and build log looks like that:


-------------- Build: Release in lcd_test_2 (compiler: GNU GCC Compiler for AVR)---------------

avr-gcc -mmcu=atmega8 -Wall -DF_CPU=10000000UL -Os  -c main.c -o obj/Release/main.o
avr-gcc  -o bin/Release/lcd_test_2.elf obj/Release/fuse.o obj/Release/main.o  -mmcu=atmega8 -Wl,-Map=bin/Release/lcd_test_2.map,--cref  
Output file is bin/Release/lcd_test_2.elf with size 6.34 KB
Running project post-build steps
avr-objdump -h -S bin/Release/lcd_test_2.elf > bin/Release/lcd_test_2.lss
avr-objcopy -R .eeprom -R .fuse -R .lock -R .signature -O ihex bin/Release/lcd_test_2.elf bin/Release/lcd_test_2.hex
avr-objcopy --no-change-warnings -j .eeprom --change-section-lma .eeprom=0 -O ihex bin/Release/lcd_test_2.elf bin/Release/lcd_test_2.eep
avr-objcopy --no-change-warnings -j .lock --change-section-lma .lock=0 -O ihex bin/Release/lcd_test_2.elf bin/Release/lcd_test_2.lock
avr-objcopy --no-change-warnings -j .signature --change-section-lma .signature=0 -O ihex bin/Release/lcd_test_2.elf bin/Release/lcd_test_2.sig
avr-objcopy --no-change-warnings -j .fuse --change-section-lma .fuse=0 -O ihex bin/Release/lcd_test_2.elf bin/Release/lcd_test_2.fuse
srec_cat bin/Release/lcd_test_2.fuse -Intel -crop 0x00 0x01 -offset  0x00 -O bin/Release/lcd_test_2.lfs -Intel
srec_cat bin/Release/lcd_test_2.fuse -Intel -crop 0x01 0x02 -offset -0x01 -O bin/Release/lcd_test_2.hfs -Intel
/bin/sh: 1: srec_cat: not found
Process terminated with status 127 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second

Have to do more reading, i guess...

Andy

Last Edited: Sat. Aug 7, 2021 - 05:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

andyoclover wrote:
Have to do more reading, i guess...

srec_cat: not found

And more installing.

 

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

andyoclover wrote:
Who is Morten and what about that line #17?
See post #17 above.

David

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
-------------- Clean: Release in lcd_test_2 (compiler: GNU GCC Compiler for AVR)---------------

Cleaned "lcd_test_2 - Release"

-------------- Build: Release in lcd_test_2 (compiler: GNU GCC Compiler for AVR)---------------

avr-gcc -mmcu=atmega8 -Wall -DF_CPU=10000000UL -Os  -c fuse.c -o obj/Release/fuse.o
avr-gcc -mmcu=atmega8 -Wall -DF_CPU=10000000UL -Os  -c main.c -o obj/Release/main.o
avr-gcc  -o bin/Release/lcd_test_2.elf obj/Release/fuse.o obj/Release/main.o  -mmcu=atmega8 -Wl,-Map=bin/Release/lcd_test_2.map,--cref  
Output file is bin/Release/lcd_test_2.elf with size 6.34 KB
Running project post-build steps
avr-objdump -h -S bin/Release/lcd_test_2.elf > bin/Release/lcd_test_2.lss
avr-objcopy -R .eeprom -R .fuse -R .lock -R .signature -O ihex bin/Release/lcd_test_2.elf bin/Release/lcd_test_2.hex
avr-objcopy --no-change-warnings -j .eeprom --change-section-lma .eeprom=0 -O ihex bin/Release/lcd_test_2.elf bin/Release/lcd_test_2.eep
avr-objcopy --no-change-warnings -j .lock --change-section-lma .lock=0 -O ihex bin/Release/lcd_test_2.elf bin/Release/lcd_test_2.lock
avr-objcopy --no-change-warnings -j .signature --change-section-lma .signature=0 -O ihex bin/Release/lcd_test_2.elf bin/Release/lcd_test_2.sig
avr-objcopy --no-change-warnings -j .fuse --change-section-lma .fuse=0 -O ihex bin/Release/lcd_test_2.elf bin/Release/lcd_test_2.fuse
srec_cat bin/Release/lcd_test_2.fuse -Intel -crop 0x00 0x01 -offset  0x00 -O bin/Release/lcd_test_2.lfs -Intel
srec_cat bin/Release/lcd_test_2.fuse -Intel -crop 0x01 0x02 -offset -0x01 -O bin/Release/lcd_test_2.hfs -Intel
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))

That's that!Lets see what happens next...

Andy

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

Solved!

One single line of code in front of my eyes all the time but i wasn't paying attention to it.

Here is very good reading material : http://web.alfredstate.edu/facul...

The actual line is data = 0b11000000; // Set DD RAM address.This moves cursor to the beginning of 2nd line.Yes, no below but at the end of the first 8 characters.

#include <avr/io.h>
#include <util/delay.h>

unsigned int data;
void lcd_command(unsigned int);
void lcd_data(unsigned int);


int main()
{

  DDRD = 0xff;                  //PORTD output
  DDRC |= (1 << PC0) | (1 << PC1) | (1 << PC5);  //PORTC PIN0; PIN1 output

  PORTC |= (1 << PC5); //test LED
  PORTC |= (1<<PC1); //E=1
  _delay_ms(100);

  data = 0b00110000; // Function set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00110000; // Function set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00110000; // Function set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00111000; // Function set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00001000; // Display off
  lcd_command(data);
  _delay_ms(5);

  data = 0b00000001; // Display clear
  lcd_command(data);
  _delay_ms(10);

  data = 0b00000010; //Return home
  lcd_command(data);
  _delay_ms(10);

  data = 0b00000110; // Entry mode set
  lcd_command(data);
  _delay_ms(10);

  data = 0b00001110; // Display on, cursor on
  lcd_command(data);
  _delay_ms(10);

  data = 0b01010111; // Character "W"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01000101; // Character "E"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01001100; // Character "L"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01000011; // Character "C"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01001111; // Character "O"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01001101; // Character "M"
  lcd_data(data);
  _delay_ms(10);

  data = 0b01000101; // Character "E"
  lcd_data(data);
  _delay_ms(10);

  data = 0b00101101; // Character "-"
  lcd_data(data);
  _delay_ms(10);

  data = 0b11000000; // Set DD RAM address.Cursor is moved to the beginning of the 2n line.
  lcd_command(data);
  _delay_ms(10);

  data = 0b00110010; //Character "2"
  lcd_data(data);
  _delay_ms(10);

  data = 0b00110000; //Character "0"
  lcd_data(data);
  _delay_ms(10);

  data = 0b00110010; //Character "2"
  lcd_data(data);
  _delay_ms(10);

  data = 0b00110001; //Character "1"
  lcd_data(data);
  _delay_ms(10);



  return 0;

}

void lcd_command(unsigned int data)
{
  PORTC &= ~(1 << PC0); //RS=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1 << PC1); //E=0
  _delay_ms(1);
  PORTC |= (1 << PC1); //E=1
  _delay_ms(1);

  return;
}

void lcd_data(unsigned int data)
{
  PORTC |= (1<<PC0); //RS=1
  _delay_ms(1);
  PORTC |= (1<<PC1); // E=1
  _delay_ms(1);
  PORTD = data;
  _delay_ms(1);
  PORTC &= ~(1<<PC1); //E=0
  _delay_ms(1);
  PORTC |= (1<<PC1); //E=1
  _delay_ms(1);

  return;
}

Thanks y'all for help!

Keep educating people.You are doing a good job.

Andy

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

Just out of interest why do you write a line such as:

data = 0b01010111; // Character "W"

rather than the slightly more obvious:

data = 'W';

?? 0b01010111 is 0x57 which is the ASCII code for 'W'.

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

Or even better IMO:

  lcd_data('M');

 

It's good to see you've got over the conceptual understanding of the 2nd display line and you got it working.

 

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


Thanks everyone!!

 

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

I think that was supposed to be here: https://www.avrfreaks.net/commen... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...