Question about running a VFD/LCD (parallel) - Page 1
Forum section: electronics / general

author: SuperJeep
author_rank: Contributor
timestamp: July 31, 2013, 02:27:16 pm
content: Hi,I have a 256x128 noritake VFD display that I am trying to interface with a SAM9260 Arm board.I am using the parallel interface and can initialize the display and send data to it but my problem is that it does not stay on the display.I have thoroughly checked the data sheet to see if you can send a display command and have it keep it on the display or something with no luck.Example: if I write "hello", as soon as I trigger the "WR" pin to send the command(active low), the words flash and disappear.I wrote a draw routine which re-sends these write commands every few milliseconds but the "flicker" on the display looks too buggy, and drawing more often seems to make the display act twitchy(random characters appear at times). I am checking the RDY status so as to not send when the display is busy, so I can't explain why it is behaving this way.If anyone has any information regarding display routines for LCDs or VFD's in parallel mode I would be very grateful!Thank you

author: jeroen74
author_rank: Frequent Contributor
timestamp: July 31, 2013, 04:39:16 pm
content: Part#?

author: SuperJeep
author_rank: Contributor
timestamp: July 31, 2013, 04:48:02 pm
content: oh sorry, It is the GU-3000 series:http://www.noritake-elec.com/3000_series.htm

author: jeroen74
author_rank: Frequent Contributor
timestamp: July 31, 2013, 04:54:28 pm
content: Are you sure you have met the timing requirements?

author: SuperJeep
author_rank: Contributor
timestamp: July 31, 2013, 05:00:58 pm
content: I am quite sure I meet them in that it display's the messages I send out, But the instant my code begins toggling WR, the message simply appears and disappears immediately after. I haven't taken exact measurements of how fast my program is doing the send, but I was pretty sure that it was longer than the min requirements

author: jeroen74
author_rank: Frequent Contributor
timestamp: July 31, 2013, 05:07:42 pm
content: (Interestingly) the interface requires 50ns of hold time so be sure not to change the data when set /WR high again. How did you connect it? Relevant code?

author: SuperJeep
author_rank: Contributor
timestamp: July 31, 2013, 05:19:04 pm
content: So from the functions below, I pretty much just call Send_String("test") from mai. sorry if it is a bit messyCode:void Send_String(unsigned char *ch){unsigned char i=0x00 ;while(i != *ch){send_byte(*ch++); //send each character}void send_byte(unsigned char c) //send byte to vfd{int a;PIO_Clear(&pinsLCD_DMASK);//reset port pinsa=(unsigned int ) c<<22;pinsLCD_DMASK.mask = a;PIO_Set(&pinsLCD_DMASK);//set the port pinsfor (i=0;i<100;i++);toggle_WR();//send bytefor (i=0;i<100;i++);wait_for_busy();//wait for rdy pin}void toggle_WR(void){PIO_Clear(&pinWR); // pulls pin lowfor(int m = 0; m<100;m++); //quick waitPIO_Set( &pinWR); // pulls pin high}

author: jeroen74
author_rank: Frequent Contributor
timestamp: July 31, 2013, 05:29:04 pm
content: Those short waits might be optimized away by the compiler. You should declare the variables as volatile;e.g:Code:for (volatile int i=0;i<100;i++);

author: SuperJeep
author_rank: Contributor
timestamp: July 31, 2013, 05:47:16 pm
content: Oh thanks for the advice on the declarations. It still seems to be doing the same thing, I've been changing the wait times out of trial and error in hopes that this is just a timing issue

author: Unknown
author_rank: Unknown
timestamp: July 31, 2013, 06:02:17 pm
content: Or use proper delay functions that your C library (or a library like ASF) will likely provide. Volatile will force the compiler to store i in RAM after each increment. I'm not intimately familiar with this architecture, but I would expect this to slow down the loop. Library functions use hand optimized assembly to give you more accurate timing, regardless of the clock frequency. How many µs does this 100 iteration for loop take? How many iterations for 100 ns delay?

author: SuperJeep
author_rank: Contributor
timestamp: July 31, 2013, 06:12:35 pm
content: hmm I just did some rough math and the sample project im using has the master clock at 99.33Mhz, so ~10ns per cycle. Not sure if I can assume one iteration per loop iteration but if i do, thats 1us for the loop. Theres a good chance I might be wrong on that one though.EDIT: I'm probably way off, because bringing down that delay results in nothing appearing on the screen at allUPDATE: So I just probed the WR line with a scope and saw that it stays low for 600ms without any wait loops. So I guess I just need to scope all the pins and see whats happening. A logic analyzer would be great right about now:PThanks for all the help people! Im open to any new suggestions aswell (in case it seems as if I am closing this thread, feedback is always welcome)

author: MacAttak
author_rank: Unknown
timestamp: August 01, 2013, 12:23:18 am
content: You should definitely heed the advice to not rely on an empty for() loop to implement delays. That's a programming habit you would be well-advised to just go ahead and break right now.Your platform will have some basic delay function that you can use - probably named "delay()" - or you can implement your own crude delay by checking the total elapsed cpu clock ticks counter in a loop. This isn't the same thing as making your own for() loop and inspecting the control var for it.

author: SuperJeep
author_rank: Contributor
timestamp: August 14, 2013, 01:51:54 pm
content: Alright I have noticed weird behavior while troubleshooting the issue. When I run the program with the vfd connected, nothing displays, but when I physically pull out and slide in the parallel cable (also has v+ and gnd) the display shows my test text and then it fades away.Not sure if this is trying to tell me something.- I made sure there is a common ground between both the vfd and the development board.UPDATE: It turns out the display was defective. A controller or something on it may have burnt out because I got my hands on a new display and the code works fine!Thanks for all the help everyone

author: alank2
author_rank: Super Contributor
timestamp: January 29, 2014, 12:00:41 am
content: Hi Everyone,Help me understand the /WR in the above timing diagram. According to wikipedia this would be an active low signal:QuoteWhen are the D0-D7 lines sampled? When /WR returns high? What is active-low about that?Thanks,Alan

author: alank2
author_rank: Super Contributor
timestamp: January 29, 2014, 09:19:00 pm
content: Did some testing. The lines are sampled when /WR goes high. Again, I'm not sure why that would be active low or have the / on it.I have a 256x64 graphic display and wanted to see how fast I could write an entire screen (16384 bits, 2048 bytes) and then display it. I did this in such a way that you can't see it happening until it is done (write to the memory that isn't visible and then snap it into what is visible). It was 2072 bytes total with formatting characters. Waiting on that PBUSY line really consumes some time. It takes 105ms to write this particular 2072 byte stream, so it averages 19733 characters per second. This is only roughly 70% faster than 115200 baud using the serial interface. I expected much more performance out of the parallel, being that it requires 10 i/o pins, but the limit is how fast the module can process the data.

author: Bassman59
author_rank: Super Contributor
timestamp: January 29, 2014, 11:46:25 pm
content: Quote from: alank2 on January 29, 2014, 09:19:00 pmBecause the microprocessors to which they were originally designed to interface with used an active-low write enable on an asynchronous bus. The timing diagram posted earlier shows a minimum /WR low pulse width of 100 ns, a setup time of 50 ns before the rising edge of /WR, and a hold time of 50 ns after that edge.That it gives setup and hold times with respect to the rising edge of /WR is your indicator that the data are latched on that edge.-a

author: macboy
author_rank: Super Contributor
timestamp: February 04, 2014, 05:19:41 pm
content: Quote from: alank2 on January 29, 2014, 09:19:00 pmI have a similar 3900 series display. I haven't played with it yet but I have read the datasheet. This display has a significant receive FIFO buffer,use it. You can configure flags for full/empty at specific FIFO depths. Yes, the busy flag may be set but if there is still room in the buffer, keep sending data. This ensures that the display never sits idle waiting for the next thing to do, which is exactly what will happen if you stop sending data whenever BUSY is set.I use a similar technique on serial interfaced 7000 series VFD's. These have a small 12 byte buffer and no way to know the depth, just the BUSY flag. I wrote my code to burst up to 12 bytes at a time (regardless of the BUSY flag becoming set after the first byte or so) then wait for the flag to clear, then burst up to 12 bytes again. This results in a significant improvement in throughput without any lost data.