Tutoriales
Librería LCD Nokia 6100 para PIC32
- Detalles
- Categoría: Tutorial
- Publicado el Jueves, 23 Diciembre 2010 10:33
- Escrito por Santiago Villafuerte
- Visto: 20339
Esta librería se puede emplear para controlar una LCD de celular Nokia 6100 mediante un PIC32MX y 4 líneas de control. Te será útil para dibujar imágenes y texto en la pantalla. Para este ejemplo se utilizó la Color LCD - Breakout Board de Sparkfun y la ya antes revisada tarjeta MiE32U para PIC32MX de Microingenia. La librería surge a partir de la mezcla de 2 librerías proporcionadas por Sparkfun: una librería escrita para un microcontrolador LPC y otra para un Atmel.
Características de la pantalla Nokia 6100
+ 131 x 131 pixeles
+ Compatible con diversos celulares (6100, 6610, 7210, 7250, and 5100)
+ Comunicación SPI de 9 bits
+ Iluminación integrada (funcional a 7V)
+ 4,096 colores disponibles
La pantalla cuenta con un conector SMD muy pequeño que llega a ser difícil de soldar. Cuento con una pantalla a la que le hice su propia PCB y pude soldar el conector. Sólo bastó proporcionarle una alimentación de 7V, la cual armé con una fuente step-up usando un TC962CPA de Microchip. Posteriormente compré la breakout board de Sparkfun, la cual ya incluye la LCD soldada, 2 tact switches, un LED tricolor, la fuente step-up de 7V a partir de 3.3V y un header para conexiones. Me resultó bastante práctica ya que para cuestiones de prueba es muy versátil.
Comunicación SPI
La pantalla usa la interfaz SPI de 9 bits para comunicarse con un microcontrolador. Se emplean 4 líneas para controlarla:
+ Reset
+ DIO, data input output
+ SCK, reloj
+ CS, chip select
Los pulsos para la interfaz SPI pueden generarse por hardware o por software y en la librería que he mezclado se usa el modo software (bit banging).
La librería Nokia_LCD_driver
Esta librería cuenta con 3 archivos:
+ Nokia_LCD_driver.c
Contiene las funciones principales para inicializar la librería, enviarle pixeles y trazar texto
+ Nokia_LCD_driver.h
Contiene defines útiles como los códigos de cada color
+ fonts.c
Contiene 3 tablas con caracteres en tamaños pequeño, mediano y grande
Para utilizar la librería basta con incluir los 3 archivos anteriores mediante una línea #include y definir qué pines se usarán en el PIC32. Nótese la posición del bit en cada define. La librería hace uso perfecto de los registros atómicos del PIC32.
//Librería para la LCD
#define LCD_RES 1 //RB0
#define LCD_DIO 2 //RB1
#define LCD_SCK 4 //RB2
#define LCD_CS 8 //RB3
#include "./lcd_nokia/Nokia_LCD_driver.c"
Los 4 pines se declararán con TRIS de salida.
Embebiendo una imagen
Para insertar una imagen a la pantalla se debe hacer pixel a pixel. El contenido de la imagen debe exportarse de archivo .BMP a un archivo .H. Para lograr esto existe la aplicación C Code Image Generator escrito por Jamie Samayoa. Se debe abrir un BMP de 131 x 131 pixeles y exportar el código. Después se guarda el archivo .H en el proyecto. Se debe comentar la primera línea de datos ya que puede resultar inconviente para el código.
// Image format {Width, Height, Bit Depth, Byte Count , Max Frame, ...
// Bit Depth:
// 12b bit: 0x04
// 0000RRRR GGGGBBBB
const unsigned char bmp[] = {
//0x83, 0x83, 0x04, 0x02, 0x00, //comentada
0xF, 0xFF, 0xF, 0xFF, 0xF, 0xFF, 0xF, 0xFF, 0xF
El programa
En este ejemplo se mostrará una pantalla y sobre ella se escribirá texto con una medición del ADC del PIC32MX440F512H directamente en Volts y posteriormente unos saludos. El código es muy simple y creo que no hace falta explicarlo. Si tienes dudas te recomiendo que leas mis 2 tutoriales anteriores sobre PIC32. La conexión PIC32 <-> LCD, del PWM y del ADC es como sigue:
+ RB0 Reset
+ RB1 DIO
+ RB2 SCK
+ RB3 CS
+ RB4 a una señal de 0V a 3.3V (ADC)
+ RD0 a cualquier LED
La LCD se alimenta por los pines VBAT y 3.3V directamente a 3.3V y su línea GND. No hace falta usar una fuente de 7V.
Los archivos fuente del programa se pueden descargar a continuación
La contraseña de descarga es PIC32MXLCD
(Descarga)
/*
Demo de LCD Nokia 6100
MigSantiago.com
*/
#include <p32mx440f512h.h>
#include <plib.h>
////////////////////////////////////////////////////////////////////////////////////////////
//Configurando los osciladores
//Entrada de cristal a 8MHz
//Para CPU será elevada a 80Mhz
#define SYS_FREQ (80000000L)
//CPU
//XT es de 8MHz y hay que elevarlo a 80MHz
#pragma config FPLLIDIV = DIV_2, FPLLMUL = MUL_20, FPLLODIV = DIV_1
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
#pragma config FSOSCEN = OFF //sin oscilador secundario
////////////////////////////////////////////////////////////////////////////////////////////
//Delays
#define GetInstructionClock() (80000000L)
#include "TimeDelay.c"
//Librería para la LCD
#define LCD_RES 1 //RB0
#define LCD_DIO 2 //RB1
#define LCD_SCK 4 //RB2
#define LCD_CS 8 //RB3
#include "./lcd_nokia/Nokia_LCD_driver.c"
//Pines a usar
#define TRIS_AD4 TRISBbits.TRISB4 //adc
#define TRIS_PWM TRISDbits.TRISD0
#define SYS_FREQ (80000000L)
#define PB_DIV 1
#define PRESCALE 1
//Logotipo
#include "logo.h"
char texto[30];
//////////////////////////////////////////////////////////////////////////////////////////
//tiempo * 250us
void DelayPWM(unsigned int tiempo)
{
BOOL sentido=1;
while(tiempo--)
{
Delay10us(25);
if(sentido)
{
++OC1RS;
if(OC1RS==1999)
sentido=0;
}
else
{
--OC1RS;
if(OC1RS==0)
sentido=1;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//Programa principal
int main()
{
int i, j, k;
int pix;
float voltaje;
SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
//disable JTAG port
DDPCONbits.JTAGEN = 0;
//Configura pines
TRIS_PWM = 0; //Salida PWM
TRIS_AD4 = 1;
AD1CON2 = 0;
AD1CON3 = 0x000F; //512 Tpb
AD1PCFG = 0xFFFF; //todo digital
AD1PCFGbits.PCFG4 = 0; //menos AN4
AD1CSSL = 0;
AD1CHS=0;
AD1CHSbits.CH0SA = 4;
AD1CON1 = 0x8000; //adc on
//Pines RB0 a RB3 serán para controlar la LCD
PORTSetPinsDigitalOut(IOPORT_B, LCD_RES | LCD_DIO | LCD_SCK | LCD_CS);
//Inicializa la pantalla
LCDInit();
//Configura OC1 junto con TIMER2 para generar PWM en RD0
//Duty cycle (es el que cambiara constantemente)
OC1R = 0; //sólo se debe escribir al inicio
OC1RS = 0;
//Modo de operación PWM sin Fault Pin
OC1CONbits.OCM = 0b110;
//Elige TIMER2 como origen de comparaciones
OC1CONbits.OCTSEL = 0;
//Arranca PWM
OC1CONbits.ON = 1;
//TIMER2 corriendo 1:1, 80MHz generará evento cada 25us
//Periodo PWM = 25us = 40kHz
//(1999+1)(1/80MHz)=25us
OpenTimer2(T2_ON | T2_SOURCE_INT | T2_PS_1_1, 1999);
while(1)
{
//Logo
k=0;
for(i=0; i<131; ++i)
for(j=0; j<131; ++j)
{
pix=(int)(bmp[k*2]<<8);
pix|=(int)bmp[k*2+1];
LCDSetPixel(pix, i, j);
++k;
}
//Medir ADC
AD1CON1bits.SAMP = 1;
Delay10us(1);
AD1CON1bits.SAMP = 0;
while(!AD1CON1bits.DONE);
voltaje=(float)ADC1BUF0*0.003225806452; //10 bits @ 3.3V
sprintf(texto, "ADC: %0.2fV", voltaje);
LCDString(texto, GRA, 5, 34, RED, WHITE);
sprintf(texto, "Saludos desde");
LCDString(texto, PEQ, 5, 51, BLUE, WHITE);
sprintf(texto, "MigSantiago.com");
LCDString(texto, MED, 5, 66, GREEN, WHITE);
sprintf(texto, "Nokia LCD 6100");
LCDString(texto, GRA, 5, 82, BLUE, WHITE);
sprintf(texto, "PIC32MX440F512H");
LCDString(texto, GRA, 5, 98, RED, WHITE);
sprintf(texto, "MiE32U V1.0");
LCDString(texto, GRA, 5, 114, GREEN, WHITE);
DelayPWM(5000);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
Los resultados
El programa dibuja la imagen y el texto correctamente. Además se usa la salida PWM con efecto de desvanecimiento para iluminar uno de los 3 LEDs de la tarjeta de Sparkfun. Prácticamente se puede escribir cualquier cosa en la pantalla ya que la tabla de caracteres contiene todos los caracteres ASCII disponibles.