Controle de LED RGB com PWM

Introdução

 

 

Os LEDs RGB são bem conhecidos e possuem diversas aplicações em sistemas eletrônicos. É possível encontrar muitas páginas da internet e artigos que descrevem exaustivamente as mais variadas aplicações e utilidades dos LEDs para a geração de efeitos luminosos, programados em populares plataformas de programação para computação (como Arduínos e Raspberry Pis), o controle da luminosidade de um LED pode ser feito com o uso de uma Modulação de Largura de Pulso (PWM), como descrito neste outro artigo. No artigo referenciado, descreve-se um projeto que permite aumentar ou diminuir a luminosidade de um LED a partir do comando de dois botões.

Neste projeto, um bloco de código VHDL é utilizado para controle via PWM, dos três componentes de cor de um LED RGB, podendo-se compor da forma desejada, uma cor qualquer dentro do espectro de cores atingido pelo LED. O software Quartus II Web Edition foi utilizado para geração dos blocos do projeto e do código VHDL e o kit de CPLD baseado no componente MAXV para testar a aplicação em hardware. O funcionamento do sistema é mostrado no clipe de vídeo disponível acima.

 

Hierarquia e Lógica de Funcionamento do Sistema

Deseja-se fazer o controle individual, da intensidade dos componentes de cor do LED RGB, que são na verdade três LEDs de cores vermelho, verde e azul, de modo a poder gerar qualquer cor. Os três blocos de PWM, permitem controlar a intensidade de cada cor e podem ser controlados pelo bloco CONTROLE_CORES, onde um conjunto de botões é continuamente verificado (servindo com IHM). O desenvolvimento deste projeto se caracterizou por uma abordagem hierárquica, em que blocos desenvolvidos e testados separadamente são agrupados para a composição de um sistema completo. Os seguintes componentes fazem parte da estrutura do projeto:

  • GERA_CLOCKS, controla a geração dos sinais de clock CLK_IHM e CLK_PWM;
  • CONTROLE_CORES, gerencia a seleção da cor e a razão cíclica dos LEDs;
  • MODULO_PWM, define a intensidade luminosa para um LED.

A figura abaixo mostra o diagrama de blocos do projeto:

diag blocos pwm rgb

 

Figura 1 – Diagrama de Blocos

 

 É possível observar na figura 1, a presença de três instâncias controladas por módulo PWM (uma para cada LED). E a animação a seguir representa um pequeno teste do projeto, onde os botões são pressionados (à esquerda), a bola verde informa qual LED esta selecionado e o resultado é exibido pelas formas de onda (à direita) que representam a razão cíclica da luz dos LEDs RGB:

animacao ledrgb

Figura 2 – Animação

 

Descrição dos Blocos do Projeto 

A seguir apresentamos uma introdução básica do sistema destacando alguns trechos de código.

 

GERA_CLOCKS:

O clock do kit de CPLD possui uma frequência de 24MHz, valor demasiadamente alto para o projeto. Sendo assim, utilizaremos um bloco de prescaler, um divisor de frequência que a partir da entrada de clock do sistema gera os sinais CLK_IHM e CLK_PWM, de menor frequência, que irão sincronizar a monitoração do estado dos botões e o efeito do PWM sobre os sinais de cor do LED. A arquitetura, em VHDL, para o GERA_CLOCKS é mostrado abaixo.

 

Observe que o princípio de funcionamento é bastante simples, sendo descrito a seguir:
O sinal de entrada RSTn é um reset ativo em baixo, e deve ser momentaneamente baixo na partida do sistema, ou quando se deseja reiniciar o sistema.
O sinal CLK_ENABLE, quando em nível alto, habilita o divisor de frequência.
A divisão de frequência é realizada a partir de duas contagens, nas variáveis cnt1 e cnt2, respectivamente associadas aos sinais de saída CLK_PWM e CLK_IHM.
A contagem em cnt1 vai de 0 a 200.000, quando se inverte o estado na saída CLK_PWM. Em duas destas contagens, CLK_PWM completa um período. Sendo assim, sua saída deve ter um período de:
2 * 200.000 * (1/ 24 MHz) = ~16,67 ms, e uma frequência de 1/16.67 ms = 60 Hz.
A contagem em cnt2 é incrementada a cada transição de subida de CLK_PWM, até atingir 15, quando se inverte o estado de CLK_IHM. Assim, em dois ciclos de contagem de cnt2, ou seja, em 30 períodos de CLK_PWM obtem-se um período de CLK_IHM. A duração deste período é de:
2*15*200.000*(1/24 MHz) = 0,25 s, correspondente a uma frequência de 4Hz.
No bloco CONTROLE_CORES, este valor implica em que os botões do sistema serão verificados quatro vezes por segundo.

DECLARAÇÃO:
Entre o begin e a architecture do arquivo de topo do projeto (rgb_teste.vhd), é necessário inserir a declaração do componente. A seguir, a declaração do componente GERA_CLOCKS, em VHDL:

a, sans-serif;”>E a tabela abaixo classifica as portas especificando suas funções:

Nome da Porta Tipo Definição
CLK Entrada Contém o valor do sinal de clock do kit.
CLK_ENABLE Entrada Ativa ou desativa o componente.
RSTn Entrada Botão de reset negado.
CLK_IHM Saída Sinal de clock gerado.
CLK_PWM Saída Sinal de clock gerado.

 

INSTANCIAÇÃO:

Entre o begin e o fim da architecture do arquivo de topo do projeto (rgb_teste.vhd), é preciso inserir a instanciação do componente. A seguir, a instanciação do componente GERA_CLOCKS, em VHDL:

A seguinte tabela classifica as portas, especificando a que sinal cada uma delas é atribuída:

Nome da Porta Atribuíção Justificação
CLK CLK O sinal de clock do componente possui o mesmo valor de CLK (sinal de clock do kit).
CLK_ENABLE ‘1’ A função desta porta é ativar ou desativar o prescaler, neste projeto, seu valor será sempre ‘1’ (habilitada). 
RSTn RSTn O valor deste sinal é o mesmo do botão reset negado.
CLK_IHM CLK_IHM Sinal de saída.
CLK_PWM CLK_PWM Sinal de saída.

 

CONTROLE_CORES:

Este bloco representa a IHM do projeto, e é responsável por verificar o estado dos botões e gerar os sinais de comando que são interpretados pelos módulos PWM para efetuar o controle das cores. A Figura 3 representa os botões da placa que serão utilizados:

botoea

Figura 3 – Botões no Kit

Diferentemente do componente anterior, este bloco não utiliza o sinal de clock do kit para executar sua função, mas utiliza o sinal de clock CLK_IHM que possui uma frequência de 60Hz, gerada no processo GERADOR_CLOCKS do componente GERA_CLOCKS. Este valor de frequência foi escolhido porque é adequado para que o usuário não perceba o “pisca-pisca” dos LEDs. Neste componente há apenas um processo, denominado testa_botoes, onde são feitas as checagens dos botões do kit. A seguir uma lista das funções de cada botão:

  • COR_ANTERIOR: Seleciona a cor anterior da lista.
  • COR_PROXIMA: Seleciona a próxima cor da lista.
  • COR_MAIS: Aumenta a razão cíclica.
  • COR_MENOS: Diminui a razão cíclica.
  • LED_ESTADO: Apaga os LEDs, entretanto, quando liberado, retorna todas as configurações anteriores.
  • RSTn: Altera a cor selecionada para a inicial (azul), e a razão cíclica dos LEDs para 0%.

Observação: Os botões são verificados na borda de subida do clock CLK_IHM, exceto RSTn, pois não necessita de um sinal de clock.

Após as checagens dos botões, o processo testa_botoes gera três sinais, PWM_VERMELHO, PWM_VERDE e PWM_AZUL, valores de oito bits, cada um deles definindo a razão cíclica de seu respectivo LED. Abaixo, o código em VHDL, utilizado para gerar os três sinais:

Primeiramente a porta RSTn é verificada. Se RSTn estiver com o valor zero (ou seja, o botão esta sendo apertado), a variável select_cor é alterada para zero (então a cor selecionada passa a ser azul), e o vetor de três bits var_cor têm todos os seus valores alterados para zero, modificando a razão cíclica de todos os LEDs para 0%.Se RSTn for diferente de zero, então será checada a borda de subida de CLK_IHM e o valor do sinal HABILITA_CLK. Na subida de clock, se habilitado, as seguintes instruções poderão ser executadas:

 

  • Se COR_ANTERIOR estiver pressionado, a variável select_cor será decrementada, selecionando uma nova cor.
  • Se COR_PROXIMA estiver pressionado, a variável select_cor será incrementada, selecionado uma nova cor.
  • Se COR_MAIS estiver pressionado, a variável var_cor  correspondente à cor selecionada é aumentada em 5 unidades, até o máximo de 255. Desta forma, aumenta-se a intensidade luminosa de um dos componentes de cor do LED.
  • Se COR_MENOS estiver pressionado a variável var_cor  é subtraída em 5 unidades, até o mínimo de 0. Desta forma, aumenta-se a intensidade luminosa de um dos componentes de cor do LED.

Quando os botões COR_MAIS ou COR_MENOS são pressionados, a variável que representa a razão cíclica do respectivo LED é modificada em 05 na faixa entre 0 e 255. Como a frequência deste bloco é de 4Hz, cada segundo que um destes botões permanecer pressionado, resultará num aumento/subtração de 20 unidades.

DECLARAÇÃO:
Entre o begin e a architecture do arquivo de topo do projeto (rgb_teste.vhd), é necessário inserir-se a declaração do componente. A seguir, a declaração do componente CONTROLE_CORES, em VHDL:

 

 

A seguinte tabela classifica as portas especificando a que sinais cada uma é atribuída:

Nome da Porta Tipo Definição
CLK Entrada Contém o valor do sinal de clock do componente.
HABILITA_CLK Entrada Ativa ou desativa o componente.
RSTn Entrada Botão de reset negado.
COR_MAIS Entrada Botão que incia as instruções de incremento da intensidade da luz dos LEDs.
COR_MENOS Entrada Botão que incia as instruções de decremento da intensidade da luz dos LEDs.
COR_MENOS Entrada Botão que inicia as instruções de seleção da próxima cor.
COR_ANTERIOR Entrada Botão que inicia as instruções de seleção da cor anterior.
LED_ESTADO Entrada Botão que desliga o LED, enquanto pressionado, e que, quando despressionado, não perde suas configurações anteriores.
PWM_VERMELHO Saída Contém o valor da razão cíclica do LED vermelho.
PWM_VERDE Saída Contém o valor da razão cíclica do LED verde.
PWM_AZUL Saída Contém o valor da razão cíclica do LED azul.
SEL_LEDS Saída Vetor de 3 bits que contém os LEDs RGB que serão acessos.

INSTANCIAÇÃO:

Entre o begin e o fim da architecture do arquivo de topo do projeto (rgb_teste.vhd), é preciso inserir a instanciação do componente. A seguir, a instanciação do componente CONTROLE_CORES, em VHDL:

A seguinte tabela classifica as portas, especificando a que sinal cada uma delas é atribuída:

Nome da Porta Atribuição Justificação
CLK CLK_IHM
O sinal de clock deste componente possui o valor do sinal de clock CLK_IHM.
HABILITA_CLK 1′ A função desta porta é ativar ou desativar o sinal de clock, neste projeto, seu valor será sempre ‘1’ (habilitada). 
RSTn RSTn
O valor deste sinal é o mesmo do botão reset negado.
COR_MAIS COR_MAIS
Valor do botão (pressionado ou não).
COR_MENOS COR_MENOS Valor do botão (pressionado ou não).
COR_PROXIMA COR_PROXIMA Valor do botão (pressionado ou não).
COR_ANTERIOR COR_ANTERIOR Valor do botão (pressionado ou não).
LED_ESTADO LED_ESTADO Valor do botão (pressionado ou não).
PWM_VERMELHO Saída Valor de 8 bits que contêm a intensidade luminosa do LED vermelho.
PWM_VERDE Saída Valor de 8 bits que contêm a intensidade luminosa do LED verde.
PWM_AZUL Saída Valor de 8 bits que contêm a intensidade luminosa do LED azul.
SEL_LEDS Saída Define que LEDs acenderam.

 

MODULO_PWM

Este é um bloco previamente desenvolvido, que gera um sinal PWM. Neste projeto, são utilizadas três instâncias deste componente, uma para cada cor básica (Vermelho, Verde e Azul).

O bloco MODULO_PWM tem três entradas: clock, TAXA e PRESCALER.

  • A entrada TAXA, de oito bits configura a razão cíclica para o sinal de saída PWM, variando de 0% (quando TAXA for zero) a 100% (quando TAXA for “255”).
  • A entrada PRESCALER configura um divisor de frequência para o clock de entrada. Nesta aplicação, com a entrada PRESCALER em zero, o prescaler é desabilitado, e o sinal de clock de entrada determina a frequência do sinal de saída.
  • clock é o clock geral do sistema.

O PWM é gerado através de uma variável de contagem de oito bits, que varia de zero a “255”, sendo incrementada a cada borda de subida do clock de entrada, e zerada instantaneamente ao chegar a “255”. A saída de PWM transita para nível lógico alto quando a contagem é zerada, e para nível lógico baixo quando se iguala ao valor contido em TAXA, ou seja, a frequência do sinal de saída é “1/255” da frequência do clock de entrada, como mostrado na figura abaixo.

A saída do processo GERA_PWM do código é o sinal PRE_PWM, que é transferido à saída PWM do bloco se HABILITA for ‘1’ e INV_PWM zero. Neste projeto estes sinais são constantes, atendendo a ambas as condições, e o PWM é sempre habilitado.

A seguir o arquitetura de GERA_PWM:

 

 

 

DECLARAÇÃO:
Entre o begin e a architecture do arquivo de topo do projeto (rgb_teste.vhd) é necessário inserir a declaração do componente. A seguir, a declaração do componente MODULO_PWM, em VHDL:

A tabela classifica as portas especificando suas funções: 

Nome da Porta Tipo Função
CLK Entrada Contém o valor do sinal de clock do componente.
RSTn Entrada Botão de reset negado.
HABILITA Entrada Ativa ou desativa o processo gera_prescaler.
INV_PWM Entrada Se ativo, inverte o PWM (não utilizado nesta aplicação).
HAB_SAIDAn Entrada Habilita a saída do sinal PWM (não utilizado nesta aplicação).
TAXA Entrada Razão cíclica.
PRESCALER Entrada Número inteiro maior ou igual a 0, que divide o sinal de clock de entrada se maior que zero.
PWM Saída Sinal PWM de saída.

 

INSTANCIAÇÃO:
Entre o begin e o fim da architecture do arquivo de topo do projeto (rgb_teste.vhd) é necessário inserir a instanciação do componente:

*O código e a tabela mostra a instanciação para a cor vermelha apenas. A instanciação das outras duas cores é similar e pode ser vista na arquitetura de topo do projeto.

A seguinte tabela classifica as portas, especificando a que sinal cada uma delas é atribuída:

Nome da Porta Atribuição Justificação
CLK CLK_IHM Contém o valor do sinal de clock do componente.
RSTn RSTn Botão de reset negado.
HABILITA ‘1’ Ativa ou desativa o processo gera_prescaler.
INV_PWM ‘0’ Se ativo, inverte o PWM (não utilizado nesta aplicação).
HAB_SAIDAn ‘0’ Habilita a saída do sinal PWM (não utilizado nesta aplicação).
TAXA PWM_VERMELHO Razão cíclica.
PRESCALER X”00″ Número inteiro maior ou igual a 0, que divide o sinal de clock de entrada se maior que zero.
PWM PWM_COR(2) Sinal PWM de saída.

 

Conclusão

O Controle de LED RGB com PWM é um exemplo simples de aplicação didática de PWM, e pode servir de referência para outros projetos. Ainda, é interessante exemplo da abordagem hierárquica do projeto, um conceito fundamental para o desenvolvimento de projetos avançados em sistemas digitais. A sua implementação no kit de CPLD MAXV do projeto FPGA para Todos é bastante facilitada pelos recursos já disponíveis na placa (LED RGB, botões, oscilador), e ocupa 189 elementos lógicos do CPLD. Os arquivos do projeto são disponibilizados para experimentação dos usuários.

Arquivos Disponíveis para Transferência

Nos arquivos abaixo, o projeto foi compilado para o componente 5M240ZT100C5 de 240 elementos lógicos. O kit de CPLD MAXV também é compatível com o componente 5M570ZT100C5 de 570 elementos lógicos. A adaptação deste projeto para outros componentes é bastante simples.

Projeto RGB_TEST: Projeto

Arquivo POF para gravação: Arquivo para Gravação

 

 

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *