=======Programação ATmega328======= Nesta página são apresentados os conceitos básicos para programação de [[ATmega328|ATmega328 e ATmega328p]] utilizando programação em C e o compilador AVR-GCC. A programação é feita tipicamente em um Sistema Operacional Linux. Informações sobre a compilação e gravação de códigos aqui mostrados nos microcontroladores podem ser encontradas em [[Gravação ATmega328]]. ---- =====Portas Digitais===== Uma das coisas mais essenciais na programação de um microcontrolador é a entrada e a saída de sinais por seus pinos. No ATmega328 e ATmega328p, temos três portas programáveis: * Porta B, com 8 pinos; * Porta C, com 7 pinos; * Porta D, com 8 pinos. Contudo, não conseguimos trabalhar com pinos separadamente durante a programação, ficando restritos à configuração da porta inteira. Então precisamos fazer operações bit a bit que envolvam bytes representantes das portas e não bits representantes dos pinos (no que é conhecido como [[Máscara de bits]]). Para realizar as ações descritas abaixo, é necessário importar no código a biblioteca de entrada e saída do microcontrolador, ou seja, é necessário incluir no início do código: #include ====Direção do Pino==== Antes de usar um pino, é necessário definir se o mesmo é um pino de entrada ou de saída (se vai ler o sinal elétrico no pino ou se vai escrever um sinal elétrico no mesmo). Esta definição é feita através da configuração dos registradores DDR (Data Direction Register), sendo que há um registrador DDR para cada uma das portas: DDRB, DDRC e DDRD. Um bit configurado como '0' significa que o pino correspondente será de entrada, e caso seja configurado como '1', será saída. Exemplo: caso queiramos que o pino B4 seja configurado como entrada, colocaremos '0' no bit 4 de DDRB; caso queiramos que seja saída, colocaremos '1' no bit 4 de DDRB. Desta forma, se formos configurar o pino C3 como entrada e o pino D7 como saída, usaremos os comandos DDRC &= ~(1< Onde DDC3 e DDD7 são macros definidas pela biblioteca AVR e representam, respectivamente, 3 e 7. De forma semelhante, há DDB1, DDB5, DDC0 e DDD4. Os números puros poderiam ser usados no lugar das macros, mas elas são usadas para fins de legibilidade de código, pois explicitam qual pino está sendo configurado. Informações sobre os operadores bit a bit e sobre as máscaras de bits podem ser encontradas [[https://www.embarcados.com.br/bits-em-linguagem-c/|aqui]]. ====Entrada Digital==== Depois que a direção de um pino foi configurada como entrada, o valor presente nele pode ser lido. Assim como na definição da direção da porta, as operações de leitura também são feitas usando bytes, então precisaremos usar a máscara de bits na posição desejada para ler apenas o valor de interesse. Para ler o conteúdo de uma porta, usaremos os registradores PIN, sendo que há um registrador desse para cada porta: PINB, PINC e PIND. Além disso, usaremos uma variável do tipo ''unsigned char'' para receber o dado de uma porta, pois é a representação que temos de um byte "puro" na linguagem C. Desta forma, se formos ler o conteúdo presente no pino C3, usaremos os comandos DDRC &= ~(1< Onde PINC3 é uma macro de valor 3 semelhante às macros de DDR. Uma coisa que vale notar é que, seguindo o código anterior, se houver sinal baixo na entrada C3, valorLido == 0. Contudo, se houver sinal alto na entrada C3, valorLido == 0b00001000 == 8. Isso não será problema caso valorLido seja usado como variável condicional, pois o C interpreta variável igual a 0 como Falso e variável diferente de 0 como Verdadeiro. Contudo, é preciso cuidado na hora de fazer comparações entre valores lidos de pinos ou caso deseja-se (por algum motivo obscuro) fazer operações matemáticas usando o valor. ====Saída Digital==== Depois que a direção de um pino foi configurada como saída, pode-se definir qual valor ele terá. Assim como na definição da direção da porta, as operações de escrita também são feitas usando bytes, então precisaremos usar a máscara de bits na posição desejada para escrever apenas no valor de interesse. Para escrever em uma porta, usaremos os registradores PORT, sendo que há um registrador desse para cada porta: PORTB, PORTC e PORTD. Assim como na definição de direção do pino e na leitura do mesmo, há macros usadas para o número do pino a ser escrito, elas são como PB2, PC5 e PD0. Desta forma, se quisermos escrever '1' no pino B0 e escrever '0' no pino D7, usaremos os comandos DDRB |= (1< ---- =====Facilitando a Vida===== Muitas vezes é chato ficar fazendo as máscaras de bits na mão, então há maneiras de simplificar a programação. ====_BV==== A primeira delas é a macro de sistema ''_BV'', acrônimo de "Bit Value". Por exemplo, ''_BV(6)'' é igual a ''(1<<6)''. Desta forma, se quisermos configurar o pino D0 como saída, podemos escrever: DDRD |= (1< E se quisermos configurar o pino B3 como entrada, podemos escrever: DDRB &= ~(1< ====Macros extras==== Além da macro ''_BV'', podemos definir nossas próprias macros. Algumas macros úteis que podem ser definidas no código são: [(siteEmbarcados>> title : Bits em Linguagem C publisher : Embarcados url : https://www.embarcados.com.br/bits-em-linguagem-c/ )] #define setBit(valor,bit) (valor |= (1< =====Referências===== ~~REFNOTES~~