|
|
View previous topic :: View next topic |
Author |
Message |
scottc
Joined: 16 Aug 2010 Posts: 95
|
20Chr x 2 Lcd Display Update Speed General Question |
Posted: Fri Sep 03, 2010 11:46 pm |
|
|
Hi All
I'm using a 20chr by 2 line display running on the upper nibble of port B
in 4bit mode.
Also on Port B is a button connected to Pin3.
The display works fine but I am curious to know if its speed is a bit slow.
I increment a variable by 1 as the button is pressed and display its
value on the display. My Part is a pic16f886 running on the internal clock
at 8Mhz.
Anyway if I press the button, it takes about 7 seconds to cycle from 1 to 100 on the display. This seems kind of slow to me. I was wondering if this is typical. The LCD display is a Standard module based on the HD44780 controller.
Here is a snip.
Code: |
#include <test2.h>
#include <LCD4bit.C>
#use delay(clock=8000000)
#byte port_a = 0x05
#byte port_b = 0x06
#byte port_c = 0x07
#BIT TOGGLE = port_b.0
#BIT BUTTON1 = port_b.2
#BIT BUTTON2 = port_b.3
#Define Backlight Pin_B1
int16 Value1;
int16 Value2;
//============= MAIN DISPLAY HANDLER ================
void Display_Stuff()
{
Lcd_cmd( LCD_LINE2 );
printf(Write_LCD, " %lu.%02lu0 :) ", Value1,Value2);
}
//============ Button Press =========================
void ButtonPress(void)
{
if( BUTTON2 == 0 )
{
++Value1;
if (Value1 > 100)
Value1 = 100;
}
}
//=========== MAIN FUNCTION =======================
void main(Void)
{
set_tris_b(0b00001101);
LCD_START();
Output_Low (Backlight);
Value1=1;
Value2=00;
while (true)
{
ButtonPress();
Display_Stuff();
}
}
|
Thanks Scott |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Sat Sep 04, 2010 4:03 am |
|
|
Sounds very slow...
However, you may actually not be really seeing the real update, but a 'beat' effect with the data being updated many times, and only 'seen' as the screen is re-scanned.
Value2, is presumably zero.
Value1 goes up to 100, and you output 2 digits for 0 to 99, and three digits on the occasion it is 100.
You send a 'position' command, about 6 spaces, then value1, decimal point, value2, then it looks like another six characters.
Now, you don't tell us who's 4bit LCD driver you are using (why not use flex_lcd), but in general, any of the general purpose drivers, will take perhaps 50+ instructions to send a byte (25uSec). Then the LCD itself, is slow, taking about 46uSec per byte to be ready for the next character. So you are probably looking at about 75uSec/character (say 100 to be safe). The int16 arithmetic done to generate the digits (typically a couple of divisions by ten for what you show), are going to add another 320uSec, for the numeric digits. So the 'time', becomes something like:
90uSec (goto)
100*15uSec (write display digits)
320uSec (arithmetic)
repeated 100 times.
A total, under 0.2 seconds.
So, three things:
First, move the delay statement, above the LCD include. In CCS, the delay statement, _must_ be above anything using delays. The LCD code, probably does. It is possible, that the LCD code is giving wildly wrong timings, because of this....
Second, look at the display. If the digits are counting smoothly, without flicker, then it 'rules out' the 'beat' effect, instead implying that you are probably running a lot slower than you think
Then test your processor speed. Do a simple 'toggle a pin program. Does this run at the right speed?. If not, then you may have a compiler fault with the clock setup. Some versions of the CCS compiler do not give the right settings on some chips, and I think the f886, may be one of these.
Best Wishes |
|
|
scottc
Joined: 16 Aug 2010 Posts: 95
|
|
Posted: Sat Sep 04, 2010 4:47 pm |
|
|
Ttelmah, I believe my problem was related to the home brew LCD
routine I was using.
I found that the enable line function was slowing down the display
updating. I reconfigured the code and now the display will count from
1 to 100 really fast, about 1 second. This is alot closer to where I need
to be.
Here is the 4bit lcd routine I am using.
Thanks Scott.
Code: |
/*
Supported Commands Called from Main for 20x2 and 20x4 LCD module
LCD_START() Starts up the display
LCD_Cmd( CLEAR_DISP ); Clears the display
LCD_Cmd( LCD_LINE1 ); Selects Line 1
LCD_Cmd( LCD_LINE2 ); Selects Line 2
LCD_Cmd( LCD_LINE3 ); Selects Line 3
LCD_Cmd( LCD_LINE4 ); Selects Line 4
*/
//>>> PIN DEFINES CHANGE AS REQUIRED<<<<<<<<<<<
#define LCD_D0 pin_b4 // LCD Data bit 4.
#define LCD_D1 pin_b5 // LCD Data bit 5.
#define LCD_D2 pin_b6 // LCD Data bit 6.
#define LCD_D3 pin_b7 // LCD Data bit 7.
#define LCD_RS pin_c0 // LCD Register Select Data bit.
#define LCD_EN pin_c1 // LCD Enable Data bit.
//-----------------------------------------------------------------------------------
#define CLEAR_DISP 0x01 // Data to clear the Entire lcd Display
#define LCD_Line1 0X80 // Lcd First Line: Position top left
#define LCD_Line2 0xC0 // Lcd Second Line: Position top left
#define LCD_Line3 0x94 // LCD Third Line: Position top left
#define LCD_Line4 0xD4 // LCD Fourth Line: Position top left
//=== LCD SETUP and configuration =====================
void LCD_Enable ( void ) //Enable Line (EN) Routine
{
output_high ( LCD_EN );
delay_us (800);
output_low ( LCD_EN );
delay_us (800);
}
void LCD_SendByte(byte val) // Function Sends Data to Port B
{
OUTPUT_B(val | 0x0F); // Send data to port b, mask lower order bits.
LCD_Enable(); // Strobe Enable line.
swap(val); // Swap data in local variable val.
OUTPUT_B(val | 0x0F); // Send data to port b, mask lower order bits.
LCD_Enable(); // Strobe Enable Line.
}
void LCD_CmdLsbNibble(byte val)
{
output_low ( LCD_RS );
swap(val);
OUTPUT_B(val | 0x0F);
}
void LCD_Cmd(unsigned int cmd )
{
output_low ( LCD_RS );
LCD_SendByte(cmd);
}
/*------------------------ LCD Init Routine---------------------------------*/
void LCD_Init (void)
{
LCD_CmdLsbNibble( 0x00 ); // Set LCD Module DB4 TO DB7 to knowN state.
delay_ms (50); // Wait for 50 mili seconds after LCD Power on so LCD will stabilise.
output_low ( LCD_RS ); // Take register select Line to logic 0 ''Low''
LCD_CmdLsbNibble( 0x03 );
LCD_Enable(); // Send first init sequence. (0x03)
LCD_CmdLsbNibble( 0x03 );
LCD_Enable(); // Send second init sequence. (0x03)
LCD_CmdLsbNibble( 0x03 );
LCD_Enable(); // Send third init sequence. (0x03)
LCD_CmdLsbNibble( 0x02 ); // select 4-bit interface mode.
LCD_Enable(); // Call LCD_Enable function
// Configure the display module to display information
LCD_Cmd( 0x28 ); // function set (2 lines, 5x7 characters)
LCD_Cmd( 0x01 ); // clear display
LCD_Cmd( 0x0C ); // display ON, cursor off, no blink
LCD_Cmd( 0x03 ); // entry mode set, increment no shift
}
void lcd_start(void) // Starts the display Call from Main First
{
LCD_Init ();
LCD_Cmd( CLEAR_DISP );
}
//================= LCD Write Functions============
// Note these functions are used after the display has been Init.
void Enable1 ( void ) //Enable Line (EN) Routine
{
output_high ( LCD_EN );
delay_us (10);
output_low ( LCD_EN );
delay_us (10);
}
void Sendstuff(byte val)
{
OUTPUT_B(val | 0x0F);
Enable1();
swap(val);
OUTPUT_B(val | 0x0F);
Enable1();
}
void Write_LCD (byte Data )
{
Output_High (LCD_RS);
Sendstuff(Data);
} |
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|