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:
  1. // Conexões dos LEDS  
  2. #define LED_DDR     DDRB  
  3. #define LED_PORT    PORTB  
  4. #define LED1        _BV(PB7)  
  5. #define LED2        _BV(PB6)  
  6. #define LED3        _BV(PB5)  
  7. #define LED4        _BV(PB4)  
  8. #define LED5        _BV(PB3)  
  9. #define LED6        _BV(PB2)  
  10. #define LED7        _BV(PB1)  
  11. #define LED8        _BV(PB0)  
  12.   
  13. // Conexão das Teclas  
  14. #define TEC_DDR     DDRD  
  15. #define TEC_PORT    PORTD  
  16. #define TEC_PIN     PIND  
  17. #define TEC1        _BV(PD4)  
  18. #define TEC2        _BV(PD5)  
  19. #define TEC3        _BV(PD6)  
  20. #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:
  1. // Inicia as direçoes dos pinos de conexão dos LEDs  
  2. LED_DDR |= 0xFF;  
  3.       
  4. // LEDs Apagados  
  5. LED_PORT = 0x00;  
  6.   
  7. // Liga pullup das teclas  
  8. TEC_DDR &= ~(TEC1|TEC2|TEC3|TEC4);  
  9. 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:
  1. for (;;)  
  2. {  
  3.     if ((TEC_PIN & TEC1) == 0)  
  4.         LED_PORT |= LED1;  
  5.     else  
  6.         LED_PORT &= ~LED1;  
  7.       
  8.     if ((TEC_PIN & TEC2) == 0)  
  9.         LED_PORT |= LED2;  
  10.     else  
  11.         LED_PORT &= ~LED2;  
  12.   
  13.     if ((TEC_PIN & TEC3) == 0)  
  14.         LED_PORT |= LED3;  
  15.     else  
  16.         LED_PORT &= ~LED3;  
  17.   
  18.     if ((TEC_PIN & TEC4) == 0)  
  19.         LED_PORT |= LED4;  
  20.     else  
  21.         LED_PORT &= ~LED4;  
  22. }  
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:
  1. GCCFLAGS=-g -Os -Wall -mcall-prologues -mmcu=atmega32  
  2. LINKFLAGS=-Wl,-Map,${PROGNAME}.map  
  3.   
  4. PROGNAME=Teste1  
  5.   
  6. all: ${PROGNAME}.hex  
  7.   
  8. program: ${PROGNAME}-upload  
  9.   
  10. ${PROGNAME}.hex: ${PROGNAME}.c jymega32.h  
  11.  avr-gcc ${GCCFLAGS} ${LINKFLAGS} -o ${PROGNAME}.o ${PROGNAME}.c  
  12.  avr-objcopy -O ihex ${PROGNAME}.o ${PROGNAME}.hex  
  13.    
  14. ${PROGNAME}-upload: ${PROGNAME}.hex  
  15.  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: