terça-feira, 25 de setembro de 2012

Usando display LCD 20X4 com o ATmega328



Configuração e desenho no simulador(clique na imagem para ampliar ):


configuração no avr Studio( tenho o 5 mas o 4 é mais rápido!)



Código fonte:



//************************************************************************
//                             Display 20X4 - com atmega328
//  Version    : 1.0
//  microcontrolador : AVR ATMega328P
//  Autor        : Aguivone
//  descrição  : funcionamento de display 
//  data : 25/09/2012.
//
//************************************************************************
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include <string.h>

/////////////////////////variaveis globais ////////////////////////////////////////////////////////////

char frase[]="12345678912345678912";//vetor de 20 posiçoes

/////////////////////////////////////variaveis usada no lcd ///////////////////////////////////////////
#define LCD PORTC //define qual porta vai usar
//o pino r/w é conectado ao terra pois não é feita nenhuma leitura no display
//configuração:
//
// pino display  / pino da porta selecionada
//
// D4 = bit 0 da porta
// D5 = bit 1 da porta
// D6 = bit 2 da porta
// D7 = bit 3 da porta
//
// RS = bit 4 da porta
// EN = bit 5 da porta
//
/////////////////////////////////////////////////Funções usadas no LCD/////////////////////////////////////////////

void inicializa_LCD(void)
{
    _delay_ms(15);//tempo para estabilizar a tensão e preparar o display
    // o primeiro digito é de controle e o segundo configuração

    LCD = 0X22;//nesse momento o display ainda está em modo 8bits solicita modo de 4 bits
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X02;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);
                // é preciso colocar este comando pelo menos 2 vezes para que funcione o display
    LCD = 0X22;//nesse momento o display  está em modo 4bits 
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X02;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);

    ////////entrou no modo 4bits/////////////////////////////////////

    LCD = 0X28;//nesse momento o display  está em modo 4bits,manda usar 2 linhas 
    _delay_ms(1);//tempo estabilizar o pino
    LCD =0X08;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);

    /////////////////////envia 0X01 - limpar display ////////////////////////////////////
    LCD = 0X20;//manda limpar o display
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X00;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

    LCD = 0X21;//segundo nibble (limpa display)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X01;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

        /////////////////////envia 0X06  - movimento e pisca do display////////////////////////////////////
    
     LCD = 0X20;//manda deslocar a direita (0x06)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X00;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);

     LCD = 0X26;//segundo nibble (desloca a direita)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X06;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

    /////////////////////envia 0X0C - desliga display ////////////////////////////////////

    LCD = 0X20;//cursor desligado (0X0C)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X00;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

    LCD = 0X2C;//segundo nibble (cursor deligado)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X0C;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

        /////////////////////envia 0X2F - modo 4bits modo 4 linhas tipo de fonte ////////////////////////////////////

    LCD = 0X22;//cursor desligado (0X2F)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X02;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 

    LCD = 0X2F;//segundo nibble (cursor deligado)
    _delay_ms(1);//tempo estabilizar o pino
    LCD = 0X0F;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_ms(15);//substitui a leitura do busy flag 
    
}
// escreve nibble
void escr(unsigned char crt,int vlr)//se vlr = 1 é dados ,senão é comandos
{
    if(vlr == 1)
    {
    LCD = crt | 0X30 ;//escreve dados
    _delay_us(30);//tempo estabilizar o pino
    LCD = crt | 0X10;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_us(30);
    }
    else
    {
    LCD = crt | 0X20 ;//escreve comando
    _delay_us(30);//tempo estabilizar o pino
    LCD = crt | 0X00;//ao passar do nivel alto para o nivel baixo ele faz leitura
    _delay_us(30);
    }
}
// escreve caracter ou comando
void escreve(unsigned char carac,int val)
{
    unsigned char temp=carac;
    carac = ((carac >> 4) & 0X0F);
    temp  = temp & 0X0F;
    escr(carac,val);  //escreve primeiro nibble
    escr(temp,val);  //escreve segundo nibble
}

void impri_lcd(char frase[22])
{
      unsigned int indice=0;
      unsigned int tamanho = strlen(frase);
      while(indice<tamanho)
       {         
            if(frase[indice]=='\n')//linha 1 
            {
                 escreve(0X80,0);
            }
            if(frase[indice]=='\r')//linha2
            {
                 escreve(0XC0,0);//
            }
            if(frase[indice]=='@')//linha 3 
            {
                 escreve((0X94),0);
            }
            if(frase[indice]=='$')//linha4
            {
                escreve((0XD4),0);
            }
            if((frase[indice]!='\r') && (frase[indice]!='\n') && (frase[indice]!='@') && (frase[indice]!='$'))//dados
            {
               if(indice<21)
               {
                escreve(frase[indice],1);
               }
            }   
       indice++;
       }
} 

////////////////////////////////////telas de interface //////////////////////////////////////////////////

void tela_inicial()
{
           impri_lcd("\n.Testando display de");
           impri_lcd("\r.......20x4.........");
           impri_lcd("@12345678912345678912");
           impri_lcd("$------AGUIVONE------");
}

void tela_2()
{
            impri_lcd("@                    ");
           impri_lcd("$------teste2  ------");
}

void tela_3()
{
           impri_lcd("$------teste3  ------");
}

//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{
           DDRC = 0XFF;  //inicializa portC como saidas
           inicializa_LCD();
           tela_inicial();
           _delay_ms(2000);
           tela_2();
           _delay_ms(1000);
           tela_3();
           _delay_ms(1000);
           for(;;)
             {
              //faz nada!                                    
             }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////