Hardware
O Arduino UNO possui uma saída de 3,3V, porém as saídas digitais operam com 5V. Por este motivo é necessário colocar o divisor resistivo nos sinais lógicos; o display em si é alimentado pela saída de 3,3V. No circuito abaixo os LEDs de backlight são alimentados pela saída de 5V, através de um resistor.
Para quem não enxergar na figura (mesmo depois de clicar para ampliar) são as seguintes as conexões no display:
- pino 1 (Vcc) com a saída de 3,3V do Arduino.
- pino 2 (GND) com o sinal GND do Arduino.
- pino 3 (SCE) com o Digital 7 do Arduino, através de um divisor 15K / 22K
- pino 4 (RST) com o Digital 6 do Arduino, através de um divisor 15K / 22K
- pino 5 (D/C) com o Digital 5 do Arduino, através de um divisor 15K / 22K
- pino 6 (DIN) com o Digital 4 do Arduino, através de um divisor 15K / 22K
- pino 7 (SCK) com o Digital 3 do Arduino, através de um divisor 15K / 22K
- pino 8 (LED) com a saída de 5V do Arduino, através de um resistor de 390R
Software
Vamos usar alguns defines para determinar quais os pinos usados na conexão:
// Conexões do display ao Arduino #define PIN_SCE 7 #define PIN_RESET 6 #define PIN_DC 5 #define PIN_SDIN 4 #define PIN_SCLK 3O primeiro passo é termos uma rotina que envie um byte serialmente ao display, a biblioteca do Arduino possui a função shiftOut que faz o trabalho pesado:
// Seleção de dado ou comando #define LCD_CMD LOW #define LCD_DAT HIGH // Envia um byte para o controlador do display // dc: LCD_CMD ou LCD_DAT // data: byte a enviar void LcdWrite(byte dc, byte data) { digitalWrite(PIN_DC, dc); digitalWrite(PIN_SCE, LOW); shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data); digitalWrite(PIN_SCE, HIGH); }Com esta rotina podemos criar uma rotina de iniciação do display, que envia os comandos necessários para a configuração. Os valor usado no comando Set Vop pode precisar ser ajustado para obter um bom contraste.
// Iniciação do display void LcdInitialise(void) { // define a direção dos pinos de E/S pinMode(PIN_SCE, OUTPUT); pinMode(PIN_RESET, OUTPUT); pinMode(PIN_DC, OUTPUT); pinMode(PIN_SDIN, OUTPUT); pinMode(PIN_SCLK, OUTPUT); // executa um reset do controlador digitalWrite(PIN_RESET, LOW); digitalWrite(PIN_RESET, HIGH); // envia os comandos de iniciação LcdWrite( LCD_CMD, 0x21 ); // LCD Extended Commands. LcdWrite( LCD_CMD, 0xaf ); // Set LCD Vop (Contraste) LcdWrite( LCD_CMD, 0x04 ); // Set Temp coefficent LcdWrite( LCD_CMD, 0x14 ); // LCD bias mode 1:48 LcdWrite( LCD_CMD, 0x20 ); // LCD Basic Commands. LcdWrite( LCD_CMD, 0x0c ); // LCD no modo normal }Podemos agora implementar uma limpeza da tela, que preenche toda a memória com zeros:
// Limpa a tela // Tamanho da tela #define LCD_DX 84 #define LCD_DY 48 void LcdClear(void) { // posiciona ponteiro no inicio da memória LcdWrite( LCD_CMD, 0x40); LcdWrite( LCD_CMD, 0x80); // preenche a memória com zeros for (int index = 0; index < LCD_DX * LCD_DY / 8; index++) { LcdWrite(LCD_DAT, 0x00); } }Vamos implementar agora a escrita de caracteres, usando uma matriz de 7x8. Para simplificar, vamos considerar que os caracteres estão sempre alinhados em um grid alfanumérico de 6 linhas de 12 caracteres. O aspecto dos caracteres é armazenado em uma matriz (copiada do exemplo no site da Sparkfun), vamos deixar uma coluna em branco antes e depois de cada caracter:
// Definição dos caracteres static const byte ASCII[][5] = { {0x00, 0x00, 0x00, 0x00, 0x00} // 20 ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 ! ,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 " ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 # // etc };O posicionamento em uma certa linha e coluna é feita através dos comandos Set Address:
// Posiciona em uma determina linha e coluna alfanuméricas void LcdPos(int lin, int col) { LcdWrite( LCD_CMD, 0x40 + lin); LcdWrite( LCD_CMD, 0x80 + col*7); }A escrita de um caracter consiste simplesmente em copiar para a memória do display os 5 bytes correspondente ao caracter, mais um zero antes e depois:
// Escreve um caracter na posição atual void LcdWriteChar(char character) { LcdWrite(LCD_DAT, 0x00); for (int index = 0; index < 5; index++) { LcdWrite(LCD_DAT, ASCII[character - 0x20][index]); } LcdWrite(LCD_DAT, 0x00); }Feito tudo isto, é trivial fazer uma rotina para apresentar um string:
// Escreve um string a partir de uma certa // linha e coluna void LcdWriteString(char *characters, int lin, int col) { LcdPos (lin, col); while (*characters) LcdWriteChar(*characters++); }
O sketch correspondente (ldc5110_1.zip) pode ser baixado dos arquivos do blog (ver no alto à direita).
Nenhum comentário:
Postar um comentário