Jump to content
  • 0

Not understanding LCD Display


PoorCollegeStudent

Question

Hello Digilent community,

   I am currently taking my first digital electronics class and my final project is a calculator written in VHDL using a Basys3 board, 16-key keypad, and a 16x2 LCD display with parallel interface, all provided by Digilent. I took a look at the provided example code from the resource library and I just had some questions about how it works. Now, the example code declares a constant before any of the processes, and this constant is an array of std_logic_vectors so it holds a preloaded message "Hello From Digilent" with the necessary function sets and all that preceding the message. In my case, I have to have a way to display the inputs from the keypad on the display and also display the output on the 2nd line of the display. I have the main logic part of the calculator settled, I just want to know how I can direct these signals from the keypad and the output of the computational module (as in the sum, difference, product, etc.) to the LCD display. I have never played with a display before now and never used VHDL or any type of board like the Basys3 before this class, so I guess I'm still quite novice and don't understand a good part of what the example code is telling me. I do get that the state machine is just cycling through the values in the constant and waits for certain delays to pass through before transitioning between certain states.

Since the values on the display have to be updated live as the user inputs numbers from the keypad and also when there is a value computed, how can I shift from having a constant with a preloaded message to something that can update itself as needed? My idea was keep the idea of the array of std_logic_vectors but only have one value (rather than the 23 or 24 that are preloaded in the current example code) that will update with every key press. I'll have two of these, one for the inputs (to show the numbers and operations on the first line) and one for the output (to show on the second line). I'm thinking maybe I declare a variable within a process that will update and be sensitive to the key presses? 

Also, I tried looking around the reference manual and such but I could not find the function code for how to display information on the 2nd line; so far, stuff only displays on the first line. 

Sorry this is such a bulky post. I have had a lot of questions and my professor hasn't been around much. Also, part of this project is learning to interface with new components, so in my case the keypad and lcd display, and I'm not having much luck without any guidance unfortunately. Thank you for taking the time to read this!

P.S. Attached the example vhd file from Digilent here for easy access in case anyone wants to look!

PmodCLP.vhd

Link to comment
Share on other sites

Recommended Posts

I've never used the this display, but on other display the second line start on address C0, (http://www.avrfreaks.net/forum/problem-second-line-2x16-lcd

So try this:

Change

                14 => "10"&X"20",           -- blank

To:

                14 => "00"&X"C0",          -- Move to second line

This might also be of use: https://mil.ufl.edu/3744/docs/lcdmanual/commands.html

 

Link to comment
Share on other sites

Hello again,

So a little update if it even matters or if anyone still cares at this point: I still don't know what the command is for accessing the next line, haven't been able to find it still. My confidence in my googling stills has been diminishing exponentially.

I managed to make it to the numbers show one by one only when I press a key, and the characters do not keep repeating on the display anymore. However, there is this long delay of like 4 or 5 seconds between each character, and I have tried adjusting the timing values in the code to even make them really short, but the delay between characters seems to remain at about 4 or 5 seconds. It's actually different each time. Any idea why this might be?

There is a warning about the debug hub not detected at User Scan Chain 1 or 3, and Vivado says to make sure the clock connected to the debug hub (dbg_hub) core is a free running clock and is active -- me being a newbie, I have no idea what this means. I tried looking it up but the forum posts I found were for some very specific projects that don't relate to mine.

Link to comment
Share on other sites

18 hours ago, hamster said:

So if you add a top-level port of "bcd : in std_logic_vector(7 downto 0)" (enough for two digits as a test) then within the module you could do the following:

a. replace "constant" with "signal" on LCD_CMDS

b. Add a couple of assignments to overwrite the desired values in the array.

Add a couple of concurrent assignments:

   LCD_CMDS(15) <= x"3" & bcd_value(7 downto 4);

   LCD_CMDS(14) <= x"3" & bcd_value(3 downto 0);

That will overwrite the "Di" in "Digilent" with two digits.

Once you get this working, you can follow your nose to add the extra digits (e.g. make 'bcd' wider, overwrite extra digits, change the commands being sent to the display so you can access the second line, remove the shift...)

Hello,

I have done part a and was trying to do part B as well. However, I was unable to find the command for accessing the second line. It wasn't in the reference manual and I couldn't find it online? Am I just looking in the wrong places? I feel like ASCII tables would have a value that equates to moving down a line but so far I haven't found one.

Thank you for your help so far by the way. I appreciate it a lot. 

Link to comment
Share on other sites

So if you add a top-level port of "bcd : in std_logic_vector(7 downto 0)" (enough for two digits as a test) then within the module you could do the following:

a. replace "constant" with "signal" on LCD_CMDS

b. Add a couple of assignments to overwrite the desired values in the array.

Add a couple of concurrent assignments:

   LCD_CMDS(15) <= x"3" & bcd_value(7 downto 4);

   LCD_CMDS(14) <= x"3" & bcd_value(3 downto 0);

That will overwrite the "Di" in "Digilent" with two digits.

Once you get this working, you can follow your nose to add the extra digits (e.g. make 'bcd' wider, overwrite extra digits, change the commands being sent to the display so you can access the second line, remove the shift...)

Link to comment
Share on other sites

8 hours ago, hamster said:

HI!

Ignoring the JA and JB ports that are required to talk to the display hardware, what would your module's ideal interface look like?

Would it be a register based interface, where you write data to be displayed, (e.g. digit 0 in register 0):

  addr[4:0],
  din[7:0],
  writeEnable

 or would it be just a minimal interface for each digit you want to show:

  digit0[3:0], decimal0, blank0, 
  digit1[3:0], decimal1, blank1,
  ...
  digitX[3:0], decimalX, blankX

Or would it expose the ASCII nature of the display, allowing you to show almost anything?

  character0[7:0],
  character1[7:0],
  ...
  characterX[7:0]

Or would it be a stream interface:

  din[7:0],
  data_enable,
  first_byte_of_packet

Have you thought how you would manage the cursor (if it is needed at all)?

Once you have that sketched out, the you are in the position of how to implement the innards of the module...

Hello!

I'm not too sure how you are describing the methods of interfacing, but I get the gist of it I think. I believe my purposes fit the 3rd one where I want to use the ASCII nature of the display. Basically, 4-bit BCD values will come in 8 at a time (for 8 digits to display) and by adding 30 to each one, I can send the proper ASCII value to the display. There won't be a cursor, sorry forgot to mention that. 

I just want to see if maybe I could create a variable that will update for every incoming set of 8 BCD values, which in turn would create 8 new ASCII values to send to the display. I would like the input values to go to the first line of the display, and the computed value to go to the second line of the display, but I'm not sure how to send values to the 2nd line.

Link to comment
Share on other sites

HI!

Ignoring the JA and JB ports that are required to talk to the display hardware, what would your module's ideal interface look like?

Would it be a register based interface, where you write data to be displayed, (e.g. digit 0 in register 0):

  addr[4:0],
  din[7:0],
  writeEnable

 or would it be just a minimal interface for each digit you want to show:

  digit0[3:0], decimal0, blank0, 
  digit1[3:0], decimal1, blank1,
  ...
  digitX[3:0], decimalX, blankX

Or would it expose the ASCII nature of the display, allowing you to show almost anything?

  character0[7:0],
  character1[7:0],
  ...
  characterX[7:0]

Or would it be a stream interface:

  din[7:0],
  data_enable,
  first_byte_of_packet

Have you thought how you would manage the cursor (if it is needed at all)?

Once you have that sketched out, the you are in the position of how to implement the innards of the module...

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...