Entrar
Todos os segredos de informática para iniciantes e profissionais
  • A Vodafone Ucrânia lançou um programa de fidelidade de bônus “Vodafone Bonus” para assinantes, sob o qual os bônus podem ser trocados por bens e serviços
  • Atualizando o BIOS ou como atualizar o BIOS Descubra qual versão do BIOS você instalou
  • Vodafone (MTS) Ucrânia - “Smartphone Standard”: condições e conexão
  • Revisão do jogo Counter-Strike: Global Offensive
  • Especificações do Samsung Galaxy S8, comentários de usuários, descrição, prós e contras do Samsung s8 plus dimensões do smartphone
  • Onde vender seu telefone antigo se você realmente deseja um novo com desconto
  • Programa para interação entre indicadores PIC16 e LCD. Trabalhando com um LCD de caracteres baseado no controlador HD44780 Instalando e inicializando um monitor LCD

    Programa para interação entre indicadores PIC16 e LCD.  Trabalhando com um LCD de caracteres baseado no controlador HD44780 Instalando e inicializando um monitor LCD

    Vamos considerar a interação entre um usuário e um dispositivo baseado em microcontrolador. Muitas vezes, o usuário precisa inserir informações de alguma forma e lê-las em alguma coisa. Um teclado e um display () são muito adequados para esses fins. Considere a interação entre o usuário e um dispositivo baseado em microcontrolador. Muitas vezes, o usuário precisa inserir informações de alguma forma e lê-las em alguma coisa. O teclado e o display () são muito adequados para esses fins. Nesta nota, examinaremos mais de perto a exibição de informações em um símbolo LCD com síntese de sinais.

    Esses indicadores são frequentemente usados ​​ao projetar dispositivos digitais, então você precisa saber como trabalhar com eles.
    Consideremos a estrutura interna típica de um sintetizador de sinais LCD:

    Estrutura interna do HD44780

    O LCD é baseado em uma matriz de cristais líquidos, ao aplicar tensão ao elemento do qual podemos “iluminar” um ponto da tela. No nosso caso, a matriz consiste em espaços familiares (geralmente 8x5 pixels), agrupados em várias linhas. Tudo isso é gerenciado pelo integrado Controlador HD44780. O controlador possui células de memória de byte único ( DDRRAM), cujo conteúdo é efetivamente exibido na tela de acordo com a tabela registrada em CGRAM. Geralmente há mais células de memória do que células familiares em LCD, então você precisa observar o endereçamento de locais familiares na folha de dados. Ou seja, só precisamos escrever o código do caracter desejado na posição desejada, e tudo mais HD44780 fará isso sozinho.

    Para selecionar uma posição, existe um cursor virtual (número da célula de memória atual, AC), que pode ser controlado através de comandos; o cursor pode ficar visível. Por padrão, ao escrever um caractere em uma célula, o cursor avança uma posição. Códigos de caracteres para LCD o suporte ao cirílico pode ser visto na tabela:

    A tétrade alta do código será igual à linha do símbolo selecionado, e a tétrade baixa será igual à linha. Você pode criar sua própria tabela de símbolos escrevendo-a em CGRAM. Cada caractere requer 5 bytes, onde uns são responsáveis ​​pelos pixels “acesos”. Por exemplo, o número "8" é codificado como 0x6c,0x92.0x92.0x92.0x6c.
    Os códigos de comando são fornecidos na tabela.

    Tabela de caracteres HD44780


    Significados da bandeira:


    A questão permanece em aberto: “como escrever o código do símbolo requerido na posição requerida?” Para fazer isso, vejamos quais são as responsabilidades das conclusões. LCD. conclusões DB0-DB7 são responsáveis ​​pelos dados de entrada/saída. Um nível alto no pino RS permite que o indicador saiba que o sinal nos pinos DB0-DB7 são dados e low é um comando. Conclusão E/R responsável pela direção dos dados, sejam os dados gravados na memória ou lidos dela (geralmente lendo de LCD não for usado, podemos aplicar-lhe com segurança um nível baixo). Pulso de saída E(com duração de pelo menos 500 ns) é usado como sinal para escrita/leitura de dados dos pinos DB0-DB7, R.S. E E/R.

    Conclusão V0 usado para definir o contraste da imagem, pinos A, K - para alimentar a luz de fundo (se o seu modelo tiver LCD). Os 2 pinos restantes são a fonte de alimentação real LCD. Ou seja, controlar LCD Serão necessários 8+1+1=10 pinos. Mas você pode trabalhar no modo de interface de 4 bits. Neste caso, a tétrade de comando/dados alta nos pinos DB4-DB7 será transmitida primeiro e depois a tétrade baixa. Conclusões DB0-DB3 não são usados. No total, são necessários 6 pinos do microcontrolador para controle.
    Agora vamos ver um exemplo ao vivo. Vamos escrever um programa para gerar texto "local na rede Internet" para o que tenho em estoque WH1602A(2 linhas de 16 caracteres).

    Para outros LCDs, você deve verificar a correspondência das células DDRRAM conhecidos. Diagrama de conexão LCD para o controlador fica assim.

    Diagrama de conexão ao microcontrolador AVR


    Resistor R3- 17 Ohm limita a corrente através da luz de fundo e da CA VR1 define o contraste (se tudo estiver conectado e programado corretamente, mas o indicador estiver silencioso, gire VR1 para que a imagem fique visível). Além disso, sob nenhuma circunstância a polaridade deve ser confundida. LCD, alimente-o acima de 5,5 V, pela minha experiência posso dizer que eles queimam instantaneamente. O propósito de todas as outras partes é o mesmo que em
    Agora vamos prosseguir com a escrita do programa. Para controlar o indicador, escreveremos um programa com diversas funções principais para trabalhar com LCD: lcd_dat(unsigned char x) – para escrever dados x, lcd_com(unsigned char x) – para escrever o comando x, lcd_init(void) – para inicialização inicial do indicador:

      #incluir //biblioteca de entrada/saída

    1. #define RS 2 //RS=PD2 - sinal de controle LCD

      #define E 3 //E=PD3 - sinal de controle LCD

    2. #define TIME 10 //Constante de atraso de tempo para LCD

      //Frequência de clock MK - 4 MHz

    3. //Programa de geração de atraso

      pausa nula (unsigned int a)

      (unsigned int i;

    4. para (i= a; i> 0 ; i-- ) ;

    5. //Programa para transmissão de comandos para o LCD

      void lcd_com (lcd de caractere não assinado)

      (temperatura de caractere não assinado;

    6. temp= (lcd& ~(1<< RS) ) | (1 << E) ; //RS=0 é um comando

      PORTD=temperatura; //Envia a tétrade mais alta do comando, sinais RS, E para portD

      asm("não");

      PORTD=temperatura& ~(1<< E) ; //Sinal de gravação de comando

    7. temp= ((lcd* 16 ) & ~(1<< RS) ) | (1 << E) ; //RS=0 é um comando

      PORTD=temperatura; //Envia a tétrade de ordem inferior do comando, sinaliza RS, E para portD

      asm("não"); //Pequeno atraso de 1 ciclo MK, para estabilização

      PORTD=temperatura& ~(1<< E) ; //Sinal de gravação de comando

    8. pausa (10 * TEMPO); //Pausa para execução do comando

    9. //Programa para gravar dados no LCD

      void lcd_dat (lcd de caractere não assinado)

      (temperatura de caractere não assinado;

    10. temperatura = (lcd | (1<< RS) ) | (1 << E) ; //RS=1 são dados

      PORTD=temperatura; //Envia a tétrade de dados mais significativa, sinais RS, E para portD

      asm("não"); //Pequeno atraso de 1 ciclo MK, para estabilização

      PORTD=temperatura& ~(1<< E) ; //Sinal de gravação de dados

    11. temp= ((lcd* 16 ) | (1<< RS) ) | (1 << E) ; //RS=1 são dados

      PORTD=temperatura; //Envia a tétrade de dados de ordem inferior, sinais RS, E para portD

      asm("não"); //Pequeno atraso de 1 ciclo MK, para estabilização

      PORTD=temperatura& ~(1<< E) ; //Sinal de gravação de dados

    12. pausa(TEMPO); //Pausa para saída de dados

    13. //Programa de inicialização do LCD

      vazio lcd_init(vazio)

      lcd_com(0x2c); //Interface de 4 fios, tamanho de caracteres 5x8

      pausa(100 * TEMPO);

      pausa(100 * TEMPO);

      pausa (100 * TEMPO);

    14. //Programa principal

      int principal(vazio)

      DDRD = 0xfc; //Inicializa a portaD

      PORTD= 0x00 ;

    15. pausa(1000);

      lcd_init(); //Inicialização do LCD

    16. lcd_dat("w"); //Saída "www.site"

      lcd_dat("w");

      lcd_dat("w");

      lcd_dat("." );

      lcd_dat("a");

      lcd_dat("v");

      lcd_dat("r");

      lcd_dat("l");

      lcd_dat("a");

      lcd_dat("b");

      lcd_dat("." );

      lcd_dat("c");

      lcd_dat("o");

      lcd_dat("m");

    17. lcd_dat("Eu"); //Escreva "É tão fácil"

      lcd_dat("t");

      lcd_dat(""");

      lcd_dat("s");

      lcd_dat(" ");

      lcd_dat("s");

      lcd_dat("o");

      lcd_dat(" ");

      lcd_dat("e");

      lcd_dat("a");

      lcd_dat("s");

      lcd_dat("y");

    18. enquanto(1) //ciclo sem fim

    19. retornar 1;

    O programa é muito simples, não será difícil para quem tenha pelo menos um pouco de conhecimento entendê-lo. C Para AVR. Para latim e números ASCII os códigos correspondem aos programados no gerador de caracteres LCD, portanto é permitido usar lcd_dat('A'). Você pode criar sua própria biblioteca para trabalhar com LCDs separando as funções lcd_dat(unsigned char x), lcd_com(unsigned char x), lcd_init(void) em um módulo separado LCD.h e conecte-o conforme necessário.

    Essa ideia economiza muito tempo; você só precisa escrever as funções necessárias uma vez e depois usá-las o tempo todo. Você também pode notar que é inconveniente gerar uma frase longa, uma letra por vez; para fazer isso, você pode inserir nossa string de saída em um array de caracteres não assinados e produzi-la usando um loop:

      int principal(vazio)

      (dados de caracteres não assinados [14] = ( "w" , "w" , "w" , "." , "a" , "v" , "r" , "l" , "a" , "b" , " ." , "c" , "o" , "m" ) ;

      caractere não assinado i;

      DDRD = 0xfc; //Inicializa a portaD

      PORTD= 0x00 ;

    1. pausa(1000); //Atraso para que o LCD tenha tempo de ligar

      lcd_init(); //Inicialização do LCD

    2. para (eu= 0; eu< 14 ; i++ ) //Sai a entrada letra por letra

      lcd_dat(dados[i]);

    Só não esqueça que a numeração do array em C começa do zero. O programa existente pode ser usado em conjunto com o controlador sem alterações significativas ATtiny2313, conectando LCD Para PORTOB, como PORTD no ATtiny2313 tem apenas 7 pinos, não 8, como ATmega8.

    Eu também recomendo conectar LCD usando conexões destacáveis. É muito conveniente ao depurar um programa, quando você precisa exibir alguns dados intermediários. Conectei um conector e pronto. Na continuação desta nota, num futuro próximo considerarei a exibição das informações lidas em LCD.
    Tenham um bom dia, pessoal;)

    há uma pequena falha neste exemplo

    Há uma pequena falha neste exemplo, talvez por isso o exemplo não funcione para muitos!

    Em geral, o exemplo é lacônico e simples, então uma pequena falha não chama a atenção (para quem conhece a linguagem “C”), e mais ainda para quem está começando a conhecer o AVR e o “C”. ”linguagem, talvez eles até fiquem perplexos sobre como isso aconteceu... eles escrevem, fazem assim e vai ficar como na foto....mas não é o caso...

    Em geral, todo o problema está nos ciclos de atraso, para que o display acompanhe o controlador, nomeadamente na função -

    //Programa de geração de atraso

    pausa nula (unsigned int a)

    (unsigned int i;

    para (i=a;i>0;i--);

    tudo parece estar correto à primeira vista, mas os compiladores para microcontroladores se esforçam para otimizar o código para obter a compactação máxima da imagem de memória flash resultante dos programas... e não vendo nenhum sentido em um loop vazio e, consequentemente, mais abaixo na cadeia após it: todas as chamadas, declarações de constantes e tudo relacionado a esta função não tem sentido na opinião dele... simplesmente a remove do código durante a montagem...

    pelo menos isso é verdade para o atmel studio 6.1, e você pode verificar isso olhando na pasta do projeto, existe um arquivo *.lss contendo o código assembly deste programa, gerado na construção do projeto. nenhuma dica sobre a implementação da função void pause...

    como resultado, ao atualizar o firmware do controlador, o display fica com lixo ou vazio aleatório... quando você pressiona reset várias vezes, o lixo pode desaparecer e reaparecer... é óbvio que o processador e a tela estão fora de controle sincronizar

    mas se você fizer uma pequena correção

    pausa nula (unsigned int a)

    (unsigned int i;

    para (i=a;i>0;i--)
    asm("não");

    Então, para o compilador, isso faz sentido, isso também é confirmado pela aparência óbvia da implementação da função no código assembly

    0000006c
    :
    6c:9c 01 movimento r18, r24
    6e: 03 c0 rjmp .+6 ; 0x76
    70h00 00h00
    72: 21 50 subi r18, 0x01 ; 1
    74:31 09 sbc r19, r1
    76: 21 15 pc r18, r1
    78:31 05 cpc r19, r1
    7a: d1 f7 brne .-12 ; 0x70

    e muito provavelmente tudo vai funcionar....pelo menos para mim no atmega16 (sincronização RC interna 1Mhz) e usando atmel studio 6.1 foi exatamente assim...talvez em outras frequências você terá que brincar com o #define TIME 10 constante e/ou os valores passados ​​para a função void pause

    aqui-> pausa(valor) ...ou pausa(valor*TEMPO) ....

    Boa sorte aprendendo como operar o AVR!

    Olha, imagine que o LCD -

    Olha, imagine que o LCD é uma máquina de escrever, o papel na máquina de escrever é a memória do LCD, o carro é o ponteiro do cursor. Além disso, o LCD não exibe todo o conteúdo da memória, mas apenas uma parte. Parece uma espécie de janela que montamos em nosso papel com texto.

    Aqui o I/D determina como imprimiremos, da direita para a esquerda ou da esquerda para a direita.
    S determina se moveremos a janela da tela enquanto digitamos ou não.
    S/C - simplesmente move a janela da tela visível ou o carro da máquina de escrever.
    R/L - especifica para onde (esquerda ou direita) moveremos a tela ou os cursos usando a flag S/C.

    Acho que está faltando alguma coisa!

    Eu roubei seu programa e proteus e não inicio no mega8. A tela fica em silêncio, comecei a vasculhar as fichas técnicas e foi isso que encontrei:
    O que falta é a inicialização dos três primeiros!

    0011 - espere 5ms
    0011 - espere 100 µs
    0011 - espere 2ms
    0010 - espere 41 µs
    0000 - -e-
    0010 - -e-
    1000
    0000
    1000
    0000
    0001
    0000
    0100

    Corrija-me se eu estiver errado!

    Não funciona!

    Tentei alterar as frequências do clock, atrasos na inicialização e saída de símbolos (comandos), até o momento sem sucesso. Em relação aos fusíveis, se você pretende configurar os pinos da porta D usando DDRB, o PORTD registra como saídas de log baixo. nível, então eu fiz isso.
    Não tendo mais nada para fazer, compilei um programa simples de saída de símbolos usando ferramentas CodeVisionAVR, coloquei-o no PROTEUS - funciona!... mas com um LCD real ele recusa..

    Não, estou falando sobre isso

    Não, estou falando de tentar colocar uma luz piscante na porta D, por exemplo, ou simplesmente acender a porta inteira de uma vez. Quando comprei apenas um microcontrolador, não consegui fazer isso. Eu vasculhei os fóruns e descobri que os fusíveis estão de alguma forma programados lá e que a porta D e todos os seus 8 bits não estão ligados. Verifique este ponto, ou melhor ainda, tente mover o LCD para outra porta, por exemplo para B. O fato do programa funcionar no Proteus mas não com o real é a diferença nos parâmetros do LCD entupido no Proteus e no real.

    Não funciona!

    Montei e conectei tudo conforme o diagrama, apenas o MK usou ATmega16 e LCD WH1602M, e respectivamente compilei o firmware para ele no WinAVR. Porém, o LCD recusou-se a exibir qualquer coisa, também coletei no Proteus (no ATmega 8 e LM016L), os dados do MK são exibidos, mas nada fica visível no LCD. Qual poderia ser o problema? (Se isso for importante, use o oscilador RC interno para clock de 1 MHz)

    1. Para Atmega16 você precisa

    1. Para Atmega16, você deve primeiro ligar os fusíveis para que a porta D funcione.
    2. Tente alterar a frequência do clock para 4 MHz e 8 MHz. Todo o problema do LCD é que todas as pausas não são mantidas durante a inicialização ou ao emitir um comando. E o controlador LCD é muito sensível a isso.

    Eu tenho uma pergunta:
    Montei um circuito de cronômetro no Mega 8 com um hexadecimal pronto - as leituras são exibidas no WH0802,
    indicação é um número de três dígitos que são exibidos em toda a tela, um dígito consiste em 4 caracteres. Tela pseudográfica. Como o firmware poderia ser escrito?
    O autor se recusa categoricamente a fornecer o código-fonte e não comenta a obra, provavelmente por questões de “propriedade intelectual”.
    No meu tempo livre quero tentar escrever meu próprio firmware para fins educacionais.

    Eu me deparei com isso

    Me deparei com essa situação.
    Existem dois LCD 16x2:
    1 - MTC-S16204XFGHSAY
    2 - WH1602A-YGH-CTK

    Eu uso o primeiro em um projeto com GPS.
    Resolvi usar o segundo em um projeto com teclado. Mas por algum motivo o LCD não funciona.
    O contraste é ajustado e aparecem quadrados. Isso é tudo.
    Talvez haja uma ordem de inicialização diferente.
    Ajude-me a entender
    Aqui estão as fichas técnicas
    filebox.od.ua/?file=24a31fc50d62bfcd658bdadac84088ab

    As exibições não são diferentes.

    As exibições não são diferentes. A pinagem é a mesma. Os horários variam um pouco. Tente aumentar o atraso ao enviar comandos ao LCD ou diminuir a frequência do microcontrolador.

    Todos os LCDs do HD44780 possuem um sistema de comando idêntico. Qual interface você está usando, 4 bits ou 8 bits? Tente também aumentar o atraso entre ligar o LCD e sua inicialização, para cerca de 0,1s. A polaridade da fonte de alimentação do LCD não está confusa, eles precisam queimar um pouco? De alguma forma, tolamente, queimei-o e tentei conectá-lo. Quadrados pretos também foram exibidos, os dados foram exibidos alternadamente, ou seja, funcionou extremamente instável.

    Eu uso programas de artigos

    Eu uso programas de artigos sobre GPS.
    Interface de 4 bits

    Eu tentei o programa daqui
    chipenable.ru/index.php/programming-c/75-chasy-na-mikrokontrollere.html

    funcionou

    O que você deve mudar em seu programa?

    Preste atenção aos atrasos

    Preste atenção aos atrasos após emitir os comandos de inicialização e configuração, pode ser o caso. Eu também tive um caso semelhante, mas os controladores eram iguais e o programa só funcionava em um.

    Análogos HD44780

    Tive um problema: não consigo encontrar o LCD WH1602A a um preço razoável. Por exemplo
    no chipdip, eles estão disponíveis em chipdip.ru/product/wh1602a-ygh-ct-k.aspx
    700 de madeira. O que é YGH no nome "WH1602A-YGH-CT(K), LCD 16x2, Inglês-Russo"
    Que análogos de LCDs baseados em HD44780 existem? Encontrei a página micronika.ru/order.phtml?vid=64 - lá o nome FDCC1602A-FSBFBW-51SR contém 1602A,
    Acabei de notar. Talvez o FDCC1602A-FSBFBW-51S funcione sem muitas alterações de código?
    Que problemas podem surgir ao usar
    não o HD44780 real da Hitachi, mas seus análogos?
    PS Não seria uma má ideia ler sobre o uso de LCDs diferentes, análogos ao HD44780, dos do MELT
    LCDs são ruins

    Neste artigo darei um exemplo de uma das opções para inicializar um indicador alfanumérico de cristal líquido na plataforma do controlador HD44780 ou KS0066 para programadores iniciantes em linguagem assembly em relação aos microcontroladores PIC16.

    Este programa faz parte do programa do medidor de temperatura e umidade descrito no artigo "". Para maior comodidade de trabalhar com o artigo e o arquivo fonte do programa, é melhor primeiro baixar o projeto, imprimir o arquivo fonte e colocá-lo na sua frente. Ao escrever um programa para inicializar um display LCD, escrever comandos e exibir símbolos no indicador, é melhor usar macros criadas para esse fim. Vejamos a tela.

    Após as diretivas de substituição de texto, existem macros - pequenos programas que podem ser acessados ​​​​a partir do programa principal quantas vezes você quiser, a qualquer momento. A primeira macro, impuls_E, garante que um pulso de disparo seja recebido na linha E, as linhas de disparo e sincronização. Linha 14 – define um lógico na linha, através de dois pseudocomandos NOP, linha 17 – define um zero lógico. Assim, recebemos um pulso positivo na linha E com duração de 2 μs na frequência do oscilador de quartzo de 4 MHz. A próxima macro é Load_Znak, que nos permite carregar o código do símbolo no registro DR para exibi-lo no indicador. Você notará que nesta macro há uma chamada para outra macro escrita abaixo. Vejamos a macro send_LCD. Linha 26 – lê o conteúdo do registrador Write_data, ou seja, código do caractere que deveria estar nele. Linha – 27, troque os nibbles altos e baixos do registro. Linha – 28, selecionamos o nibble alto do código do caractere, que já está no nibble baixo, e enviamos esses dados para a porta B. O fato é que o registro dos dados no modo de operação de 4 bits do controlador do indicador ocorre sequencialmente, primeiro o nibble alto do registro, depois o júnior - linha 31... 33. Após transmitir um nibble, um pulso estroboscópico deve ser gerado. Isto é o que vemos, linhas 30 e 34. Para que o controlador do display processe as informações, um atraso de 200 microssegundos foi introduzido na macro. Após as macros que criamos, existe um procedimento padrão para inicialização do microcontrolador. No artigo "" falei sobre as principais propriedades dos displays LCD e abordei o tema da criação de seus próprios símbolos. Como eu disse antes, não há símbolo de grau nos meus indicadores. Então, vamos carregá-lo no gerador de caracteres do indicador. Para isso, escreveremos uma pequena sub-rotina, que deverá estar localizada atrás do procedimento de inicialização do microcontrolador e à frente do programa principal. A sub-rotina começa na linha 69, onde inserimos o código de endereço na área CGRAM, 40h - o primeiro usuário endereço será armazenado sob este endereço. Veja a captura de tela 2.

    Como cada caractere ocupa oito registros de memória, o próximo caractere que criarmos começará no endereço 40h + 08h = 48h. A próxima é 48h + 08h = 50h. Não se esqueça de que a adição ocorre no sistema numérico hexadecimal. E assim, linhas 69 e 70 – carregando o endereço inicial do símbolo. Em seguida vem a gravação alternativa de oito bytes do código do caractere. Pegaremos o código do símbolo de grau do programa LCDCC.

    Teremos que repetir um pouco o que estava no artigo “Indicadores alfanuméricos de cristal líquido”. Vejamos a captura de tela deste programa. Ao clicar nas células da matriz, desenhamos o símbolo desejado, neste caso é um ícone simbólico de grau. Abaixo, o programa escreve imediatamente códigos para os pontos selecionados da matriz. Agora precisamos escrever esses códigos no controlador do indicador. Foi isso que fizemos. Agora chegamos à inicialização do próprio indicador. Veja a captura de tela 3.

    Antes da inicialização, por exemplo, escreveremos dados nos registros para enviar valores ao indicador. Vamos inserir, por exemplo, um valor de temperatura de 21,7 graus. Depois vamos criar um projeto no Proteus e ver o que acontece. Então. Captura de tela 3, linhas 88... 93 – escrevendo números nos registros. A inicialização começa com o rótulo InitLCD, como esperado, esperamos pelo menos 15 ms. Após uma pausa, linhas 98...100, escreva o número três no registrador Reg_3 - este será o número de vezes que o comando será transmitido 30h = b’0011 0000’ (30h). E escrevemos três no registro da porta B, para posterior escrita no controlador do indicador, este número três está no meio byte alto do comando. Formamos um pulso estroboscópico, linha 102, pausa de 5 ms. Voltamos ao rótulo Setloop. Enviamos o comando até que o registro Reg_3 seja zerado, ou seja, três vezes. Após transmitir este comando, o controlador indicador estará pronto para operação, mas no modo 8 bits. Agora vamos mudar para o modo de 4 bits. Para isso enviaremos o comando 20h. Lembre-se de que os comandos são gravados no controlador do indicador no modo de 4 bits. Então, temos o comando 20h ou 0010 0000. Como no modo 4 bits os comandos são transmitidos em dois estágios, primeiro os dados do nibble mais significativo do registrador, inserimos os dois no registrador da porta B e escrevemos no controlador do indicador, e como o nibble mais baixo está vazio, não transmitimos nada.

    Depois de escrever 2 na porta B, disparamos a linha E e pausamos por 200 nós. Agora o indicador funcionará no modo de 4 dígitos. O próximo comando é o comando para definir o modo de operação - duas linhas, fonte - 5x7. Código de comando 28h. Em seguida vem o comando 0C para ligar o indicador. Bem, então, eu acho, você vai descobrir. Sim, um pouco mais. No Proteus, o símbolo do ícone de grau que criamos não é exibido corretamente; ele exibe dois pontos, embora na realidade tudo funcione bem. Vejamos a foto. Boa sorte.

    Hoje, os indicadores LCD simbólicos de cristal líquido são cada vez mais usados ​​para exibir informações simbólicas simples. Falaremos sobre como trabalhar com eles. Nesta parte do artigo, daremos uma olhada detalhada nos LCDs de caracteres baseados no controlador HITACHI HD44780 (ou no SAMSUNG KS0066 compatível). O artigo é uma tentativa de sistematizar as informações que encontrei ao trabalhar com esses LCDs.

    LCD de caracteres com controlador HD44780 (KS0066). Interface

    Um LCD de caracteres nada mais é do que uma matriz de pontos, dividida em linhas e campos de caracteres:

    Um controlador especial é usado para controlar esta matriz e gerar os caracteres reais.

    HD44780 (e seu compatível KS0066) é o padrão de fato para controladores de monitores LCD monocromáticos de síntese de caracteres com interface paralela de 4 ou 8 bits. Com base neste controlador, é produzido um grande número de modelos com diferentes designs e resoluções, começando com 8x1 (oito caracteres em uma linha) e terminando com 40x4 (contendo dois chips de controle independentes). A frequência operacional típica do controlador é 270 kHz.

    O controlador LCD opera com 3 blocos de memória:

    1. O controlador usa memória para gerar um caractere DDRRAM(Display Data RAM), onde são armazenados os códigos ASCII dos caracteres que queremos ver no LCD. 80 células de memória são alocadas para isso. É claro que no LCD veremos apenas parte dos caracteres que estão em DDRAM - se nosso LCD tiver 1 ou 2 linhas e exibir 8 caracteres por linha, então assim:

    A área de trabalho da tela, como você pode ver, pode ser deslocada ao longo das células DDRAM (você obtém um efeito de linha rastejante).

    2. O controlador pega os próprios modelos dos símbolos CGROM(ROM gerador de caracteres) – memória geradora de caracteres. A tabela de símbolos pode ser encontrada na especificação do HD44780.

    3. A memória é fornecida para armazenar símbolos do usuário (seus modelos) CGRAM(RAM do gerador de caracteres).

    Além disso, o controlador, dependendo de certas condições, distribui os dados recebidos nele em registro de instruções ou registro de dados.

    Interface típica do controlador HD44780 de 14 pinos:

    Terra, comum, GND

    Tensão de alimentação, Vcc (+5V)

    Ajustando o contraste (Vo)

    Seleção de registro (R/S para HD44780, A0 para KS0066)

    Ler/Escrever (R/W)

    Strobe na queda E (Ativar)

    Bit 0 (menor para interface de 8 bits)

    Linha de dados

    DB 4 (menor para interface de 4 bits)

    DB 7 (alto para interface de 8 (4) bits)

    Para display retroiluminado

    Potência de retroiluminação para displays retroiluminados (ânodo)

    Potência de retroiluminação para displays retroiluminados (cátodo)

    Observamos a numeração dos pinos em um LCD específico na folha de dados.

    O contraste da imagem no LCD pode ser alterado conectando um resistor de ajuste adicional de 10 kOhm de acordo com o diagrama a seguir:

    Porém, você deve observar as especificações do seu controlador (por exemplo, o LCD Klsn10294v-0 no chip KS0066 tem 1 Vcc e 2 GND). A fonte de alimentação da luz de fundo pode variar de modelo para modelo, dependendo do tipo. Normalmente, a luz de fundo é alimentada por 5 volts; um resistor limitador de corrente (50-100 ohms) geralmente é opcional.

    Atribuição de pinos R/S, R/W, E:

    Quando E transita de log alto. nível para dados baixos que já estão “pendurados” nos terminais DB0..DB7, são gravados na memória do controlador LCD para processamento posterior.

    Em log alto. No nível R/S (seleção de registro), o controlador LCD percebe esse conjunto de bits como dados (código de caractere) e em um nível baixo – como uma instrução e os envia para o registro apropriado.

    R/W determina a direção de operação dos pinos DB0..DB7 - se R/W for “0”, então só podemos escrever na porta DB, e se R/W = “1”, então podemos ler dela (por exemplo, descobrir se o controlador está ocupado ou livre para receber novos dados). Se não lermos os dados do LCD, poderemos “plantar” R/W no solo.

    Conjunto de instruções HD44780

    Para começar a exibir informações no LCD, seu controlador deve ser inicializado (informá-lo sobre interface, fonte, offsets, etc.). O controlador pode aceitar um total de 11 comandos:

    Nome das instruções

    Status do PIN

    Hora de conclusão

    escravo =270kHz

    Limpar todo o LCD e definir o endereço DDRAM para 0

    Definir o endereço DDRAM atual como 0 (cursor - home) Os dados DDRAM não mudam

    Definir a direção do movimento do cursor (I/D) e o deslocamento de exibição (S) ao enviar dados

    Controle liga/desliga do display

    Ligado desligado. display(D), cursor(C) e sua cintilação(B)

    Cursor ou mudança de exibição

    Move o cursor e muda a exibição entre DDRAM

    Configurando a interface(DL), número de linhas(N) e fonte dos caracteres(F)

    Definir endereço CGRAM

    Configurando o contador de endereços CGRAM. Depois disso, você pode gravar dados no CGRAM

    Definir endereço DDRAM

    Configurando o contador de endereços DDRAM

    Ler sinalizador e endereço de ocupado

    Se BF = 1 então o controlador LCD está executando uma operação interna (ocupado). AC6-AC0 – valor atual do endereço DDRAM

    Gravar dados na RAM

    Gravando dados na RAM

    Ler dados da RAM

    Lendo dados da RAM

    I/D = 1: endereço DDRAM aumenta I/D = 0: diminui
    S = 1: é permitido mudar a área de trabalho da tela via DDRAM
    D = 1: display (imagem) ligado
    C = 1: cursor habilitado
    B = 1: Cursor piscando habilitado

    S/C = 1: move o display S/C = 0: move o cursor
    R/L = 1: direita R/L = 0: esquerda

    DL=1:8 bits DL=0:4 bits
    N=1:2 linhas N=0:1 linha
    F = 1: 5x10 F = 0: 5x8

    ACG:endereço CGRAM
    ADICIONAR: endereço DDRAM (endereço do cursor)
    AC: Contador de endereços Endereços DD e CGRAM

    Inicialização do LCD

    Existem 2 maneiras de inicializar o controlador LCD:

    1. Via circuito de reinicialização interno.

    2. No modo manual (enviando uma série de comandos para ele, com os quais definimos o modo de operação do LCD)

    O circuito de reinicialização interno do controlador começa a operar imediatamente após a alimentação ser ligada. Há uma desvantagem nisso - se nossa energia “rastejar” lentamente para o nível operacional (mais lento que 10 ms), a autoinicialização do controlador poderá não ocorrer corretamente. Com este método de inicialização, o próprio controlador executa os seguintes comandos:

    1.Exibição clara

    2. Conjunto de funções:
    DL = 1; Dados de interface de 8 bits
    N = 0; Exibição de 1 linha
    F = 0; Fonte de caracteres de 5x8 pontos

    3. controle liga/desliga da tela:
    D = 0; Exibição desligada
    C = 0; Cursor desligado
    B = 0; piscando

    4. Modo de entrada definido:
    I/D = 1; Aumentar em 1
    S = 0; Sem mudança

    O segundo método elimina a dependência do circuito da fonte de alimentação. Para inicializar o controlador LCD no modo manual, você deve executar o seguinte algoritmo:

    Como você pode ver, não há nada complicado aqui: enviamos comando após comando para o LCD, levando em consideração seu tempo de execução (cerca de 40 μs) ou verificando o flag de ocupado do controlador LCD (então precisamos colocar o pino RW em o pé do microcontrolador e coloque-o em “1” quando quisermos saber se o LCD está ocupado ou não).

    Na verdade, isso é tudo o que diz respeito à teoria de trabalhar com LCDs simbólicos. Se você perdeu alguma coisa ou cometeu um erro, leia as especificações do controlador ou .

    Na segunda parte, consideraremos a implementação de hardware e software da comunicação entre um microcontrolador PIC e um LCD.

    Por algum tempo, esta tela ficou ociosa.


    E agora há um desejo de anexá-lo a um dos projetos; você pode, claro, tentar encontrar uma biblioteca com funções prontas, mas neste caso a imagem de como o display funciona ficará incompleta, e isso não não nos convém. Depois de compreender o princípio de funcionamento de um display LCD, não será difícil escrever sua própria biblioteca para o display desejado se ela estiver faltando ou não for satisfatória de alguma forma.

    Então, vamos começar.
    A primeira coisa a fazer é encontrar a pinagem, ou seja, qual contato é responsável por quê, a segunda é encontrar o nome do controlador que controla o display, para isso baixe a ficha técnica deste LCD e abra-o em a primeira página.


    Os contatos são contados da esquerda para a direita, o primeiro é marcado com uma seta vermelha. A tensão de alimentação é de 5 volts, o controlador de controle S6A0069 ou similar, por exemplo, ks0066U.

    Por que estávamos procurando o nome do controlador de controle? O fato é que na ficha técnica do display há atrasos de tempo (diagrama de temporização), o sistema de comando está descrito, mas não há inicialização banal e sem ela não há lugar nenhum.
    A seguir, abra a segunda página e veja uma tabela que diz qual contato é responsável por quê.


    DB7…DB0– barramento de dados/endereço.

    R/W- determina o que faremos, ler (R/W=1) ou escrever (R/W=0)

    R/S– determina se enviaremos um comando (RS=0) ou dados (RS=1)

    E– entrada estroboscópica, alterando o sinal nesta entrada permitimos que o display leia/escreva dados.

    LED±– controle de luz de fundo.

    Devo dizer que no display que recebi a retroiluminação não vai apenas acender, para isso é necessário soldar um resistor, marcado na placa como R7. Mas por enquanto não precisamos disso.

    Baixe a folha de dados do controlador de controle e encontre as instruções de inicialização. As imagens podem ser ampliadas clicando sobre elas.



    Acontece que existem duas instruções desse tipo, para os modos de 8 e 4 bits. Que tipo de modos são esses? Esses modos determinam quantos fios os dados serão transmitidos: quatro ou oito. Vejamos a transmissão 4 fios, neste caso o display funcionará mais devagar, mas economizaremos 4 pinos do microcontrolador, e a implementação do modo de oito bits não é muito diferente.

    O diagrama de conexão de informações é o seguinte.


    O contraste pode ser ajustado conectando um potenciômetro entre os pinos de alimentação.

    Gostaria de chamar sua atenção para o fato de que durante a inicialização R/S E R/W são sempre iguais a zero, ou seja, enviaremos equipes.

    Durante a inicialização você pode configurar:

    • N - número de linhas exibidas
    • C - liga ou desliga o cursor
    • B - faz o cursor piscar
    • I/D - aumenta ou diminui o valor do contador de endereço
    • SH - mover janela de exibição
    Vejamos os dois últimos pontos com mais detalhes.
    A figura abaixo mostra em qual endereço precisamos escrever os dados para que sejam exibidos em uma determinada posição, por exemplo, se quisermos exibir um símbolo em primeira posição da segunda linha, então devemos escrever no endereço 0x40.


    Depois disso, o valor do contador mudará automaticamente, aumentando ou diminuindo, e junto com ele a posição do cursor mudará.

    A propósito, a memória na qual escrevemos é chamada DDRRAM, tudo o que escrevermos nesta memória será exibido no display, ainda há CGROM, que armazena a tabela geradora de caracteres.


    Esta tabela não pode ser alterada, mas símbolos prontos podem ser retirados dela. Outro tipo de memória é CGRAM, também é uma tabela geradora de caracteres, mas nós mesmos desenhamos os caracteres nesta tabela.


    Agora algumas palavras sobre o movimento da tela, o fato é que normalmente no display não vemos toda a DDRAM, mas apenas uma determinada parte, como mostra a figura abaixo.


    Também podemos escrever na parte invisível, mas o que escrevemos não ficará visível até que movamos a janela da tela para este local.

    Terminamos a teoria, vamos passar à prática.
    A imagem da comunicação com um display LCD no modo de 4 bits é semelhante a esta.


    Os dados são enviados em bytes, mas como temos um modo de 4 bits, para enviar um byte é necessário fazer 2 envios, sendo o bit mais significativo primeiro. Na imagem, a primeira parcela é designada D7 (tétrade alta), a segunda D3 (tétrade baixa). Antes do próximo envio, devemos verificar o sinalizador de ocupado e se não estiver configurado, podemos enviar novamente; se estiver configurado, esperamos até que o controlador que controla o LCD termine seu trabalho.

    Tendo uma visão geral do envio, vamos descobrir como implementar a operação de envio.


    Para enviar você precisa usar um barramento de 8 bits:
    • R/W definido como 0
    • emitir código/dados de comando para o barramento
    • atraso 2us
    • estroboscópio inferior E

    A operação de leitura é implementada de forma semelhante:

    • certifique-se de que o controlador de controle esteja livre
    • R/W definido como 1
    • aumente o estroboscópio E (neste momento o LCD enviará dados para o barramento)
    • atraso 2us
    • lemos o que o LCD deu
    • estroboscópio inferior E
    De onde veio o atraso de 2us?

    Acima dos timings tem uma tabela que diz a que são iguais os atrasos mostrados no gráfico, e assim a duração do pulso estroboscópico - tw deve ser igual a 230nS ou 450nS dependendo da tensão de alimentação, levamos um pouco com um margem. Por que levamos em conta apenas esse atraso? Porque o valor dos atrasos restantes é muito pequeno.

    Para enviar um barramento de 4 bits:

    • certifique-se de que o controlador de controle esteja livre
    • defina RS como 0 (comando) ou 1 (dados), dependendo do que enviaremos
    • R/W definido como 0
    • aumentar o estroboscópio E (definido como 1)
    • emitimos o caderno mais alto para o ônibus
    • atraso 2us
    • estroboscópio inferior E
    • atrasar 1us
    • aumentar o estroboscópio E (definido como 1)
    • emitimos a tétrade baixa para o ônibus
    • atraso 2us
    • estroboscópio inferior E

    Para ler em um barramento de 4 bits:

    • certifique-se de que o controlador de controle esteja livre
    • porta de dados para entrada com pull-up
    • defina RS como 0 (comando) ou 1 (dados), dependendo do que iremos ler
    • R/W definido como 1
    • aumentar o estroboscópio E (definido como 1)
    • atraso 2us
    • leia o caderno sênior
    • estroboscópio inferior E
    • atrasar 1us
    • aumentar o estroboscópio E (definido como 1)
    • atraso 2us
    • lemos o caderno inferior
    • estroboscópio inferior E

    Aumentar o estroboscópio e enviar o comando/dados para o barramento pode ser trocado. Agora não será difícil inicializar o display. Para simplificar a inicialização, substituiremos a leitura do sinalizador ocupado por um atraso e consideraremos trabalhar com o sinalizador posteriormente.
    Deve-se observar que durante a inicialização no modo de 4 bits são utilizadas instruções de 4 bits e, após a inicialização, é utilizado um sistema de instruções de 8 bits, portanto, para inicialização implementamos uma função separada para envio de comandos void Write_Init_Command (dados uint8_t).
    //Código de inicialização para Atmega16 #define F_CPU 8000000UL #define LCD_PORT PORTA #define LCD_DDR DDRA #define LCD_PIN PINA #define DATA_BUS 0XF0 #define RS 0 #define RW 1 #define E 2 #include #incluir void Write_Init_Command(uint8_t data) ( //pernas pelas quais os comandos/dados são transmitidos para a saída LCD_DDR |= DATA_BUS; //enviaremos o comando LCD_PORT &= ~(1<Um cursor piscando alegremente indica que a inicialização foi bem-sucedida. EM