Dobrý den,
Potřeboval bych poradit s ovládáním GLCD 128x64 ST7920 od firmy Digole (model 12864ZW).
Na tomto webu microchip.com/forums/m830183.aspx jsem našel potřebný kód k ovládání řadiče ST7920 - je to fórum Microchip, kde nakonec problém vyřeší a zveřejní funkční kód.
Ten jsem upravil pro potřeby PIC16F877A - tzn. LATB → PORTB.
Dále jsem musel v kódu “převrátit” bitové hodnoty posílané na data port, neboť mám GLCD k mikrokontroléru zapojený takto: RD0 (MC) = DB0, RD1 = DB1 atd.
Příklad: v kódu bylo (funkce Initialize):
Send_Command(0b00110000); (to má být podle autora nastavení 8-bitového módu)
Podle datasheetu má být na data portu toto
DB0 = 1
DB1 = 0
DB2 = 0
DB3 = 0
DB4 = 0
DB5 = 0
DB6 = 0
DB7 = 0
tzn. že když mám dataporty GLCD připojené s portem D na MCU přímo, tak musím na PORTD poslat hodnotu 0b10000000, uvažuji doufám správně
Zde je tedy kód:
[code]#include <xc.h>
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = OFF
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF
#define _XTAL_FREQ 20000000 //20 MHz oscilator
#define DATA_OUT PORTD
#define RW RA4
#define RS RA5
#define EN RA3
#define RST RA0
#define PSB RA2
#define NC RA1
/*
- Funkce pinu GLCD podle datasheetu:
- RST = kdyz je low, tak se GLCD resetuje
- PSB = kdyz 0, tak seriova komunikace, kdyz 1, tak paralelni 8/4 bitova
- RS =
- Kdyz je paralelni mod (PSB = 1):
-
0 - "select instruction register (write) or busy flag, address counter (read)"
-
1 - "Select data register (write/read)"
- Kdyz je seriovy mod (PSB = 0):
-
0 - "Chip disabled - SID and SCLK should be set as 'H' or 'L'. Transcient of SID and SCLK is not allowed"
-
1 - "chip enabled"
- RW =
- Paralelni mod: Read-Write control
-
0 - Write
-
1 - Read
- Seriovy mod: Serial data input
- E =
- Paralelni mod:
-
1 - Enable trigger
- Seriovy mod: Serial clock
- D4 - D7 = “Higher nibble data bus of 8-bit interface and data bus for 4-bit interface”
- D0 - D3 = "Lower nibble data bus of 8-bit interface
*/
void Send_Data(unsigned char data);
void Send_Command(unsigned char command);
void Set_GraphicMode();
void Initialize();
void Clear_Graphics();
void Write_String( unsigned Y ,char * string );
char message[4] = “Ahoj”;
void main(void)
{
__delay_ms(1000); // Allow time for Vdc to settle on GLCD
TRISA = 0x00; //Set data port B as output
TRISD = 0x00; // Set control port D as output
PORTA = 0x00; // port B =0x00
PORTD = 0x00; // port D=0x00
RST = 0; // Set reset line to low
Initialize(); //Initialise GLCD
Send_Command(0x00); // Setting location to write characters. In this case 0,0 - Top Left Corner
Send_Data(0x03); // Sending a PREDEFINED character as described in ST7920 Datasheet.
Send_Data(0x04); // another one
Send_Data(0x05); // another one
Send_Data(0x06); // and another one.
Write_String(0x00, message); // Calling a function to send a String of characters, as defined in 'message' string.
// In Extended mode there are four line to print your text. Each line is 16 characters long. // Line 1 starts at 0x80 , line 2 starts at 0x90, line 3 starts at 0x88, line 4 starts at 0x99.
Set_GraphicMode(); // Set the display in Extended mode
Clear_Graphics(); // Must send a Clear command otherwise display could be corrupt.
while(1) {}
return ;
}
//======================== All the command codes below can be found on the ST7920 datasheet ======================
void Initialize()
{
__delay_ms(100);
PSB = 1; //toto jsem pridal - v datasheetu se pise, ze tady musi byt 1 pro paralelni komunikaci
RS=0;
RW=0;
__delay_us(400);
RST = 1;
__delay_ms(10); // Short delay after resetting.
Send_Command(0b00001100); // 8-bit mode. OK
__delay_us(200);
Send_Command(0b00001100); // 8-bit mode again. OK
__delay_us(100);
Send_Command(0b00110000); // display on
__delay_us(200);
Send_Command(0b10000000); // Clears screen. OK
__delay_ms(20);
Send_Command(0b01100000); // Cursor moves right, no display shift.
__delay_us(200);
Send_Command(0b01000000); // Returns to home. Cursor moves to starting point.
}
//========= Setting the control lines to send a Command to the data bus ================
void Send_Command(unsigned char command)
{
RS = 0;
__delay_us(50);
EN = 1;
DATA_OUT = command;
__delay_us(80);
EN = 0;
}
//============= Setting the control lines to send Data to the data bus =====================
void Send_Data(unsigned char data)
{
RS = 1;
__delay_us(60);
DATA_OUT = data;
__delay_us(30);
EN = 1;
__delay_us(20);
EN = 0;
__delay_us(20);
}
//======================= Sent Command to set Extanded mode ====================
void Set_GraphicMode()
{
Send_Command(0b00110100); // Extended instuction set, 8bit
__delay_us(100);
Send_Command(0b00110110); // Repeat instrution with bit1 set
__delay_us(100);
}
//=========== This function set all the pixels to off in the graphic controller =================
void Clear_Graphics()
{
unsigned char x, y;
for(y = 0; y < 64; y++)
{
if(y < 32)
{
Send_Command(0x80 | y);
Send_Command(0x80);
}
else
{
Send_Command(0x80 | (y-32));
Send_Command(0x88);
}
for(x = 0; x < 16; x++)
{
Send_Data(0x00);
}
}
}
//==== Send one character at the time from the ‘message’ string ===========
void Write_String ( unsigned Y ,char * string )
{
Send_Command(Y);
while(*string!= ‘\0’) // Looking for code signigying ‘end of line’ .
{
Send_Data (*string++);
}
}[/code]
Displej však stále nepracuje. Zkrátka se na něm nic nezobrazuje.
Dlouho jsem také pročítal datasheet (který posílám v příloze), avšak bezvýsledně.
Nerad bych vedl polemiku o tom, že jsem kód zkopíroval. Myslím, že mu z 90% rozumím
Velice by mi pomohlo, kdyby jste mi někdo s tímto problémem pomohl, neboť je to poslední záležitost, na které stojí můj projekt seismografu.
Mám na mysli např. funkci Write_String - v jakém intervalu se má dosazovat souřadnice Y - nejsem si jist, jestli se text nevykresluje někam jinam, než má.
PS.: Předem bych ale chtěl upozornit, že možnost rozbitého GLCD nechávám opravdu jako poslední možnou - GLCD je nový a nikdy nebyl použit.
Děkuji všem za konstruktivní názory!
Display 12864ZW.pdf (1010 KB)