terça-feira, dezembro 18, 2012

JY-MCU Minimum AVR System Board - Programando com o avr-gcc toolchain

Continuando o nosso exame da "Minimum AVR System Board", vamos experimentar desenvolver um primeiro programa em C para ela, usando o avr-gcc toolchain.

Como já vimos antes, o avr-gcc toolchain inclui um compilador C, uma biblioteca e alguns utilitários para o desenvolvimento de programas para os microcontroladores AVR. Como primeiro exemplo, vou fazer um software simples que acende um LED quando um botão é pressionado.

O primeiro passo é examinar o circuito (que está nos arquivos do blog) e preparar um arquivo de include que indique quais os registradores e bits estão conectados aos LEDs e botões:
// Conexões dos LEDS
#define LED_DDR     DDRB
#define LED_PORT    PORTB
#define LED1        _BV(PB7)
#define LED2        _BV(PB6)
#define LED3        _BV(PB5)
#define LED4        _BV(PB4)
#define LED5        _BV(PB3)
#define LED6        _BV(PB2)
#define LED7        _BV(PB1)
#define LED8        _BV(PB0)

// Conexão das Teclas
#define TEC_DDR     DDRD
#define TEC_PORT    PORTD
#define TEC_PIN     PIND
#define TEC1        _BV(PD4)
#define TEC2        _BV(PD5)
#define TEC3        _BV(PD6)
#define TEC4        _BV(PD7)
O programa em si é bastante simples. Na iniciação, precisamos programar os pinos onde estão os LEDs como saída e ligar os resistores de pull-up nos pinos onde estão os botões:
// Inicia as direçoes dos pinos de conexão dos LEDs
LED_DDR |= 0xFF;
    
// LEDs Apagados
LED_PORT = 0x00;

// Liga pullup das teclas
TEC_DDR &= ~(TEC1|TEC2|TEC3|TEC4);
TEC_PORT |= TEC1|TEC2|TEC3|TEC4;
Feito isto, quando um botão estiver apertado o bit correspondente estará em zero; no lado dos LEDs o valor 1 corresponde a aceso. O código abaixo implementa a lógica desejada de forma bem direta:
for (;;)
{
    if ((TEC_PIN & TEC1) == 0)
        LED_PORT |= LED1;
    else
        LED_PORT &= ~LED1;
    
    if ((TEC_PIN & TEC2) == 0)
        LED_PORT |= LED2;
    else
        LED_PORT &= ~LED2;

    if ((TEC_PIN & TEC3) == 0)
        LED_PORT |= LED3;
    else
        LED_PORT &= ~LED3;

    if ((TEC_PIN & TEC4) == 0)
        LED_PORT |= LED4;
    else
        LED_PORT &= ~LED4;
}
Vamos usar um makefile para gerar o programa. Nada de novo aqui, exceto pela parte de gravação do software, que veremos no próximo post:
GCCFLAGS=-g -Os -Wall -mcall-prologues -mmcu=atmega32
LINKFLAGS=-Wl,-Map,${PROGNAME}.map

PROGNAME=Teste1

all: ${PROGNAME}.hex

program: ${PROGNAME}-upload

${PROGNAME}.hex: ${PROGNAME}.c jymega32.h
 avr-gcc ${GCCFLAGS} ${LINKFLAGS} -o ${PROGNAME}.o ${PROGNAME}.c
 avr-objcopy -O ihex ${PROGNAME}.o ${PROGNAME}.hex
 
${PROGNAME}-upload: ${PROGNAME}.hex
 bootloadHID ${PROGNAME}.hex
Executando o make o programa é compilado e linkado e o hex correspondente é gerado.

Falta ver como gravar este hex no ATmega32. Poderíamos regravar toda a flash com o USBtinyISP ou outro programador, mas veremos no próximo post como usar o bootloader que vem de fábrica para gravar a aplicação conectando a placa diretamente a um PC.

Os projeto completo está nos arquivos do blog, em jymega32_teste1.zip.

Nenhum comentário: