Ik ben bezig met het volgende. Ik heb een 2x24 LCD scherm
(HD44780) Omdat ik wat beperkt ben qua I/O wil ik deze serieel aansturen. Hiervoor gebruik ik een 74HC595 waarbij ik de storage klok samen met de data clock aanstuur hierdoor wordt de ingang direct doorgeschoven naar.
Het geheel wordt aangestuurd door een pic16f819. Het rare is nu dat de data naar de eerste rij wel zichtbaar wordt op de lcd maar de data op de tweede rij niet. (ik heb alle adressen van de HD44780 al geprobeerd dus daar ligt het niet aan) Nu denk ik dat er ergens in mijn initializatie iets mis zit maar ik kom er niet uit kan iemand mij op helpen
// mijn init ziet er als volgt uit
Enable = 0
write($30)
Enable = 1
delay
Enable = 0
write($38) //8 bit mode
Enable = 1
delay
Enable = 0
write($30)
Enable = 1
delay
Enable = 0
write($01)
Enable = 1
delay
Enable = 0
write($06)
Enable = 1
delay
Enable = 0
Ziet iemand wat ik fout doe
Om alles wat duidelijker te maken is hier het schema wat ik gebruik (hier is een 74HC164 gebruikt ipv 74HC595 maar dat mag niet uitmaken)
Dit is de code waarmee ik de LCD probeer mee aante sturen
Let wel ik heb een pascal compiler. Volgens mij moet het geen probleem zijn om dit te lezen.
unit SLCD_8Bit_Drv;
implementation
const
_CH8 : BYTE = 1;
_COMMAND8 : BYTE = 0;
LCD_FIRST_ROW : BYTE = 128;
LCD_SECOND_ROW : BYTE = 64;
LCD_THIRD_ROW : BYTE = 148;
LCD_FOURTH_ROW : BYTE = 212;
LCD_CLEAR : BYTE = 1;
LCD_RETURN_HOME : BYTE = 2;
LCD_CURSOR_OFF : BYTE = 12;
LCD_UNDERLINE_ON : BYTE = 14;
LCD_BLINK_CURSOR_ON : BYTE = 15;
LCD_MOVE_CURSOR_LEFT : BYTE = 16;
LCD_MOVE_CURSOR_RIGHT : BYTE = 20;
LCD_TURN_OFF : BYTE = 0;
LCD_TURN_ON : BYTE = 8;
LCD_SHIFT_LEFT : BYTE = 24;
LCD_SHIFT_RIGHT : BYTE = 28;
CLK : BYTE = 0; // PIC out_port^.1 connected to Shift clock
DATA : BYTE = 1; // PIC out_port^.1 connected to Shift data
ENABLE8 : BYTE = 2; // PIC out_port^.2 connected to LCD.E
var out_port:^byte;
procedure Shift_data(output:byte);
var i: byte;
begin
clearbit(out_port^,clk);
for i:=0 to 7 do
begin
out_port^.data:=(output shr (7-i)) and 1;
setbit(out_port^,clk);
delay_us(1);
clearbit(out_port^,clk);
delay_us(1);
end;
setbit(out_port^,clk);
delay_us(1);
clearbit(out_port^,clk);
delay_us(100);
end;
procedure SLcd8_Cmd(Out_Char: byte);
begin
shift_data(Out_char);
ClearBit(out_port^, data);
SetBit(out_port^, ENABLE8);
ClearBit(out_port^, ENABLE8);
Delay_ms(5);
end;
procedure SLcd8_Chr(Row, Column, Out_Char: byte);
begin
case Row of
1: Row := LCD_FIRST_ROW;
2: Row := LCD_SECOND_ROW;
3: Row := LCD_THIRD_ROW;
4: Row := LCD_FOURTH_ROW
else
Row := LCD_FIRST_ROW;
end;//case
Row := Row + Column-1;
SLcd8_Cmd(Row); //ga naar positie
shift_data(Out_char);
SetBit(out_port^, data);
SetBit(out_port^, ENABLE8);
ClearBit(out_port^, ENABLE8);
Delay_ms(5);
end;
procedure SLcd8_Init(var PortCtrl : byte);
begin
out_port:=@PortCtrl;
//Clear everything
ClearBit(out_port^,data);
ClearBit(out_port^,ENABLE8);
Delay_ms(8);
SLCD8_cmd($30);
Delay_us(8300); //8.3 ms
//Set data = 8 bit two lines font 5x7
SLCD8_cmd($38);
Delay_us(200);
//Set dispaly off cursor off blink off
SLCD8_cmd($30);
Delay_us(40);
// Clear display
SLCD8_cmd($01);
delay_us(1640); //1.64 ms
//set entry Increment no shift
SLCD8_cmd($06);
delay_us(40); //40 us
end;
procedure SLCD8_Out(Row, Column: byte; var text: array[255] of char);
var i: byte;
begin
for i := 0 to Length(text)-1 do
SLcd8_Chr(Row, Column+i, text[i]);
end;
end.
Hallo, heb ooit zelf eens zoiets gehad, met nl BASCOM en een LCD.
Op één of andere manier kwamen de tekens niet door op de tweede lijn:
Na veel speurwerk ben ik er dan achtergekomen dat een programmeer volgorde van twee instructies van belang was in de tijd.
Ik had UPPERLINE, CLS geprogrammeerd en gaf problemen
Het moest zijn CLS, UPPERLINE en toen ging alles weer goed.
Ik weet niet of in uw broncode gebruikt wordt gemaakt van zulke opdrachten maar probeer eerst eens een hex file te laden waarvan je zeker bent dat ie werkt. 9 kansen op de 10 werkt de LCD dan wel en kan je stap voor stap jouw programma in dienst nemen. Probeer een zo basis mogelijk programma zonders toeters of bellen te laden en bouw zou verder uit. Zo ben ik er ook uitgekomen. Succes!
Ik heb nu alles weer terug gezet naar een parallele versie dus zonder shift register en nu krijg ik wel tekst op de tweede lijn. Kortom de basis driver (init volgorde, Enable lijnen ed. zijn dus wel goed). Ik ga nu maar weer stapje voor stapje verder om toch de seriele versie voor elkaar te krijgen. Ik houdt jullie wel op de hoogte met vorderingen en vragen
Hoera gelukt,
Er bleef schijnbaar een bitje hangen in mijn vorige versie,
Voor geintreseerde hier mijn Pascal code voor de driver
{*******************************************************************************
This is a driver for Hitachi based LCD wired via 8-bit interface. The driver
is provided "AS IS". Further optimizations are possible, the code should be a
guide on how to use 8-bit interface protocol. The 8-bit data is shifted serial
to the LCD by a TTL shift register.
Tested on P16F819.
2006-08-15
LCD Pin description
Pin# Symbol Level Function
1 Vss GND Ground
2 Vcc +5V Module power
3 Vee note1 Liquid crystal drive
4 RS H/L Register select, H=data, L=instruction
5 R/W H/L Read/Write, H=read (module->CPU), L=write (CPU->module)
6 E H/L Enable
7 DB0 " Data bit 0 connected to PIC portDATA.0 (least significant bit)
8 DB1 " 1 connected to PIC portDATA.1
9 DB2 " 2 connected to PIC portDATA.2
10 DB3 " 3 connected to PIC portDATA.3
11 DB4 " 4 connected to PIC portDATA.4
12 DB5 " 5 connected to PIC portDATA.5
13 DB6 " 6 connected to PIC portDATA.6
14 DB7 " 7 connected to PIC portDATA.7
*******************************************************************************}
unit LCD_8Bit_Drv;
implementation
const
_CH8 : BYTE = 1;
_COMMAND8 : BYTE = 0;
LCD_FIRST_ROW : BYTE = 128;
LCD_SECOND_ROW : BYTE = 192;
LCD_THIRD_ROW : BYTE = 148;
LCD_FOURTH_ROW : BYTE = 212;
LCD_CLEAR : BYTE = 1;
LCD_RETURN_HOME : BYTE = 2;
LCD_CURSOR_OFF : BYTE = 12;
LCD_UNDERLINE_ON : BYTE = 14;
LCD_BLINK_CURSOR_ON : BYTE = 15;
LCD_MOVE_CURSOR_LEFT : BYTE = 16;
LCD_MOVE_CURSOR_RIGHT : BYTE = 20;
LCD_TURN_OFF : BYTE = 0;
LCD_TURN_ON : BYTE = 8;
LCD_SHIFT_LEFT : BYTE = 24;
LCD_SHIFT_RIGHT : BYTE = 28;
CLK : BYTE = 0; // PIC output_port^.0 connected to Shift clock
DATA : BYTE = 1; // PIC output_port^.1 connected to Shift data
ENABLE8 : BYTE = 3; // PIC output_port^.3 connected to LCD.E
var output_port :^byte;
data_port :^byte;
procedure Shift_data(output:byte);
var i: byte;
begin
clearbit(output_port^,clk);
for i:=0 to 7 do
begin
output_port^.data:=(output shr (7-i)) and 1;
setbit(output_port^,clk);
delay_us(1);
clearbit(output_port^,clk);
delay_us(1);
end;
setbit(output_port^,clk);
delay_us(1);
clearbit(output_port^,clk);
delay_us(100);
end;
procedure MyLcd8_Cmd(Out_Char: byte);
begin
shift_data(out_char);
ClearBit(Output_port^, data);
SetBit(Output_port^, ENABLE8);
ClearBit(Output_port^, ENABLE8);
Delay_ms(5);
end;
procedure MyLcd8_Chr(Row, Column, Out_Char: byte);
begin
case Row of
1: Row := LCD_FIRST_ROW;
2: Row := LCD_SECOND_ROW;
3: Row := LCD_THIRD_ROW;
4: Row := LCD_FOURTH_ROW
else
Row := LCD_FIRST_ROW;
end;//case
Row := Row + Column-1;
MyLcd8_Cmd(Row);
shift_data(out_char);
SetBit(Output_port^, data);
SetBit(Output_port^, ENABLE8);
ClearBit(Output_port^, ENABLE8);
Delay_ms(5);
end;
procedure MyLcd8_Init(var portCTRL : byte);
begin
output_port:=@PortCtrl;
ClearBit(output_port^,data);
ClearBit(output_port^,ENABLE8);
MyLCD8_CMD($0);
Delay_ms(8);
MyLCD8_CMD($30);
Delay_us(8300); //8.3 ms
MyLCD8_CMD($38);
delay_us(40); //40 us
MyLCD8_CMD($08);
Delay_us(40);
MyLCD8_CMD($01);
delay_us(1640); //1.64 ms
MyLCD8_CMD($06);
delay_us(40); //40 us
end;
procedure MyLCD8_Out(Row, Column: byte; var text: array[255] of char);
var i: byte;
begin
for i := 0 to Length(text)-1 do
MyLcd8_Chr(Row, Column+i, text[i]);
end;
end.