【AVR】Linux


手邊還沒有機器,先寄一下筆記。

【目的】

  • 建立 Linux 下的編譯環境。

【環境】

  • Ubuntu 10.04

【步驟】

  1. 安裝 toolchain/tools
    $ apt-get install gcc-avr binutils-avr avr-libc
  2. 安裝燒錄軟體
    $ apt-get install avrdude
  3. 範例程式 (hello.c)
    #define F_CPU 1000000UL
    #include <util/delay.h>
    #include <avr/io.h>
    #include <stdio.h>
    
    int main (void)
    {
      printf("Hello AVR\n");
      return (0);
    }
  4. 編譯 
    $ avr-gcc -mmcu=atmega48 -Wall -Os -o hello.o hello.c
  1. 輸出成用來燒錄的 hex 檔
    $ avr-objcopy -j .text -O ihex hello.o hello.hex
  2. 燒錄驗證 (無機器,尚未驗證)
    $ avrdude -p m48 -c usbasp -e -U flash:w:hello.hex

【補充】

  1. Toolchain
      • GCC
        • /usr/bin/avr-gcc
      • Include
        • /usr/lib/avr/include
          • avr/io.h
            利用 ifdef 來決定要帶入的 include file,如 ATmega48 為 iom48.h。
            #ifndef _AVR_IO_H_
            #define _AVR_IO_H_
            
            #include <avr/sfr_defs.h>
            
            #if defined (__AVR_AT94K__)
            
            #elif defined (__AVR_ATmega48__)
            #  include <avr/iom48.h>
            ...
            #endif
          • util/delay.h
            提供現成的 _delay_us()/_delay_ms() 函數,
            F_CPU 值是 1000000UL。
            void
            _delay_ms(double __ms)
            {
              uint16_t __ticks;
              double __tmp = ((F_CPU) / 4e3) * __ms;
              if (__tmp < 1.0)
                __ticks = 1;
              else if (__tmp > 65535)
              {
                //__ticks = requested delay in 1/10 ms
                __ticks = (uint16_t) (__ms * 10.0);
                while(__ticks)
                  {
                    // wait 1/10 ms
                    _delay_loop_2(((F_CPU) / 4e3) / 10);
                    __ticks --;
                  }
                return;
              }
              else
                __ticks = (uint16_t)__tmp;
              _delay_loop_2(__ticks);
            }
            
            void
            _delay_us(double __us)
            {
              uint8_t __ticks;
              double __tmp = ((F_CPU) / 3e6) * __us;
              if (__tmp < 1.0)
                __ticks = 1;
              else if (__tmp > 255)
              {
                _delay_ms(__us / 1000.0);
                return;
              }
              else
                __ticks = (uint8_t)__tmp;
              _delay_loop_1(__ticks);
            }
      • Library
        • /usr/lib/gcc/avr/4.3.4/
  2. (TBD)

【參考】

 

Ed32. Copyright 2008 All Rights Reserved Revolution Two Church theme by Brian Gardner Converted into Blogger Template by Bloganol dot com