Módulo LCD



Éste es el primer módulo del hexápodo, el "prototipo" del módulo LCD con 3 pulsadores y un potenciometro que se usará para comunicarse con él de manera autónoma. Ha sido el primero de los distintos módulos que se ha hecho, se utilizará para construir el resto y comprobar su correcto funcionamiento. Sólo lleva cargado un programa que permite seleccionar entre varios "programas/funciones" para que ejecute el micro, de esta forma podemos tener todos los programas que hagamos para probar la distinta electrónica del hexápodo cargados en el micro y ordenados, así no tenemos que estar cargando el programa cada vez que queramos probar un componente. El único programa que lleva de momento es el del anterior ejemplo de leer el potenciometro.

Respecto al programa sólo anotar el uso de las variables compartidas  del main/funciones junto con la ISR, cuando usemos una variable global en el main() y accedamos a ella en las ISRs, debemos declarar esta variable como "volatile", indicandole al compilador que almacene la variable siempre y sólo en el mismo sitio (que no ponga copia en los registros) de tal forma que siempre la ISR y las funciones que las usen lean el valor actualizado de la variable (que la ISR no la modifique en un registro y la función la lea en otro no actualizado), bueno para explicar bien esto tengo que mirarme como se distribuye y usa la memoria para saber donde colocar correctamente las variables.

Otro punto a tener en cuenta es cuando operamos con variables mayores de 8 bits en nuestra función y en la ISR (variables que hemos declarado como volatile según lo anterior), al ser un micro de 8 bits leemos y escribimos en pasos de 8 bits, si accedemos a una variable de mas de 8 bits y antes de terminar de operar con ella la ISR la modifica pues tendremos un valor desconocido de la variable con bytes actualizados por la ISR y los que hayamos leído antes de la ISR sin actualizar. Por lo que cuando tengamos que operar con una variable mayor de 8 bits que pueda ser modificada por la ISR hay que deshabilitar las interrupciones, hacer la operación y después volver a habilitarlas. La mejor forma de hacerlo es guardar el registro SREG, hacer un cli(); y restaurar el registro SREG, de esta manera si las interrupciones no estaban habilitadas antes  pues no las activaremos que sería el caso si usasemos cli(); y sei();. Con ciertas operaciones ("test and set") y variables de 8 bits también hay que hacer lo anterior. Recomiendo los foros de AVRfreaks.net, están llenos de tutoriales donde explican estas cosas.

He tenido que limpiar los flags de la interrupción a mano, tenía el problema de que algunas veces al salir de la interrupción se volvía a entrar en ésta (lo hacía una de cada 4 veces mas o menos) como si de un rebote se tratase. Por lo que tenía entendido al salir de la ISR el compilador limpiaba el flag y así lo hacía la mayoría de las veces.., la solución ha sido limpiarlo a mano al final de cada ISR y desaparecer el problema de pulsar una tecla y saltar dos espacios.

Por último tengo que leerme algo de como ordenar el código ya que el programa del hexápodo va a ser muy largo y tendré que crear varios .c y .h, así que tengo que ver cuál es la mejor forma de gestionar programas grandes que desconozco totalmente.

Me dejo aquí el código del programa para tenerlo a mano y el video del funcionamiento, el programa voy escribiendo y probando y si funciona pues todo bien, según vaya conociendo los AVR ya intentaré hacer las cosas bien, de momento estos micros me están pareciendo una maravilla y es muy fácil empezar con ellos con sólo leer lo que hay por internet.

Esto es lo que llevo usado de memoria:

AVR Memory Usage
----------------
Device: atmega1280

Program:    5126 bytes (3.9% Full)
(.text + .data + .bootloader)

Data:        361 bytes (4.4% Full)
(.data + .bss + .noinit)


Build succeeded with 0 Warnings...

Aquí cabe mucho código...

//Módulo LCD Hexápodo.

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>

#define Bus_Datos PORTK
#define Bus_Control PORTF
#define RS  PORTF5
#define RW  PORTF6
#define E   PORTF7

//Comandos situar el cursor inicio línea.
#define DDRA_LINEA1 0x80    //1000 0000
#define DDRA_LINEA2 0xC0    //1100 0000
#define DDRA_LINEA3 0x94    //1001 0100
#define DDRA_LINEA4 0xD4     //1101 0100

//Botones del LCD, interrupciones externas.
//#define boton1 PORTD2   //INT2
//#define boton2 PORTD3   //INT3
//#define boton3 PORTE4      //INT4
//#define Potenciometro PORTF0  //ADC0

void lcd_comando(unsigned char comando);
void lcd_escribir_c(char caracter);
void lcd_escribir(char *cadena);
void posicionar_cursor(unsigned char x, unsigned char y) ;
void escribir_valor_decimal(unsigned char registro);
void escribir_registro(unsigned char registro);
void valor_real(unsigned char registro);
void lcd_inicializar();

//****************** Programas *******************************/

void programa0();
void programa1();
void programa2();
void programa3();
void programa4();
void programa5();
void programa6();
void programa7();
void programa8();
void programa9();

//****************** Variables Globales *********************//

volatile unsigned char estado;
unsigned char copia_estado;

volatile unsigned char cuenta_tecla;
unsigned char copia_cuenta_tecla;
unsigned char ultima_cuenta_tecla;

volatile unsigned char pantalla0=1;
volatile unsigned char pantalla1=1;
volatile unsigned char pantalla2=1;

unsigned char copia_pantalla0=1;
unsigned char copia_pantalla1=1;
unsigned char copia_pantalla2=1;

//**********************************************/

int main(void)
{
    lcd_inicializar();    //Inicializar módulo lcd.

    char linea1[]="Hexapodo FireFly";
    char linea2[]="www.jmnlab.com";
    char linea3[]="Pulse el boton1 para";
    char linea4[]="comenzar";

    posicionar_cursor(1,3);
    lcd_escribir(linea1);
    posicionar_cursor(2,4);
    lcd_escribir(linea2);
    posicionar_cursor(3,1);
    lcd_escribir(linea3);
    posicionar_cursor(4,7);
    lcd_escribir(linea4);

    while(1)
    {
   
        switch(estado)
        {
            case 0:
            {
                programa0();   
            }break;

            case 1:
            {
                programa1();
            }break;

            case 2:
            {
                programa2();
            }break;

            case 3:
            {
                programa3();
            }break;

            case 4:
            {
                programa4();
            }break;

            case 5:
            {
                programa5();
            }break;

            case 6:
            {
                programa6();
            }break;

            case 7:
            {
                programa7();
            }break;

            case 8:
            {
                programa8();
            }break;

            case 9:
            {
                programa9();
            }break;

            default:break;
        }

    }
}

/**********************************************************************************************************************/
/********************************** Configurar y escribir en el LCD ***************************************************/
/**********************************************************************************************************************/
void lcd_comando(unsigned char comando)
{
    Bus_Control &= ~(1<<RS);    //RS0
    Bus_Control &= ~(1<<RW);    //RW0
    Bus_Datos  = comando;        //Comando
    Bus_Control |= (1<<E);
    _delay_ms(5);
    Bus_Control &= ~(1<<E);
    _delay_ms(5);
}

void lcd_escribir_c(char caracter)
{
    Bus_Control |= (1<<RS);        //RS1
    Bus_Control &= ~(1<<RW);    //RS0
    Bus_Datos = caracter;       
    Bus_Control |= (1<<E);
    _delay_ms(5);
    Bus_Control &= ~(1<<E);
    _delay_ms(5);
}

void lcd_escribir(char *cadena)
{
    char *inicio = cadena;
    unsigned char i=0;
    for(i=0;((inicio[i]!='\0')&&(i<20));i++)
    {
        Bus_Control |= (1<<RS);    //RS0 RW0 caracter
        Bus_Control &= ~(1<<RW);
        Bus_Datos  = inicio[i];       
        Bus_Control |= (1<<E);
        _delay_ms(5);        
        Bus_Control &= ~(1<<E);
        _delay_ms(5);               
    }
}

void posicionar_cursor(unsigned char x, unsigned char y) //línea 1 a 4, columna de 1 a 20.
{
    unsigned char comando=DDRA_LINEA1;
    switch(x)
    {
        case 1:
        {
            comando=DDRA_LINEA1+y-1;
        }break;

        case 2:
        {
            comando=DDRA_LINEA2+y-1;
        }break;

        case 3:
        {
            comando=DDRA_LINEA3+y-1;
        }break;

        case 4:
        {
            comando=DDRA_LINEA4+y-1;
        }break;

        default:break;
    }

        lcd_comando(comando);
}
/**********************************************************************************************************************/
/****************************************** ISR's *********************************************************************/
/**********************************************************************************************************************/
ISR(INT2_vect)
{
    switch(estado)
    {
        case 0:
        {
            cuenta_tecla++;
            if(cuenta_tecla>9)
                cuenta_tecla=9;
        }break;

        default:break;
    }

    _delay_ms(200);    //Rebotes
    EIFR |=(1<<INT2);
}

ISR(INT3_vect)
{
    switch(estado)
    {
        case 0:
        {
            cuenta_tecla--;
                if(cuenta_tecla<1)
                cuenta_tecla=1;
        }

        default:break;
    }

    _delay_ms(200);    //Rebotes
    EIFR |=(1<<INT3);
}

ISR(INT4_vect)
{
    pantalla0=1;
    pantalla1=1;
    pantalla2=1;

    if (estado==0)
    {
        estado=cuenta_tecla;
        ultima_cuenta_tecla=cuenta_tecla;
    }
    else
    {
        estado=0;
        cuenta_tecla=ultima_cuenta_tecla;
    }
    _delay_ms(200);    //Rebotes
    EIFR |=(1<<INT4);
}

ISR(ADC_vect)
{

}
/**********************************************************************************************************************/
/*************************************** Funciones Manipular Registros LCD ********************************************/
/**********************************************************************************************************************/
void escribir_registro(unsigned char registro) //Escribir registro LCD.
{
    unsigned char mascara = 0b10000000;
    unsigned char cont=0;
    for(cont=0;cont<8;cont++)
    {
        if((registro & mascara)==0)
            lcd_escribir_c('0');
        else
            lcd_escribir_c('1');
//        mascara>>1;
        mascara = mascara/2;
    }
}

void escribir_valor_decimal(unsigned char registro) //Escribir binario a decimal.
{
    char centenas = 0;
    char decenas = 0;
    char unidades = 0;

    while(registro>=100)
    {
        registro= registro -100;
        centenas++;
    }
    while(registro>=10)
    {
        registro=registro -10;
        decenas++;
    }
    while(registro>0)
    {
        registro=registro-1;
        unidades++;
    }   
    lcd_escribir_c(centenas | 0b00110000);
    lcd_escribir_c(decenas | 0b00110000);
    lcd_escribir_c(unidades | 0b00110000);
}

void valor_real(unsigned char registro) //Escribir valor binario a analógico LCD, Vref 5V, 8 bits.
{
    unsigned int v_real = (int)registro;
    char unidades = 0;
    char decimas = 0;
    char centesimas = 0;
    v_real=v_real*195;
    while(v_real>10000)
    {
        v_real=v_real - 10000;
        unidades++;
    }

        while(v_real>1000)
    {
        v_real=v_real - 1000;
        decimas++;
    }

        while(v_real>100)
    {
        v_real=v_real - 100;
        centesimas++;
    }
    lcd_escribir_c(unidades | 0b00110000);
    lcd_escribir_c('.');
    lcd_escribir_c(decimas | 0b00110000);
    lcd_escribir_c(centesimas | 0b00110000);
    lcd_escribir_c('V');
}
/**********************************************************************************************************************/
/**************************** Inicializar el Módulo LCD ***************************************************************/
/**********************************************************************************************************************/
void lcd_inicializar()       
{
    /************************************************************///LCD
    DDRK=0xFF;     //1111 1111
    PORTK=0x00;   
    DDRF|=((1<<RS)|(1<<RW)|(1<<E));     //1110 0000
    PORTF &= ~(1<<E); 
    _delay_ms(100);                   
    lcd_comando(0x3C);    //Function Set RS0 RW0 0011 NF** 0011 1100 C
    lcd_comando(0x3C);    //Function Set
    lcd_comando(0x0C);    //Display ON/OFF Control RS0 RW0 00001DCB 0000 1100 c
    lcd_comando(0x01);    //Display Clear RS0 RW0 00000001
    lcd_comando(0x06);    //Entry Mode Set RS0 RW0 000001I/DS 0000 0111
    /************************************************************///ADC
    ADMUX |=(1<<REFS0);    //Tensión de referencia AVCC 5 voltios.
    ADMUX |=(1<<ADLAR);    //8 bits de resolución.
                        //Canal ADC por defecto ADC0, no tenemos que cambiarlo.
    ADCSRA |=(1<<ADATE);//Habilitamos el Free Running Mode, por defecto seleccionado
    ADCSRA |=((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));  //Prescaler 128, Fadc 125 KHz @ 16MHz.
    DIDR0 |=(1<<ADC0D); //Apagamos la parte digital del puerto.
    ADCSRA |= (1<<ADIE);//Enable ADC Interrupt
    ADCSRA |= (1<<ADEN);//Enable ADC
    /************************************************************///Botones
    //configurar registros interrupciones.
    //Tipo de evento que dispará la interrupción, 10, flanco de bajada.
    EICRA &= ~(1<<ISC20);    //INT2
    EICRA |= (1<<ISC21);
    EICRA &= ~(1<<ISC30);    //INT3
    EICRA |= (1<<ISC31);
    EICRB &= ~(1<<ISC40);    //INT4
    EICRB |= (1<<ISC41);
    //Habilitar interrupciones externas
    EIMSK |= ((1<<INT2)|(1<<INT3)|(1<<INT4));
    //Habilitar todas las interrupciones
    sei();   
}
/**********************************************************************************************************************/
void programa0()
{
    //Selección de programa.
    char linea5[]="Seleccione Programa:";
    char linea6[]="Leer Potenciometro";
    char linea7[]="Servomotor";
    char linea8[]="Sensor U. I2C";
    char linea9[]="S. Infrarrojo";
    char linea10[]="PWM Led RGB";
    char linea11[]="Comunicacion PC";
    char linea12[]="Comunicacion SPI";
    char linea13[]="Controladora 24 S.";
    char linea14[]="Control Bateria";

    ADCSRA &= ~(1<<ADEN);    //Apagar ADC.
    ADCSRA &= ~(1<<ADSC);


while(estado==0)
{

    cli();
    copia_cuenta_tecla=cuenta_tecla;
    copia_pantalla0=pantalla0;
    copia_pantalla1=pantalla1;
    copia_pantalla2=pantalla2;
    sei();   

    if((copia_cuenta_tecla>0)&&(copia_cuenta_tecla<4)&&(copia_pantalla0==1))
    {
        lcd_comando(0x01);
        lcd_escribir(linea5);
        posicionar_cursor(2,2);
        lcd_escribir(linea6);
        posicionar_cursor(3,2);
        lcd_escribir(linea7);
        posicionar_cursor(4,2);
        lcd_escribir(linea8);

        pantalla0=0;
        pantalla1=1;
        pantalla2=1;
    }

    if((copia_cuenta_tecla>3)&&(copia_cuenta_tecla<7)&&(copia_pantalla1==1))
    {
        lcd_comando(0x01);
        lcd_escribir(linea5);
        posicionar_cursor(2,2);
        lcd_escribir(linea9);
        posicionar_cursor(3,2);
        lcd_escribir(linea10);
        posicionar_cursor(4,2);
        lcd_escribir(linea11);

        pantalla0=1;
        pantalla1=0;
        pantalla2=1;
    }

    if((copia_cuenta_tecla>6)&&(copia_cuenta_tecla<10)&&(copia_pantalla2==1))
    {
        lcd_comando(0x01);
        lcd_escribir(linea5);
        posicionar_cursor(2,2);
        lcd_escribir(linea12);
        posicionar_cursor(3,2);
        lcd_escribir(linea13);
        posicionar_cursor(4,2);
        lcd_escribir(linea14);

        pantalla0=1;
        pantalla1=1;
        pantalla2=0;
    }


    switch(copia_cuenta_tecla)
    {
        case 1:
        {
            posicionar_cursor(2,1);
            lcd_escribir_c(0b01111110);
            posicionar_cursor(3,1);
            lcd_escribir_c(' ');
            posicionar_cursor(4,1);
            lcd_escribir_c(' ');
        }break;

        case 2:
        {
            posicionar_cursor(2,1);
            lcd_escribir_c(' ');
            posicionar_cursor(3,1);
            lcd_escribir_c(0b01111110);
            posicionar_cursor(4,1);
            lcd_escribir_c(' ');
        }break;

        case 3:
        {
            posicionar_cursor(2,1);
            lcd_escribir_c(' ');
            posicionar_cursor(3,1);
            lcd_escribir_c(' ');
            posicionar_cursor(4,1);
            lcd_escribir_c(0b01111110);
        }break;

        case 4:
        {
            posicionar_cursor(2,1);
            lcd_escribir_c(0b01111110);
            posicionar_cursor(3,1);
            lcd_escribir_c(' ');
            posicionar_cursor(4,1);
            lcd_escribir_c(' ');
        }break;

        case 5:
        {
            posicionar_cursor(2,1);
            lcd_escribir_c(' ');
            posicionar_cursor(3,1);
            lcd_escribir_c(0b01111110);
            posicionar_cursor(4,1);
            lcd_escribir_c(' ');
        }break;

        case 6:
        {
            posicionar_cursor(2,1);
            lcd_escribir_c(' ');
            posicionar_cursor(3,1);
            lcd_escribir_c(' ');
            posicionar_cursor(4,1);
            lcd_escribir_c(0b01111110);
        }break;

        case 7:
        {
            posicionar_cursor(2,1);
            lcd_escribir_c(0b01111110);
            posicionar_cursor(3,1);
            lcd_escribir_c(' ');
            posicionar_cursor(4,1);
            lcd_escribir_c(' ');
        }break;

        case 8:
        {
            posicionar_cursor(2,1);
            lcd_escribir_c(' ');
            posicionar_cursor(3,1);
            lcd_escribir_c(0b01111110);
            posicionar_cursor(4,1);
            lcd_escribir_c(' ');
        }break;

        case 9:
        {
            posicionar_cursor(2,1);
            lcd_escribir_c(' ');
            posicionar_cursor(3,1);
            lcd_escribir_c(' ');
            posicionar_cursor(4,1);
            lcd_escribir_c(0b01111110);
        }break;
    }
}
}

/******************************************************************************************************/
/********************** Programa para Leer el Potenciometro del LCD **********************************/
/******************************************************************************************************/
void programa1()
{


    char linea1[]="Reg. ADCH:";
    char linea2[]="Caracter LCD:";
    char linea3[]="Valor Tension:";
    char linea4[]="V. decimal ADCH:";
    char linea5[]="Programa para leer";
    char linea6[]="un Potenciometro";
    char linea7[]="Registro usado ADCH";
    unsigned char contador_anim=0;
    unsigned char copia_ADCH=ADCH;

    cli();
    copia_pantalla0=pantalla0;
    copia_estado=estado;
    sei();


    lcd_comando(0x01);
    posicionar_cursor(1,2);
    lcd_escribir(linea5);
    posicionar_cursor(2,3);
    lcd_escribir(linea6);
    posicionar_cursor(3,1);
    lcd_escribir(linea7);
    posicionar_cursor(4,1);

    for(contador_anim=0;contador_anim<20;contador_anim++)
    {
        lcd_escribir_c('.');
        _delay_ms(100);
    }


       ADCSRA &= ~(1<<ADIE);  //Sin interrupción
     ADCSRA|= (1<<ADEN);    //Comenzar conversiones.
     ADCSRA|= (1<<ADSC);    //Comenzar conversiones.

     lcd_comando(0x01);

     posicionar_cursor(1,1);
     lcd_escribir(linea1);
     posicionar_cursor(3,1);
     lcd_escribir(linea2);
     posicionar_cursor(2,1);
     lcd_escribir(linea4);
     posicionar_cursor(4,1);
     lcd_escribir(linea3);
 
     while(estado==1)
     {
        copia_ADCH=ADCH;
        posicionar_cursor(1,12);
        escribir_registro(copia_ADCH);
        posicionar_cursor(3,15);
        lcd_escribir_c(copia_ADCH);
        posicionar_cursor(2,18);
        escribir_valor_decimal(copia_ADCH);
        posicionar_cursor(4,16);
        valor_real(copia_ADCH);
    }
}
/******************************************************************************************************/
/***************************** Futuro Programa ********************************************************/
/******************************************************************************************************/
void programa2()
{
    char linea[]="Servomotor";
    char linea1[]="No implementado";

    cli();
    copia_pantalla0=pantalla0;
    copia_estado=estado;
    sei();

    if ((copia_pantalla0==1)&&(copia_estado!=0))
    {
        lcd_comando(0x01);
        posicionar_cursor(1,6);
        lcd_escribir(linea);
        posicionar_cursor(3,3);
        lcd_escribir(linea1);
        if(copia_estado==2)
            pantalla0=0;
    }

}
/******************************************************************************************************/
/***************************** Futuro Programa ********************************************************/
/******************************************************************************************************/
void programa3()
{
    char linea[]="Sensor U. I2C";
    char linea1[]="No implementado";

    cli();
    copia_pantalla0=pantalla0;
    copia_estado=estado;
    sei();

    if ((copia_pantalla0==1)&&(copia_estado!=0))
    {
        lcd_comando(0x01);
        posicionar_cursor(1,4);
        lcd_escribir(linea);
        posicionar_cursor(3,3);
        lcd_escribir(linea1);
        if(copia_estado==3)
            pantalla0=0;
    }
}
/******************************************************************************************************/
/***************************** Futuro Programa ********************************************************/
/******************************************************************************************************/
void programa4()
{
    char linea[]="S. Infrarrojo";
    char linea1[]="No implementado";

    cli();
    copia_pantalla0=pantalla0;
    copia_estado=estado;
    sei();

    if ((copia_pantalla0==1)&&(copia_estado!=0))
    {
        lcd_comando(0x01);
        posicionar_cursor(1,4);
        lcd_escribir(linea);
        posicionar_cursor(3,3);
        lcd_escribir(linea1);
        if(copia_estado==4)
            pantalla0=0;
    }
}
/******************************************************************************************************/
/***************************** Futuro Programa ********************************************************/
/******************************************************************************************************/
void programa5()
{
    char linea[]="PWM Led RGB";
    char linea1[]="No implementado";

    cli();
    copia_pantalla0=pantalla0;
    copia_estado=estado;
    sei();

    if ((copia_pantalla0==1)&&(copia_estado!=0))
    {
        lcd_comando(0x01);
        posicionar_cursor(1,5);
        lcd_escribir(linea);
        posicionar_cursor(3,3);
        lcd_escribir(linea1);
        if(copia_estado==5)
            pantalla0=0;
    }
}
/******************************************************************************************************/
/***************************** Futuro Programa ********************************************************/
/******************************************************************************************************/
void programa6()
{
    char linea[]="Comunicacion PC";
    char linea1[]="No implementado";

    cli();
    copia_pantalla0=pantalla0;
    copia_estado=estado;
    sei();

    if ((copia_pantalla0==1)&&(copia_estado!=0))
    {
        lcd_comando(0x01);
        posicionar_cursor(1,3);
        lcd_escribir(linea);
        posicionar_cursor(3,3);
        lcd_escribir(linea1);
        if(copia_estado==6)
            pantalla0=0;
    }
}
/******************************************************************************************************/
/***************************** Futuro Programa ********************************************************/
/******************************************************************************************************/
void programa7()
{
    char linea[]="Comunicacion SPI";
    char linea1[]="No implementado";

    cli();
    copia_pantalla0=pantalla0;
    copia_estado=estado;
    sei();

    if ((copia_pantalla0==1)&&(copia_estado!=0))
    {
        lcd_comando(0x01);
        posicionar_cursor(1,3);
        lcd_escribir(linea);
        posicionar_cursor(3,3);
        lcd_escribir(linea1);
        if(copia_estado==7)
            pantalla0=0;
    }
}
/******************************************************************************************************/
/***************************** Futuro Programa ********************************************************/
/******************************************************************************************************/
void programa8()
{
    char linea[]="Controladora 24 S.";
    char linea1[]="No implementado";

    cli();
    copia_pantalla0=pantalla0;
    copia_estado=estado;
    sei();

    if ((copia_pantalla0==1)&&(copia_estado!=0))
    {
        lcd_comando(0x01);
        posicionar_cursor(1,2);
        lcd_escribir(linea);
        posicionar_cursor(3,3);
        lcd_escribir(linea1);
        if(copia_estado==8)
            pantalla0=0;
    }
}
/******************************************************************************************************/
/***************************** Futuro Programa ********************************************************/
/******************************************************************************************************/
void programa9()
{
    char linea[]="Control Bateria";
    char linea1[]="No implementado";

    cli();
    copia_pantalla0=pantalla0;
    copia_estado=estado;
    sei();

    if ((copia_pantalla0==1)&&(copia_estado!=0))
    {
        lcd_comando(0x01);
        posicionar_cursor(1,3);
        lcd_escribir(linea);
        posicionar_cursor(3,3);
        lcd_escribir(linea1);
        if(copia_estado==9)
            pantalla0=0;
    }
}
/******************************************************************************************************/
/******************************************************************************************************/
/******************************************************************************************************/



Video del funcionamiento:


Para cualquier sugerencia, correción:
blog comments powered by Disqus