Tôi không có thời gian để giải thích đầy đủ, nhưng tôi có thể cung cấp cho bạn các kiểu lệnh trong sách nấu ăn mà tôi sử dụng trên hộp Linux của mình để lập trình các AVR:
Chuẩn bị
- Trên Ubuntu, đảm bảo một số gói yêu cầu được cài đặt:
sudo apt-get install avr-libc avrdude binutils-avr gcc-avr srecord
tùy chọn đưa vào gdb-avr simulavr
để gỡ lỗi và mô phỏng.
- Tôi bắt đầu tạo một thư mục trong đó tất cả các dự án ATtiny của tôi tìm thấy một ngôi nhà:
mkdir ~/attiny: cd ~/attiny
- Đối với mỗi dự án, tôi tạo một thư mục con chuyên dụng (và tôi không nhớ tên dài):
mkdir waveShare4digit8segmentDisplay; cd waveShare4digit8segmentDisplay
Tạo nguồn
- Chỉnh sửa tệp nguồn bằng trình soạn thảo văn bản yêu thích của bạn:
vi project.cpp
Cài đặt
Các lệnh dưới đây phụ thuộc rất nhiều vào các biến môi trường, để giữ cho việc bảo trì dễ dàng.
- Tên cơ sở của các tệp được sử dụng / tạo:
src=project
- Cờ trình biên dịch phổ biến:
cflags="-g -DF_CPU=${avrFreq} -Wall -Os - Werror -Wextra"
Các biến dưới đây có thể cần phải thay đổi tùy thuộc vào lập trình viên chính xác mà bạn sử dụng. Tham khảo các man
trang để biết chi tiết.
baud=19200
Baudrate lập trình viên của bạn giao tiếp với PC:
programmerDev=/dev/ttyUSB003
Tên thiết bị nơi lập trình viên của bạn được đặt. Kiểm tra dmesg
đầu ra để biết chi tiết.
programmerType=avrisp
Điều này có thể khác nhau cho lập trình viên chính xác của bạn.
Các biến dưới đây phụ thuộc vào bộ điều khiển chính xác mà bạn muốn lập trình:
avrType=attiny2313
Kiểm tra avrdude -c $programmerType
các thiết bị được hỗ trợ.
avrFreq=1000000
Kiểm tra bảng dữ liệu của bộ điều khiển cho đồng hồ mặc định.
Biên dịch
- Bước đầu tiên là tạo một tệp đối tượng:
avr-gcc ${cflags) -mmcu=${avrType) -Wa,-ahlmns=${src).lst -c -o ${src).o ${src).cpp
- Bước thứ hai là tạo tệp ELF:
avr-gcc ${cflags) -mmcu=${avrType) -o ${src).elf ${src).o
- Bước thứ ba là tạo tệp Intel Hex, đây là tệp thực sự được gửi cho lập trình viên:
avr-objcopy -j .text -j .data -O ihex ${src).elf ${src).flash.hex
Lập trình
- Bước cuối cùng là lập trình thiết bị:
avrdude -p${avrType} -c${programmerType} -P${programmerDev} -b${baud} -v -U flash:w:${src}.flash.hex
Makefile
Để thay thế cho việc ghi nhớ các lệnh, tôi đã tạo ra một tệp thực hiện theo ý thích cá nhân của mình, bạn có thể lưu nó dưới tên Makefile
(nhớ thủ đô M
). Nó hoạt động như sau:
make makefile
Chỉnh sửa tệp thực hiện;
make edit
Chỉnh sửa tập tin nguồn;
make flash
Lập trình bộ nhớ flash của thiết bị;
make help
Liệt kê các lệnh khác.
Đây là tệp thực hiện:
baud=19200
src=project
avrType=attiny2313
avrFreq=4000000 # 4MHz for accurate baudrate timing
programmerDev=/dev/ttyUSB003
programmerType=arduino
cflags=-g -DF_CPU=$(avrFreq) -Wall -Os -Werror -Wextra
memoryTypes=calibration eeprom efuse flash fuse hfuse lfuse lock signature application apptable boot prodsig usersig
.PHONY: backup clean disassemble dumpelf edit eeprom elf flash fuses help hex makefile object program
help:
@echo 'backup Read all known memory types from controller and write it into a file. Available memory types: $(memoryTypes)'
@echo 'clean Delete automatically created files.'
@echo 'disassemble Compile source code, then disassemble object file to mnemonics.'
@echo 'dumpelf Dump the contents of the .elf file. Useful for information purposes only.'
@echo 'edit Edit the .cpp source file.'
@echo 'eeprom Extract EEPROM data from .elf file and program the device with it.'
@echo 'elf Create $(src).elf'
@echo 'flash Program $(src).hex to controller flash memory.'
@echo 'fuses Extract FUSES data from .elf file and program the device with it.'
@echo 'help Show this text.'
@echo 'hex Create all hex files for flash, eeprom and fuses.'
@echo 'object Create $(src).o'
@echo 'program Do all programming to controller.'
edit:
vi $(src).cpp
makefile:
vi Makefile
#all: object elf hex
clean:
rm $(src).elf $(src).eeprom.hex $(src).fuses.hex $(src).lfuse.hex $(src).hfuse.hex $(src).efuse.hex $(src).flash.hex $(src).o
date
object:
avr-gcc $(cflags) -mmcu=$(avrType) -Wa,-ahlmns=$(src).lst -c -o $(src).o $(src).cpp
elf: object
avr-gcc $(cflags) -mmcu=$(avrType) -o $(src).elf $(src).o
chmod a-x $(src).elf 2>&1
hex: elf
avr-objcopy -j .text -j .data -O ihex $(src).elf $(src).flash.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex $(src).elf $(src).eeprom.hex
avr-objcopy -j .fuse -O ihex $(src).elf $(src).fuses.hex --change-section-lma .fuse=0
srec_cat $(src).fuses.hex -Intel -crop 0x00 0x01 -offset 0x00 -O $(src).lfuse.hex -Intel
srec_cat $(src).fuses.hex -Intel -crop 0x01 0x02 -offset -0x01 -O $(src).hfuse.hex -Intel
srec_cat $(src).fuses.hex -Intel -crop 0x02 0x03 -offset -0x02 -O $(src).efuse.hex -Intel
disassemble: elf
avr-objdump -s -j .fuse $(src).elf
avr-objdump -C -d $(src).elf 2>&1
eeprom: hex
#avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U eeprom:w:$(src).eeprom.hex
date
fuses: hex
avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U lfuse:w:$(src).lfuse.hex
#avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U hfuse:w:$(src).hfuse.hex
#avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U efuse:w:$(src).efuse.hex
date
dumpelf: elf
avr-objdump -s -h $(src).elf
program: flash eeprom fuses
flash: hex
avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U flash:w:$(src).flash.hex
date
backup:
@for memory in $(memoryTypes); do \
avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U $$memory:r:./$(avrType).$$memory.hex:i; \
done
Nó có thể được dường như cần thiết để chạy avrdude
như root
, nếu điều đó xảy ra nó biện minh cho một câu hỏi trong riêng của mình . Nó có thể được giải quyết với udev
nhưng đòi hỏi một chút thông tin cụ thể từ cách lập trình viên được hệ điều hành nhận ra.
Chào thế giới
Hãy để tôi ném vào một 'Thế giới xin chào' làm cho chân điều khiển 2 (PB3) (ví dụ: ATtiny13, ATtiny45, ATtiny85) chuyển đổi với tần số 1Hz. Gắn một đèn LED và điện trở nối tiếp vào pin và đèn LED sẽ bắt đầu nhấp nháy.
i
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB = 0x08;
while (1) {
PORTB = 0x00; _delay_ms(500);
PORTB = 0x08; _delay_ms(500);
}
}
<ESC>:wq
Làm xong.