FRDM-KL46Z_LCD_Test Versión Corregida y Aumentada. Soporte para Display LCD en Modo GPIO, I2C y SPI Correcciones a la Biblioteca TextLCD para completa funcionalidad

Dependencies:   TextLCD mbed

main.cpp

Committer:
Antulius
Date:
2022-09-22
Revision:
0:261e911dcf75

File content as of revision 0:261e911dcf75:

/* ###########################################################################
**    Archivo        : main.c
**    Proyecto       : FRDM-KL46Z_LCD_Test
**    Procesador     : MKL46Z256VLL4
**    Herramienta    : Mbed
**    Version        : Driver 01.01
**    Compilador     : GNU C Compiler
**    Fecha/Hora     : 14-07-2015, 11:48, # CodeGen: 0
**    Descripción    :
**         Este proyecto prueba todas las configuraciones para operar un
**         display LCD alfanumérico en modo de 4 bits
**         - Utilizando los GPIO's
**         - Utilizando el SPI y el C.I. SN74HC595 o CD4094
**         - Utilizando el I2C y el Modulo PCF8574 y PCF8574A
**         soporta las siguintes pantallas LCD alfanuméricas:
**         1x8, 1x16, 2x16, 2x20, 4x16, 4x20
**   Componentes     : GPIO, Timer, SPI, I2C, TextLCD.
**   Configuraciones : TextLCD, TextLCD_SPI, TextLCD_I2C
**   Autores         :
**         ATEAM Development Group:
**          - Antulio Morgado Valle
**
**   Versión        : Beta
**   Revisión       : A
**   Release        : 0
**   Date           : 20/10/2019
**   Bugs & Fixes   :
**                    Added support for Led_RGB
**                    22/09/2018 
**                    Added LCD Menu, Beta version (with bugs)
**
** El permiso se otorga por este medio, sin cargo, a cualquier persona que 
** obtenga una copia de este software y los archivos de documentación asociados
** (el "Software"), para operar en el Software sin restricciones, incluidos, 
** entre otros, los derechos de uso, copia, modificación, fusión, publicación, 
** distribución, sublicencia y/o venta de copias de el Software, y para permitir
** que las personas a quienes se suministra el Software lo hagan, sujeto a las 
** siguientes condiciones:
**
** El aviso de copyright anterior y este aviso de permiso se incluirán en todas
** las copias o partes sustanciales del Software.
**
** EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESO
** O IMPLÍCITO, INCLUYENDO PERO NO LIMITADO A LAS GARANTÍAS DE COMERCIABILIDAD,
** APTITUD PARA UN PROPÓSITO PARTICULAR Y NO INCUMPLIMIENTO. EN NINGÚN CASO,
** LOS AUTORES O TITULARES DE DERECHOS DE AUTOR SERÁN RESPONSABLES POR CUALQUIER
** RECLAMACIÓN, DAÑOS U OTRAS RESPONSABILIDADES, YA QUE SEA RESPONSABLE DE UN
** CONTRATO, CORTE U OTRA MANERA, DERIVADOS DE, FUERA O EN CONEXIÓN CON 
** EL SOFTWARE O EL USO O OTRAS REPARACIONES EN EL SOFTWARE.
** ###########################################################################*/
/*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:  Includes
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*/
#include "mbed.h"
#include "TextLCD.h"
#include "I2C.h"
#include "SPI.h"
#include "Serial.h" 
#include "stdio.h"
/*
:...............................................................................
:  Definiciones
:...............................................................................
*/
#define ON              0           // Estado para boton presionado
#define OFF             1           // Estado para boton sin presionar
#define HOLD            2           // Estado para boton mantenido
#define RELEASE         3           // Estado para boton liberado
#define REPEAT          4           // Estado para boton repetido
#define FALSE           0           // Estado FALSO
#define TRUE            1           // Estado VERDADERO
#define HIGH            1           // Estado ALTO
#define LOW             0           // Estado BAJO
#define BUZZ_ON         0           // Estado para Buzzer Encendido
#define BUZZ_OFF        1           // Estado para Buzzer Apagado
#define LCD_INTERFACE   1           // Tipo Interfaz del LCD: 0=Normal, 1=I2C, 2=SPI
#define I2C_ADDRESS     0x7E        // Dirección I2C para Interfaz al LCD: 0x7E, 0x4E
#define TICKER_RATE     1000        // Periodo de Interrupción (us)
#define BAUD_RATE       115200      // Velocidad de Transmisión (Bauds))
                                    // 300, 600, 1200, 2400, 4800, 9600,
                                    // 14400, 19600, 28800, 38400, 57600
                                    // 115200, 230400
/*
+-------------------------------------------------------------------------------
|  Configuración de Puertos 
+-------------------------------------------------------------------------------
*/
Ticker      TimerInt;               // Inicializa la Interrupción por Timer
DigitalOut  led_monitor(LED2);      // Inicializa el LED Monitor
PwmOut      buzzer (PTE31);         // Inicializa el PWM para el Buzzer
PwmOut      backlight(PTA13);       // Inicializa el LED Backlight del LCD (Externo)
AnalogIn    light (PTB0);           // Inicializa Canal Analógico para BackLight
/*
** -------------------------------------------------------------------
**    Inicialización de los Pines de Funciones Especiales.
** -------------------------------------------------------------------
*/

/*************************************************
* Host PC Communication channels
**************************************************/
Serial      terminal(USBTX, USBRX); // Inicializa la Comunicación Serial a la PC
//Serial      terminal(PTA2,PTA1);          // Terminal Serial
//Serial      terminal(PTE0, PTE1);         // Tx, Rx Using MAX3232 or BlueTooth

/*************************************************
* Bluetooth Communication support
************************************************** 
* Initialize the library with the numbers of the interface pins
* Board Freedom FRDM-KL46Z
* IDE  Mbed On Line Compiler
***************************************************/
Serial   bluetooth(PTE0, PTE1);             // Tx, Rx

/**************************************************
* Instantiation for creating a TextLCD interface 
* for using control and functions over selected port 
***************************************************/
// LCD instantiation 
#if LCD_INTERFACE == 0
/************************************************* 
* GPIO Pin Port
************************************************** 
* Initialize the library with the numbers of the interface pins
* Board Freedom FRDM-KL46Z
* IDE  Mbed On Line Compiler
* LCD    GPIO 
* Pin    Board
* VSS    5V
* VDD    GND
* VO     POT 1K
* RS     PTC6 
* RW     GND  
* E      PTC7
* D4     PTC8
* D5     PTC9
* D6     PTC10
* D7     PTC11
* BL+    PTA13 
* BL-    GND 
***************************************************/
TextLCD lcd(PTC6,PTC7, PTC8, PTC9, PTC10, PTC11, TextLCD::LCD16x2); // 4bit bus: rs, e, d4-d7 (lsb -> msb) 
DigitalOut  LE      (PTC4);                         // Pin para Latch Enable (SN74HC573)
#endif
#if LCD_INTERFACE == 1
/************************************************* 
* I2C Communication
************************************************** 
* Initialize the library with the numbers of the interface pins
* Board Freedom FRDM-KL46Z
* IDE  Mbed On Line Compiler
* LCD  I2C              PCF8574A
* Pin  Board            LCD
*      I2C_SCL          SCL (white) + resistance pull-up 4.7k
*      I2C_SDA          SDA (blue)  + resistance pull-up 4.7k
*      5V               5V  (red)
*      GND              GND (black)
***************************************************/
I2C         i2c_lcd(PTC2,PTC1);             // SDA, SCL
TextLCD_I2C lcd(&i2c_lcd, I2C_ADDRESS, TextLCD::LCD20x4);  // Address 0x4E or 0x7E I2C bus, PCF8574A Arduino Shield, LCD Type
#endif
#if LCD_INTERFACE == 2
/*************************************************
* SPI Communication
************************************************** 
* Initialize the library with the numbers of the interface pins
* Board Freedom FRDM-KL46Z
* IDE  Mbed On Line Compiler
* LCD  SPI  SN74HC595
* Pin  Board     LCD
*      SPI_MOSI  SER   (white) 
*      SPI_MISO  none  (blue)  
*      SPI_CLK   SRCLK
*      SPI_PCS   RCLK
*      5V        5V  (red)
*      GND       GND (black)
***************************************************/
SPI         spi_lcd(PTD6,PTD7,PTD5,PTD4);   // MOSI, MISO, SCLK, SSEL
DigitalOut  SSel(PTD4);                     // Inicializa el Pin de Seleccion de Esclavo SPI
TextLCD_SPI lcd(&spi_lcd, PTD4, TextLCD::LCD20x4, TextLCD::HD44780);    // SPI bus, SN74595 expander, CS pin, LCD Type 
#endif

/*
** ===================================================================
**     Variables Globales del Programa
** ===================================================================
*/
uint16_t Rate=TICKER_RATE/2;    // Velocidad de barrido (500us = 0.5ms)
uint16_t counter=250;           // Cuenta inicial de 250us
uint16_t heartbeat;             // Contador de Overrunig
/*
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|  Definición de Funciones Prototipo y Rutinas de los Vectores de Interrupción
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
void Setup(void);                   // Rutina de Inicialización para el Hardware
void Caratula(void);                // Carátula de Bienvenida
void Ticker_OnInterrupt(void);      // Rutina de Atención para el Ticker
void Buzzer_Beep(void);             // Pitidos del Buzzer
void I2C_Scanner(void);             // Busca dispositivos conectados al bus I2C
void Test_LCD(void);                // Prueba la operación del LCD
void Blinking_Led(void);            // Rutina de Parpadeo del Led monitor
/* END definitions */ 
/*
#===============================================================================
|
|               P R O G R A M A     P R I N C I P A L
|
#=============================================================================== 
*/
int main()
{
//=================== Secuencia  Principal =====================================
  Setup();                  // Inicializa el Hardware
  Caratula();               // Carátula de Bienvenida
  lcd.cls();                // Limpia la Pantalla LCD
//=================== Lazo Principal ===========================================
  while (true)              // El Lazo del Programa principal está aquí !!!
    {
        lcd.cls();
        lcd.locate(0,0);                  
        lcd.printf("Bienvenidos Sean");       // El LCD saluda al Mundo
        lcd.printf("    a la \n");              // y a la          
        lcd.setInvert(ON);      
        lcd.printf("Gloriosa ESIME !\n");       // Gloriosa ESIME ! 
        lcd.setInvert(OFF);
        lcd.locate(0,4);                  
        lcd.printf("Flashings: %d",heartbeat); // Led Flasings Transcurridos
        wait(0.5); 
//        Blinking_Led();                 // Parapadeo del LED por Software                         
    }
}
/* END main */

/*
................................................................................
:  Rutinas de los Vectores de Interrupción
................................................................................
*/
/*
** ===================================================================
**     Vector      :  Ticker_OnInterrupt()
*/
/*!
**     @brief
**         Called after Ticker is done, [Interrupt service/event]
**         and it is enabled: 
**         TimerInt.attach_us(&Ticker_OnInterrupt, TICKER_RATE);
**         the event is enabled and will be executed every  [TICKER_RATE]
**     @param
**         UserDataPtr     - Pointer to the user or
**                           RTOS specific data. The pointer is passed
**                           as the parameter of Init method.
*/
/* ===================================================================*/
void Ticker_OnInterrupt()           // Rutina de Atención al Ticker
{
    counter--;                      // Aquí va la Rutina de Servicio !
    if (!counter)
    {
        led_monitor = !led_monitor; // Parapadeo del LED por Interrupción (Toggle the LED)
        if(led_monitor==0) terminal.printf("Led Toggled %d Times!\r",heartbeat);
        heartbeat++;                // Incrementa el contador de Pulsaciones
        counter = Rate;             // Restablece el contador
    }
}
/* END Events */   
/*
________________________________________________________________________________
|
|  Funciones Prototipo
|_______________________________________________________________________________
*/
                // Las Funciones Prototipo van aquí !
/*
|-------------------------------------------------------------------------------
|     Función     :     Caratula()
|      
|     Descripción :     Rutina que muestra la Carátula de Bienvenida en la  
|                       Terminal Serial
|
|     Parámetros  :     Ninguno
|          
|     Retorna     :     Nada
|-------------------------------------------------------------------------------
*/
void Caratula()                    // Carátula de Bienvenida
{  terminal.printf ("\t\e[1;37;41mInstituto Politecnico Nacional\e[0m\n\r");
  terminal.printf ("\e[1;37;42mESCUELA SUPERIOR DE INGENIERIA MECANICA Y ELECTRICA\e[0m\n\r\v");
  terminal.printf ("\t\e[1;31;40mPrueba \e[1;35;40mde \e[1;33;40mla \e[1;34;40mPantalla \e[1;32;40mLCD \e[0m\n\r\v\v\e[0m");
}
/*
|-------------------------------------------------------------------------------
|     Función     :     Setup()
|      
|     Descripción :     Rutina para inicialización de los puertos y funciones 
|                       de la Bluepill
|
|     Parámetros  :     Ninguno
|          
|     Retorna     :     Nada
|-------------------------------------------------------------------------------
*/
void Setup()                    // Inicialización del Hardware del Sistema
{
    /* Inicia la comunicación la Terminal */ /* 115200 Bauds, 8 bits, 1 stop, N parity */
  terminal.baud(115200);                 // Se inicia la comunicación serial.    
  terminal.printf("Beginig Start Up, Please wait...\n\r"); 
/* Prueba del Buzzer */    
  terminal.printf("Testing Buzzer... \n\r");   
  Buzzer_Beep();
/* Inicialización del Bluetooth */      
  bluetooth.baud(115200);                // Se inicia la comunicación Bluetooth.  
//  bluetooth.scanf("%s", buf);          //Lee un carácter desde el Bluetooth
//  bluetooth.printf("recv: %s", buf);   //Hace eco al Bluetooth
//  terminal.printf("recv: %s\r\n", buf);  //Imprime en la Terminal el caracter recibido
  bluetooth.printf("Bluetooth Starting OK! ... \n\r"); 
  terminal.printf("Bluetooth Starting OK! ... \n\r"); 
/* Configufración del Display LCD */    /* Mucho OjO !!! */
#if LCD_INTERFACE == 1
/* LCD Utilizando el I2C */
  i2c_lcd.frequency(100000);    // Frecuencia de operación para el I2C
  i2c_lcd.start();              // Inicio de operación para el I2C 
  I2C_Scanner();                // Busca Dispositivos I2C conectados al Bus 
  terminal.printf("I2C Initialzed...\n\r");  
#endif
#if LCD_INTERFACE == 2
/* LCD Utilizando el Puerto SPI */
  spi_lcd.frequency(1000000);   // Frecuencia de operación para el SPI = 1MHz
  spi_lcd.format(8,0);          // Número de Bits y Modo de Operación para el SPI
//  SPI1 -> SPIx_C1 |= 0x01;      // Formato de la Trama (LSBFE): 0 = MSB (default), 1= LSB
  SSel=FALSE;                   // Desactiva el Latch del SN74HC595  
  terminal.printf("SPI Initialzed...\n\r");
#endif
/* Prueba de operación de la Interfaz al LCD */
#if LCD_INTERFACE == 1
  terminal.printf("LCD on I2C interface Address: 0x%X, \n\r",I2C_ADDRESS);  
#endif
#if LCD_INTERFACE == 2
  terminal.printf("LCD on SPI interface \n\r"); 
  if ((SPI1 -> SPIx_C1 & 0x01) > 0) terminal.printf ("SPI LSB First \n\r");
  else terminal.printf ("SPI MSB First \n\r");
#endif
/* Prueba de operación del LCD */
  terminal.printf("LCD Test, please wait...\n\r");  
  Test_LCD();                   // Rutina de prueba del LCD
  terminal.printf("LCD Initialized Succesfuly...\n\r");
/* Arranque de la interrupción por el Ticker */  
  terminal.printf("Ticker Starting Now...\n\r"); 
  TimerInt.attach_us(&Ticker_OnInterrupt, TICKER_RATE);   // Le asigna el periodo de interrupción de 1ms (TICKER_RATE=1000)
}  // end of Setup 
/*
|-------------------------------------------------------------------------------
|     Función     :     Test_LCD()
|      
|     Descripción :     Rutina para inicialización del LCD y funciones 
|                       de la Bluepill
|
|     Parámetros  :     Ninguno
|          
|     Retorna     :     Nada
|-------------------------------------------------------------------------------
*/
void Test_LCD()
{
//  lcd.init(TextLCD::LCDDatalength, 4 ); // Configura el LCD en Modo 4 Bits (Modo GPIO)
  lcd.setBacklight(TextLCD::LightOn);            // Enciende la Iluminación de Fondo
  lcd.setCursor(TextLCD::CurOff_BlkOff);         // Apaga el Cursor y Apaga el Parpadeo
  lcd.cls();                            // Limpia la Pantalla LCD
  lcd.locate(0,0);                      // Ubica cursor en Col, Ren
  lcd.printf("Hello World!\n");         // El LCD saluda al Mundo!
  lcd.setInvert(ON);
  lcd.printf("Hola Mundo!\n");          // El LCD saluda al Mundo!
  lcd.setInvert(OFF);
  lcd.printf("Ciao Mondo!\n");          // El LCD saluda al Mundo!
  lcd.setInvert(ON);
  lcd.printf("Bonjour le Monde");       // El LCD saluda al Mundo!
  wait(5); 
  lcd.cls();                            // Limpia el Display LCD
  lcd.setCursor(TextLCD::CurOn_BlkOn);           // Cursor Encendido, Parpadeo Encendido
  terminal.printf("TextLCD Enhanced Test. Columns=%d, Rows=%d\n\r", lcd.columns(), lcd.rows());   
  Timer Elpased_Time;                   // Inicializa el Tiempo a Transcurrir
  Elpased_Time.start();                 // Comienza a contar el tiempo transcurrido
  for (int row=0; row<lcd.rows(); row++)// Prueba toda la Pantalla
  {
    int col=0;      
    terminal.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row)); 
    lcd.putc('0' + row);                 // Enumera los renglones
    for (col=1; col<lcd.columns()-1; col++) 
    {    
      lcd.putc('*');                    // Llena la linea con el carácter "*"
    }
  terminal.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));      
  lcd.putc('+');                        // Al final de la línea agrega el "+"
  }  
  Elpased_Time.stop();                  // Detiene el Contador de Ticks
  terminal.printf("All my hard work took %f sec\r\n", Elpased_Time.read()); // Calcula el tiempo transcurrido
  wait(1);                              // Espera por 1 segundo  
  terminal.printf("LCD Display and TextLCD Enhanced Test Completed.\n\r");
  wait(1);                              // Espera 1 segundo
  lcd.cls();                            // Limpia la Pantalla
//  lcd.setBacklight(TextLCD::LightOff);  // Apaga la Iluminación de Fondo  
  lcd.setCursor(TextLCD::CurOff_BlkOn);          // Apaga el Cursor y Enciende el Parpadeo
// Set and show user defined characters. A maximum of 8 UDCs are supported by the HD44780.
// They are defined by a 5x7 bitpattern. 
  lcd.setUDC(0, (char *) udc_0);        // Selecciona el caracter para el cursor |>
  lcd.putc(0);                          // Lo imprime en la Pantalla LCD
  lcd.printf(" LCD Ready... ");         // El LCD está listo para usarse  
  wait(2);                              // Espera 2 segundos
  lcd.setCursor(TextLCD::CurOff_BlkOff);         // Apaga el Cursor y Apaga el Parpadeo      
  terminal.printf("LCD Starting OK! ... \n\r");
}   // end of Test_LCD

/*
|-------------------------------------------------------------------------------
|     Función     :     Buzzer_Beep()
|      
|     Descripción :     Rutina para prueba del Buzzer
|
|     Parámetros  :     Ninguno
|          
|     Retorna     :     Nada
|-------------------------------------------------------------------------------
*/
void Buzzer_Beep()                      // Software routine for Buzzer Beep
{
//  terminal.printf("Testing Buzzer... \n\r");
  buzzer = BUZZ_ON;
  wait_ms(750);
  buzzer = BUZZ_OFF;
  wait_ms(125);
  buzzer = BUZZ_ON;
  wait_ms(250);
  buzzer = BUZZ_OFF;   
  wait_ms(125);
  buzzer = BUZZ_ON;
  wait_ms(500);
  buzzer = BUZZ_OFF;
//  terminal.printf("Buzzer OK ! \n\r");
}  
/*
|-------------------------------------------------------------------------------
|     Función     :     Blinking_Led()
|      
|     Descripción :     Rutina de parpadeo del Led por software
|
|     Parámetros  :     Ninguno
|          
|     Retorna     :     Nada
|-------------------------------------------------------------------------------
*/
void Blinking_Led()             // Software Blinking routine for LED 
{
        // The on-board LED is connected, via a resistor, to +3.3V (not to GND). 
        // So to turn the LED on or off we have to set it to 0 or 1 respectively
        led_monitor = 0;        // turn the LED on
        wait_ms(200);           // 200 millisecond
        led_monitor = 1;        // turn the LED off
        wait_ms(1000);          // 1000 millisecond
}
/*
|-------------------------------------------------------------------------------
|     Función     :     I2C_Scanner()
|      
|     Descripción :     Rutina de parpadeo del Led por software
|
|     Parámetros  :     Ninguno
|          
|     Retorna     :     Nada
|-------------------------------------------------------------------------------
*/
void I2C_Scanner()
{     
#if LCD_INTERFACE == 1
  terminal.printf ("I2C scanner. Scanning ...");
  uint8_t count = 0;
  char     test[] = { 0b00000000, 0b00000000, // RS=0, EN=1,0, LED+=1, NC, DB4=DB5=DB6=DB7=0 en datos
                      0b01101100, 0b00101100, // RS=0, EN=1,0, LED+=1, NC, DB4=DB5=1 en datos,
                      0b01101100, 0b00101100, // RS=0, EN=1,0, LED+=1, NC, DB4=DB5=1 en datos,
                      0b01101100, 0b00101100, // RS=0, EN=1,0, LED+=1, NC, DB4=DB5=1 en datos, 
                      0b01100100, 0b00100100, // RS=0, EN=1,0, LED+=1, NC, DB5=1 en datos,
                      0b01100100, 0b00100100, // RS=0, EN=1,0, LED+=1, NC, DB5=1 en datos, 
                      0b01100110, 0b00100001, // RS=0, EN=1,0, LED+=1, NC, DB7=N=1 2 líneas, DB6=F=0 5x7puntos,
                      0b01100000, 0b00100000, // => Display ON/OFF Control.
                      0b01100001, 0b00100001, // RS=0, EN=1,0, LED+=1, NC, DB7=1 (Display off, cursor off, blink off)
                      0b01100000, 0b00100000, // => Display Clear.
                      0b01101000, 0b00101000};// RS=0, EN=1,0, LED+=1, NC, DB4=1 en datos, (Cursor Home};  // Patrón de Prueba

//  char     test[] = {0x55,0xAA,0x0F,0xF0,0xFF,0x00};// Patrón de Prueba    
  i2c_lcd.frequency(100000);    // Frecuencia de operación para el I2C (100KHz)
  i2c_lcd.start();              // Inicio de operación para el I2C  
  for (int i = 8; i < 128; i++)
  {
    uint8_t acknoledge = i2c_lcd.write (i,test,22,1);    //(dirección, ap_datos, N°_datos, repetición) 
    if (acknoledge == 0)
      {
      terminal.printf ("\n\rFound address: ");
      terminal.printf ("%u DEC",i);         // Valor de la dirección en Decimal
      terminal.printf (" (0x%x HEX)\n\r",i);// Valor de la dirección en Hexadecimal
      char data = i2c_lcd.read (i);         // Lee el dato en la dirección       
      terminal.printf ("Data: (0x%hd HEX)\n\r",data);  // Valor del último dato en la dirección en Hexadecimal
      count++;

      wait (1);                             // maybe unneeded?
      }                                     // end of good response
      led_monitor = !led_monitor;           // Parapadeo del LED       
  }                                         // end of for loop
  led_monitor = 1;                          // Apaga el LED
  i2c_lcd.stop();                           // Fin de operación para el I2C    
  terminal.printf ("\n\rDone.\n\r");
  terminal.printf ("Found %d Device(s)\n\r",count);
#endif 
}  // end of I2C_Scanner                

/* END Program */

/*+-----------------------------------------------------------------------------       
*+ Direccinamiento de la RAM del Display:
*+ 
*+ Los módulos de 8x1 (obsoletos) están arreglados como una líneas de 
*+ 8 caracteres de lada a lado.
*+  "Linea 1" Las direcciones comienzan en 80h a 87h
*+
*+ Los módulos de 16x1 están arreglados como dos líneas de 8 caracteres de lada a lado.
*+  "Linea 1" Las direcciones comienzan en 80h a 87h (primera parte de la línea)
*+  "Linea 1" Las direcciones comienzan en C0h a C7h (segunda parte de la línea)
*+  de manera que al escribir caracteres al módulo, el cursor se incrementará automaticamente
*+  hasta alcanzar el 9° caracter entonces tendrá que mover el cursor a la dirección C0h antes
*+  de escribir el 9° caracter en el módulo de 1x16.
*+  
*+  Módulo de 16x2 es dos líneas por 16 caracteres
*+  "Linea 1" Las direcciones comienzan en 80h a 8Fh
*+  "Linea 2" Las direcciones comienzan en C0h a CFh
*+
*+  Módulo de 16x4 
*+  "Linea 1" Las direcciones comienzan en 80h a 8Fh
*+  "Linea 2" Las direcciones comienzan en C0h a CFh
*+  "Linea 3" Las direcciones comienzan en 90h a 9Fh
*+  "Linea 4" Las direcciones comienzan en D0h a DFh
*+    
*+  Módulo de 20x1 
*+  "Linea 1" Las direcciones comienzan en 80h a 93h
*+  
*+  Módulo de 20x2 
*+  "Linea 1" Las direcciones comienzan en 80h a 93h
*+  "Linea 2" Las direcciones comienzan en C0h a D3h
*+  
*+  Módulo de 20x4 
*+  "Linea 1" Las direcciones comienzan en 80h a 93h
*+  "Linea 2" Las direcciones comienzan en C0h a D3h
*+  "Linea 3" Las direcciones comienzan en 94h a A7h
*+  "Linea 4" Las direcciones comienzan en D4h a E7h
*+  
*+  Módulo de 24x2 
*+  "Linea 1" Las direcciones comienzan en 80h a 98h
*+  "Linea 2" Las direcciones comienzan en C0h a D8h
*+  
*+  Módulo de 32x2 
*+  "Linea 1" Las direcciones comienzan en 80h a A0h
*+  "Linea 2" Las direcciones comienzan en C0h a E0h
*+
*+  Módulo de 40x2 
*+  "Linea 1" Las direcciones comienzan en 80h a A7h
*+  "Linea 2" Las direcciones comienzna en C0h a E7h
*+ 
*+
*+--------------------------------------------------------------------------- */ 

/*+-----------------------------------------------------------------------------
*+ Inicializaci¢n del Display de Cristal Líquido Alfanumérico en modo de 4 bits
*+
*+ Definici¢n de pines:
*+                            __      Vdd GND
*+             MOSI MISO SCK SS       |   |    
*+               |   |   |   |       10K  |   
*+               |   |   |   |        |   |    
*+ CD 4094     DATA NC CLOCK STROBE  NC  OE  QS  ---> DATA en la siguiente etapa
*+ 74HC 595     SER NC SCLK RCLK    SCLR  G  QH' ---> SER en la siguiente etapa
*+
*+ CD 4094      Q1  Q2  Q3  Q4   Q5  Q6  Q7  Q8
*+ 74HC 595     QA  QB  QC  QD   QE  QF  QG  QH
*+               |   |   |   |    |   |   |   |
*+               |   |   |   |    |   |   |   |               
*+ HD44780      R/S  RW  E  BL   DB4 DB5 DB6 DB7 
*+
*+ Notas: El pin RW del LCD debe estar estar siempre en "L" o conectado a GND.
*+        El pin E2 es usado solo para el LCD40x4 (segundo controlador)
*+        La señal BL = LED+ y debe ser usado para control del Backlight
*+        Para enviar cualquier dato o instrucci¢n hay que hacer una   _
*+        transici¢n de bajo a alto en el pin de E (Enable) del LCD. _| |_
*+
*+------------------------------------------------------------------------------
*+
*+ Ubicaciónn de pines:
*+      ---------------------------------------------------------------------
*+      |  _______________________________________________________________  |
*+      | |                                                               | |
*+      | |                                                               | |
*+      | |                                                               | |
*+      | |                                                               | |
*+      | |                                                               | |
*+      | |                                                               | |
*+      | |_______________________________________________________________| |
*+      |                                                                   |
*+      ---------------------------------------------------------------------
*+                          |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
*+                          |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
*+                          16 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1
*+
*+   1   Vss - GND
*+   2   Vdd - Vcc
*+   3   Vee - Ajuste de contraste
*+   4   RS  - (Register/String) 0=Entrada de Instrucción, 1=Entrada de Dato 
*+   5   RW  - Lectura/Escritura 0=Escribe al LCD, 1=Lee del LCD
*+   6   E   - Señal de Habilitación  "101"
*+   7   DB0 - Línea 0 del bus de datos
*+   8   DB1 - Línea 1 del bus de datos
*+   9   DB2 - Línea 2 del bus de datos
*+   10  DB3 - Línea 3 del bus de datos  _
*+   11  DB4 - Línea 4 del bus de datos   |
*+   12  DB5 - Línea 5 del bus de datos    \  Operación en 4 bits
*+   13  DB6 - Línea 6 del bus de datos    / 
*+   14  DB7 - Línea 7 del bus de datos  _|
*+   15  LED+  Ánodo  Backlight
*+   16  LED-  Cátodo Backlight 
*+
*+------------------------------------------------------------------------------                                 
*+
*+  +5V ------------*----------- Vcc          PTE19 PTE18 PTE20 PTE21 PTE22 PTE23                
*+                  |                           RS    E    D4    D5    D6    D7 
*+                  /
*+          10k to  \<---------- Vee          R/W ---> GND  
*+          20k pot /                         A   ---> PWM1 o   R=330 ---> Vcc
*+                  \                         K   ---> GND
*+                  |
*+  GND ------------*----------- Vss
*+
*+------------------------------------------------------------------------------
*+      
*+ Definici¢n de bits:
*+
*+ I/D=1:   (Increment/Decrement) Incremento (+) del Cursor
*+ I/D=0:   (Increment/Decrement) Decremento (-) del Cursor
*+ D=0:     (Display) Apaga el Display
*+ D=1:     (Display) Enciende el Display
*+ C=0:     (Cursor) Apaga el Cursor
*+ C=1:     (Cursor) Enciende el Cursor
*+ B=0:     (Blinking) Apaga el parpadeo del Cursor
*+ B=1:     (Blinking) Enciende el parpadeo del Cursor
*+ S=0:     (Shift) Sin corrimiento del Display
*+ S=1:     (Shift) Con corrimiento del Display
*+ S/C=1:   (Shift/Cursor) Con corrimiento del Display
*+ S/C=0:   (Shift/Cursor) Con Movimiento del Cursor
*+ R/L=1:   (Right/Left) Corrimiento a la Derecha
*+ R/L=0:   (Right/Left) Corrimiento a la Izquierda
*+ DL=1:    (Data Lenght) 8 Bits de datos
*+ DL=0:    (Data Lenght) 4 Bits de datos
*+ N=1:     (Number Lines) Modo de 2 Líneas de despliege
*+ N=0:     (Number Lines) Modo de 1 Línea de despliege
*+ F=1:     (Font) 5X10 Puntos por caracter
*+ F=0:     (Font) 5X7 Puntos por caracter
*+ BF=1:    (Busy Flag) Operación interna en proceso
*+ BF=0:    (Busy Flag) Listo para aceptar instrucciones/datos
*+ DDRAM:   (Display Data Ram)
*+ CGRAM:   (Character Generator RAM)
*+ ACC:     Address of CGRAM
*+ ADD:     Address of DDRAM These correspond to curser addresses.
*+ AC:      Address counter used for both DDRAM and CGRAM
*+
*+                              RS RW  MSB                         LSB 
*+ Clear Display                0  0    0   0   0   0   0   0   0   1
*+ Cursor at Home               0  0    0   0   0   0   0   0   1   0
*+ Entry Mode Set               0  0    0   0   0   0   0   1  I/D  S
*+ Display ON/OFF control       0  0    0   0   0   0   1   D   C   B
*+ Cursor/Display Shift         0  0    0   0   0   1  S/C R/L  x   x
*+ Function Set                 0  0    0   0   1   DL  N   F   x   x
*+ CGRAM                        0  0    0   1   -------- ACC --------
*+ DDRAM                        0  0    1   ---------- ADD ----------
*+ Busy Flag/Address Read       0  1    1   -----------AC------------
*+ CGRAM/CDDRAM Data Write      1  0            Write Data
*+ CGRAM/CDDRAM Data Read       1  1            Read  Data
*+
*+
*+ Tiempos de Ejecución:
*+ Dependiendo del Oscilador Interno del LCD los tiempos de ejecución de las 
*+ instrucciones pueden variar.
*+                                          Fosc
*+   INSTRUCCION            160Khz          250Khz          270Khz
*+   Clear Display          120us~4.9ms     82us~1.6ms      40us~1.5ms
*+   Cursor Home            120us           40~1.6ms        37us~1.5ms
*+   Todas las demás        120us           40us            37us
*+   Lectura/Escritura      120us           40us            37us
*+   Lectura de Busy Flag   1us             1us             1us

*+   El controlador podría estar en modo de 8 bits (reinicio de encendido)
*+   o en modo de 4 bits (reinicio en caliente) en este punto.
*+   Siga este procedimiento para asegurarse de que el controlador entre en el
*+   estado correcto. 
*+
*+******************************************************************************
*+// Patrón de Configuración del LCD  en modo de 4 bits (LSN first)
*+******************************************************************************
*+   char init_LCD[] = {0b00000000, 0b00000000, // Datos en DB7=DB6=DB5=DB4=0, LED+=0, EN=0,RW=0,RS=0   
*+                      0b00111110, 0b00111010, // Datos en DB5=DB4=1, LED+=1, EN=1,0,RW=1,RS=0
*+                      0b00111110, 0b00111010, // Datos en DB5=DB4=1, LED+=1, EN=1,0,RW=1,RS=0
*+                      0b00111110, 0b00111010, // Datos en DB5=DB4=1, LED+=1, EN=1,0,RW=1,RS=0 
*+                      0b00101110, 0b00100010, // Datos en DB5=1, LED+=1, EN=1,0,RW=1,RS=0                       
*+                      0b00101110, 0b00100010, // => Function Set Control: DB5=1, LED+=1, EN=1,0,RW=1,RS=0 
*+                      0b10001110, 0b10001110, // => Function Set Control: DB7=N=1 2 líneas, DB6=F=0 5x7puntos, LED+=1, EN=1,0,RW=1,RS=0
*+                      0b00001110, 0b00000010, // => Display ON/OFF Control: DB7=DB6=DB5=DB4=0, LED+=1, EN=1,0,RW=1,RS=0 
*+                      0b00101110, 0b00100010, // => Display ON/OFF Control: DB7=1 (Display off, cursor off, blink off),LED+=1, EN=1,0,RW=1,RS=0
*+                      0b00001110, 0b00000010, // => Display Clear: DB7=DB6=DB5=DB4=0, LED+=1, EN=1,0,RW=1,RS=0 
*+                      0b00011110, 0b00010010, // => Display Clear: D4=1, LED+=1, EN=1,0,RW=1,RS=0
*+                      0b00001110, 0b00000010, // => Cursor Home: DB7=DB6=DB5=DB4=0, LED+=1, EN=1,0,RW=1,RS=0                                          
*+                      0b00101110, 0b00100010, // => Cursor Home: DB5=1, LED+=1, EN=1,0,RW=1,RS=0 , (Cursor Home};
*+                      0b01001111, 0b00001011, // => Text 0x48: DB5=1, LED+=1, EN=1,0,RW=1,RS=1                                          
*+                      0b10001111, 0b00101011, // => Text "H" : DB7=1, LED+=1, EN=1,0,RW=1,RS=1 , (ASCII "H"}
*+                      0b01101111, 0b01101011, // => Text 0x6F: DB5=1, LED+=1, EN=1,0,RW=1,RS=1
*+                      0b11111111, 0b11111011, // => Text "o" : DB7=DB6=DB5=DB4=1, LED+=1, EN=1,0,RW=1,RS=1 , (ASCII "o"}
*+                      0b01101111, 0b01101011, // => Text 0x6C: DB6=DB5=1, LED+=1, EN=1,0,RW=1,RS=1                                          
*+                      0b11001111, 0b11001011, // => Text "l" : DB7=DB6=1, LED+=1, EN=1,0,RW=1,RS=1 , (ASCII "l"}
*+                      0b01101111, 0b01101011, // => Text 0x61: DB6=DB5=1, LED+=1, EN=1,0,RW=1,RS=1                                          
*+                      0b00011111, 0b00011011, // => Text "a" : DB4=1, LED+=1, EN=1,0,RW=1,RS=1 , (ASCII "a"}
*+                      0b00101111, 0b00101011, // => Text 0x21: DB5=1, LED+=1, EN=1,0,RW=1,RS=1                                          
*+                      0b00011111, 0b00011011};// => Text "!" : DB4=1, LED+=1, EN=1,0,RW=1,RS=1 , (ASCII "!"}
*+
*+   La interfaz de hardware entre el MCU y la LCD  en modo de 8 bits solo puede 
*+   recibir los 4 bits más significativos (Nibble más significativo, MSN) 
*+   como instrucción para cambier a modo 4.
*+   En el modo de 4 bits, la pantalla LCD espera el MSN primero, seguido del LSN.
*+----------------------------------------------------------------------------*
*+
*+   Powered by
*+
*+          T H E     A N T U L I U ' S   T E A M   R&D  Unltd 
*+
*+  Research, Development, Systems, Equipment, Support & Spare Parts.
*+  (C) Copyright 1989-2019, All Rights Reserved            
*+
*+  Welcome to The Beaners Proyect Community!                   
*+----------------------------------------------------------------------------*/

/* END Mbed */