PDA

View Full Version : Virtual 20x4 display in ram on a 12F683



retepsnikrep
- 6th February 2013, 05:34
Imagine I have a looping program which is very time dependent and am using the debug command to send one character at a time to a serial lcd display. One character every 30ms to be exact.

What i want to do is build a virtual display in ram and then as my program loops transfer one byte at a time from this internal display to the lcd.

When my program writes to the display it basically changes things in this stored virtual display area and a simple incrementing counter transfers bytes from this one at a time to the lcd using debug.

I'm assuming I need to define an array say 80 bytes (20 x 4) and then simply write data to it while a seperate routine transfers this data to the lcd.

Any ideas/issues or examples out there?

I appreciate it will take 2.4 seconds to update the entire area of a 20x4 display at one byte every 30ms. I'm not bothered about that.

HenrikOlsson
- 6th February 2013, 18:18
Hi,
Never done with a LCD but have done similar things when outputting data to a PC/Terminal, which is basically the same thing as you're doing since the LCD is serial enabled. In my case though I've used the hardware UART.

Anyway, yes, you can declare an array of 80 characters (or 4 arrays of 20 each might be easier) and to create a "buffer" of the display content in the PIC. Problem with that is that the 12F683 only has 128bytes of RAM, PBP needs a couple of those for its internal use. Do you have 80 bytes free?

Are you going to constantly update the LCD, one char each time thru your main loop? Or will you "trig" a refresh of the display only when some data which are on the display changes?
Are there any static text on the display which never changes, like labels, units etc? In that case there's no need to rewrite the full display every time. Set it up once at the beginning of the program then only update the "fields" that actually changes.

Here's some code that illustrates one concept of doing it, ie an example. Obviously I don't know if it'll fit your application. And again, I don't think you'll be able to fit an 80byte buffer in the 12F683.


Buffer VAR BYTE[80]
Index VAR BYTE
ValuesDirty VAR BIT

Sample VAR BYTE
Result VAR WORD

ValuesDirty = 0
Index = 0

Main:
If GPIO.0 = 1 THEN ' Just somethig to trig a new ADC reading.
ADCIN 0, Result
ArrayWrite Buffer, ["Sample number ", DEC Sample, ": ", DEC Result]
ValuesDirty = 1
Sample = Sample + 1
WHILE GPIO.0 : WEND ' Wait for button to be released.
ENDIF

If ValuesDirty THEN GOSUB UpdateDisplay
Pause 30
Goto Main:


UpdateDisplay:
DEBUG Buffer[Index]
Index = Index + 1
If Index = 80 THEN
Index = 0
ValuesDirty = 0
ENDIF
RETURN

/Henrik.

Mike, K8LH
- 6th February 2013, 23:03
I did something like this but it was for a 12F1822 with a 2x16 LCD display using the 4-bit interface and 250 microsecond update intervals.

Using a faster update interval and modifying the buffer directly does allow you to do some neat things. For example, exclusive-or'ing the colon character positions in the buffer with ':'^' ' every 500 milliseconds will produce the flashing colon effect seen in the video below.


http://www.youtube.com/watch?v=z0t3_CGqQqU

Here's the interrupt routine from the demo (C code);


/************************************************** ****************
* *
************************************************** ****************/

void interrupt() // 250 usec (500 cycle) interrupts
{ static char line = 0xC0; //
static char bndx = 0; //
pir1.TMR2IF = 0; // clear TMR2 interrupt flag

/* *
* update one LCD character from the display array buffer (34 *
* interrupts or 8.5 ms to completely refresh the display). *
* */
if(line & 0x80) // if "new line"
PutCMD(line ^= 0x40); // set DDRAM address (0x80 or 0xC0)
else // not "new line" so
PutDAT(lcd[bndx++]); // refresh display, bump index
bndx &= 31; // pseudo %32, 0..31 inclusive
if((bndx & 15) == 0) // if new line (0 or 16)
line ^= 0x80; // toggle b7 pseudo "new line" flag
}