====== LED ======
//Conhecimento prévio:
[HW][[en:hardware:homelab:digi]],
[ELC][[en:electronics:led_resistor]],
[AVR][[en:avr:registers]], [AVR] [[en:avr:io]],
[LIB][[en:software:homelab:library:bit]], [LIB][[en:software:homelab:library:pin]]//
===== Teoria =====
[{{ :examples:digi:led:led_picture.jpg?150|LED de pernas (5 mm)}}]
Um diodo de emissão de luz é um semicondutor que emite luz quando a tensão é aplicada. A sigla para diodo emissor de luz é LED (light-emitting diode). Existem diferentes combinações de cores de diodos, os díodos também podem emitir luz branca. Como um diodo normal, o LED tem dois contatos - ânodo e cátodo. Em desenhos do ânodo é marcado como "+" e cátodo como "-".
[{{ :examples:digi:led:led_designator.png?150|Esquema simbólico do LED e a sua polarização}}]
Quando a tensão é aplicada, o ânodo de um LED está ligado à tensão positiva e o cátodo à tensão negativa. A tensão do LED depende da cor do diodo emissor de luz: comprimento de onda maior (vermelho) ~ 2 V, comprimento de onda menor (azul) ~ 3 V. Normalmente, a alimentação de um LED não é mais do que um par de dezenas de miliwatts, o que significa que a corrente elétrica tem de estar na mesma gama. Ao aplicar uma maior tensão ou corrente o LED pode queimar.
Se os LEDs são usados especialmente para iluminar, é aconselhável usar circuitos eletrônicos especiais que regulem a corrente e voltagem adequada para LEDs. No entanto LEDs são muitas vezes utilizados como indicadores e são alimentados directamente a partir dos pinos do microcontrolador. Uma vez que a tensão de alimentação dos microcontroladores é geralmente mais elevada do que a tensão dos LEDs, deve haver uma resistência ligada em série com o LED, o que limita a corrente e cria a necessária queda de tensão. Instruções para calcular a resistência apropriada podem ser encontradas no capítulo eletrônica.
Os LEDs são produzidos numa variedade de embalagens. LEDs com pés mais comuns têm 3 mm ou 5 mm de diâmetro e dois longos pinos conectores de metal. O pino mais longo é o ânodo, o mais curto é o cátodo. OS LEDs montados em superficie (SMD - Surface Mounted Device) têm um símbolo em forma de T na parte inferior para indicar a polaridade, em que a cobertura do T significa a localização do ânodo e o pólo marca o cátodo.
[{{ :examples:digi:led:led_pin_markings.png?200|Polaridade dos LEDs de pernas e SMD}}]
===== Prática HomeLab =====
O módulo de controle do controlador HomeLab tem um único indicador LED, cujo ânodo está ligado através de uma resistência a uma fonte de alimentação e o cátodo está ligado ao pino do controlador. A fim de ligar e desligar este LED, o pino do LED deve ser definido como saída e configurado como baixo ou alto em conformidade. O que significa que se o pino está configurado como alto, o LED está desligado e se o pino é configurado como baixo, o LED está ligado. Basicamente, seria possível ligar o LED também de modo que o ânodo estivesse ligado ao pino do microcontrolador, e o cátodo ligado à terra (também teria de haver uma resistência em algum lado) - nessa situação, quando o pino é configurado como alto, o LED brilha e quando o pino é configurado como baixo, o LED desliga-se.
Todos os exemplos práticos para o kit HomeLab, piscar de LED incluído, usam a biblioteca de pinos do HomeLab. A biblioteca de pinos inclui o tipo de dados //pino//, que contém os endereços dos registos relacionados com pino e a máscara de bits do pino. Se for criada uma variável do tipo pino no programa e inicializa-la usando a macro função PIN, o pino pode ser usado livremente ao longo do programa inteiro com esta variável (PIN) sem usar os registradores.
Aqui estão 2 exemplos de programas, que estão fazendo exatamente a mesma coisa, mas um foi criado com base na biblioteca de HomeLab, o outro não. A depuração LED, led_debug na biblioteca HomeLab, tem sido descrito como PB7 (HomeLab I e II) e PQ2 (HomeLab III). O LED de depuração está fisicamente localizado no módulo do controlador.
// HomeLab Controller module LED test program, which
// is based on HomeLab library
#include
// LED pin configuration.
pin led_debug = PIN(Q,2);
// Main program
int main(void)
{
// Configuring LED pin as an output
pin_setup_output(led_debug);
// Lighting up LED
pin_clear(led_debug);
}
// HomeLab II Controller module LED test program, which
// accesses registers directly
#include
// Main program
int main(void)
{
// Configuring LED pin as an output
DDRB |= (1 << 7);
// Lighting up LED
PORTB &= ~(1 << 7);
}
O primeiro exemplo utiliza a biblioteca de pinos (ficheiro //pin.h//). Primeiro, uma variável do tipo pino chamada //led_debug// é criada no programa, que contém informações sobre o pino de LED. No programa principal este pino será definido como saída usando a função //pin_setup_output//. Depois disso o pino é configurado como baixo pela função //pin_clear//. Como resultado o LED acenderá. No segundo exemplo não são usadas quaisquer variáveis, a configuração da saída LED e iluminação será feita alterando valores de direção de dados da porto B e registros de saída. O leitor que sabe mais sobre avisos AVR, nota que em ambos os exemplos não há necessidade de dar comando ao LED de luz, porque o valor de saída padrão do AVR é 0 de qualquer maneira, mas aqui é feito por motivos de correção educativa.
Qual a diferença entre a utilização da biblioteca e dos registros? A diferença está no conforto - a biblioteca é mais fácil, porque não é necessário saber os nomes dos registos e os seus efeitos. O benefício mais importante da biblioteca é a adaptabilidade. Usando registros, é necessário alterar nomes e máscaras de bits dos registros ao longo do programa inteiro, a fim de alterar pinos. Ao usar a biblioteca, só necessita ser feito no início do programa, onde o pino variável é inicializado. Usando registros tem uma vantagem enganadora - o uso de pino é direto e não é feito através da memória do programa ou funções que consomem tempo. No entanto, versões mais recentes do compilador AVR-CCG são tão inteligentes que transformam funções de biblioteca para exatamente os mesmos comandos diretos para a manipulação de registros como ela teria sido feito diretamente no programa. Deve ser dito que os compiladores podem otimizar o código apenas quando se trata de variáveis únicas constantes, não voláteis que mudam durante a execução ou com matrizes.
O próximo código do programa é parcialmente biblioteca operacional de pinos. O seu objectivo é explicar os procedimentos com variáveis de pinos. Pode não ser compreensível para os iniciados por usar apontadores de linguagem C que não são abordados neste livro, mas uma grande quantidade de materiais sobre ponteiros podem ser encontrados em livros ou na internet.
// Defining the Pins inside the pin struct
// pin name = PIN(PORT LETTER, PIN NUMBER IN PORT);
pin led_green = PIN(H,5);
// Configuring pin as output
inline void pin_setup_output(pin pin){
bitmask_set(*pin.ddr, pin.mask);
}
// Setting pin high
inline void pin_set(pin pin){
bitmask_set(*pin.port, pin.mask);
}
// Setting pin low
inline void pin_clear(pin pin){
bitmask_clear(*pin.port, pin.mask);
}
Além do módulo do controlador, os LEDs são também localizados no módulo da placa de interface do utilizador. Eles estão ligados eléctricamente, da mesma forma do LED do módulo Controlador, o que significa que o cátodo está ligado ao pino AVR. Para mais informações consulte o guia do módulo de hardware.
Além dos comandos //pin_set// e //pin_clear//, também pode usar os comandos //led_on// e //led_off//para controlar os pinos LED. A seguinte tabela mostra as constantes de LEDs que são descritas na biblioteca e os correspondentes pinos de módulo controlador. LEDs verdes, amarelos e vermelhos estão localizados no módulo de interface do utilizador.
^Nome da constante^Nome alternativo^Pino HomeLab I & II^Pino HomeLab III^Descrição^
|led_debug|LED0|PB7|PQ2| LED azul no módulo do controlador|
|led_green|LED1|PC3|PH5| LED verde|
|led_yellow|LED2|PC4|PH4| LED amarelo|
|led_red|LED3|PC5|PH3| LED vermelho|
Um programa exemplo baseado na biblioteca HomeLab:
// LED test program for HomeLab User interface module
#include
// Main program
int main(void)
{
// Configuring LED pins as an output
pin_setup_output(led_red);
pin_setup_output(led_yellow);
pin_setup_output(led_green);
// Lighting up red and green LED
led_on(led_red);
led_on(led_green);
// Turn off yellow LED
led_off(led_yellow);
}