Tengo un LCD de 20x4 caracteres conectado a mi kit TI TM4C1294 de la siguiente manera:
- Bus de datos al puerto A.
- pines RS, RW y E al puerto L 0-2
Escribí este código para conducirlo:
#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c1294ncpdt.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
void LCD_SendChar(short c)
{
GPIO_PORTA_AHB_DATA_R = c;
GPIO_PORTL_DATA_R |= 0x01;
GPIO_PORTL_DATA_R |= 0x04;
asm (" NOP");
GPIO_PORTL_DATA_R &= ~(0x04);
LCD_IsBusy();
}
void LCD_SendCmd(short command)
{
GPIO_PORTA_AHB_DATA_R = command;
GPIO_PORTL_DATA_R |= 0x00;
GPIO_PORTL_DATA_R |= 0x04;
asm (" NOP");
GPIO_PORTL_DATA_R &= ~(0x04);
LCD_IsBusy();
}
void LCD_SendString(char* value)
{
while(*value != 0)
{
LCD_SendChar(*value++);
}
}
void LCD_Init()
{
LCD_SendCmd(0x01);
LCD_SendCmd(0x38);
LCD_SendCmd(0x0E);
LCD_SendCmd(0x06);
LCD_SendCmd(0x02);
}
int main(void)
{
// Enable clock gating control for GPIO A and L
SYSCTL_RCGCGPIO_R |= SYSCTL_RCGCGPIO_R10;
SYSCTL_RCGCGPIO_R |= SYSCTL_RCGCGPIO_R0;
// Wait until GPIO blocks are ready.
while((SYSCTL_PRGPIO_R & SYSCTL_PRGPIO_R10) == 0);
while((SYSCTL_PRGPIO_R & SYSCTL_PRGPIO_R0 ) == 0){};
// Configure as Output, digital, no alternate or analog functions.
GPIO_PORTA_AHB_DIR_R = 0xFF;
GPIO_PORTA_AHB_DEN_R = 0xFF;
GPIO_PORTA_AHB_AFSEL_R = 0x0;
GPIO_PORTA_AHB_AMSEL_R = 0x0;
GPIO_PORTA_AHB_PCTL_R = 0x0;
GPIO_PORTL_DIR_R = 0x7;
GPIO_PORTL_DEN_R = 0x7;
GPIO_PORTL_AFSEL_R = 0x0;
GPIO_PORTL_AMSEL_R = 0x0;
GPIO_PORTL_PCTL_R = 0x0;
LCD_Init();
LCD_SendCmd(0x94);
LCD_SendString("Hello World!");
LCD_SendCmd(0xD4);
LCD_SendString("Hello World!");
while (1);
}
La placa se está ejecutando a una velocidad de 120MHz.
El problema es con el direccionamiento de línea. Descubrí que el direccionamiento de línea para un LCD de 20x4 es 0x80
, 0xC0
, 0x94
, 0xD4
para las líneas 1 a 3 respectivamente. Cuando se envía un "Hello World" en dos líneas como se muestra, las dos cadenas se muestran en la misma línea con un carácter aleatorio entre ellas. Si intento un "Hello World" para una línea mientras cambio la dirección de la línea cada vez que funciona bien. ¿Cuál podría ser la razón para no abordar las líneas correctamente? y cuál es el trato con esos caracteres aleatorios?
Sospecho con:
- Los valores proporcionados para cada función de retardo no son precisos.
- He leído que debo comprobar si la pantalla LCD está ocupada o no, pero no entendí el mecanismo detrás de ella.
Actualización: Además de Finbarr me las arreglé para verificar el indicador de ocupado. Aquí está mi función
void LCD_IsBusy()
{
GPIO_PORTA_AHB_DIR_R = 0x00;
GPIO_PORTL_DATA_R = 0x00;
GPIO_PORTL_DATA_R |= 0x02;
while(GPIO_PORTA_AHB_DATA_R & 0x80)
{
GPIO_PORTL_DATA_R &= ~(0x04);
GPIO_PORTL_DATA_R |= 0x04;
}
GPIO_PORTA_AHB_DIR_R = 0xFF;
}
Lo que me ayudó a eliminar todas las demoras en las llamadas. El código anterior se actualiza.