terça-feira, 14 de setembro de 2010

usando lcd 4 bits com atmega8 AVR STUDIO

Aqui a proposta é controlar um lcd de forma facil e sem biblioteca :
///************************************************************************/
//                             usando LCD
//  Version    : 1.0
//  microcontrolador : AVR ATMega8
//  Autor        : Aguivone
//  descrição  : usando lcd interface de 8 bits
//  data : 02/09/2010.
//
//************************************************************************/
#define F_CPU 4000000UL  // 4 MHz
#include <avr/io.h>
#include <util/delay.h>
#include <string.h> 

/////////////////////////////////////variaveis usada no lcd ///////////////////////////////////////////
//#define LCD PORTC //define qual porta vai usar neste caso port C
#define LCD PORTD //define qual porta vai usar neste caso port D
//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);

    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);

    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 
    
     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 

    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 
    
}
// escreve nibble
void escr(unsigned char crt,int vlr)
{
    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[17])
{
      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]!='\r') && (frase[indice]!='\n') && (indice<18))//dados
            {
               escreve(frase[indice],1);
            }   
       indice++;
       }
} 

//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{
           DDRC = 0XFF;  //inicializa portC
           DDRD = 0XFF;  //inicicializa portD como saida
           inicializa_LCD();
           impri_lcd("\n   teste de lcd ");
           impri_lcd("\r      AGUIVONE  ");
          for(;;)
            {
              //faz nada                
            }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////


5 comentários :

  1. olá, sou novo nesse lance de programação de Mcontroladores e tenho uma dúvida sobre o teu código: o que seria as vairáveis "gt" e "amp"? elas foram declaradas em algum lugar?

    ResponderExcluir
  2. obrigado iaan não tinha visto esse erro,é por que ao copiar e colar aqui no blog deu erro mas já estou usando um outro processo para postar esses código de forma que esses erros não aconteçam mais.é por isso que preciso da colaboração de vcs para melhorar cada vez mais obrigado!

    ResponderExcluir
  3. Será que consigo utilizar este mesmo codigo compilando ele no Mikroc Pro, e utilizando um LCD 20x4 ?

    Abraços!

    ResponderExcluir
    Respostas
    1. creio que sim basta fazer algumas mudanças,se vc colocar do jeito que está ele vai escrever apenas nas 2 linhas dai vc adpta ele pra escrever nas outras linhas, mas se não me engano tem um exemplo de lcd com 4 linhas aqui no blog, dê uma olhada.

      Excluir
  4. Quero colocar o valor de uma variável para ser exibido no LCD, como faço?

    ResponderExcluir

olá,digite aqui seu comentário!