Linux下的MCU开发之AVR系列1-avr系列的编译烧录调试方法

来源:互联网 发布:淘宝竹月阁 编辑:程序博客网 时间:2024/04/30 07:16
Linux下的MCU开发之AVR系列1

-avr系列的编译烧录调试方法

Galaxy2416

联系方式:sunxiao.gin@gmail.com

附件内容: 程序源码,Makefile模板,相关文档。

http://download.csdn.net/detail/galaxy_blue/4277134附件网址~

系列说明:LINUX下程序开发具有一定的成熟性,包括大部分的MCU,FPGA,DSP甚至PCB制图等都是可行的。本系列将针对AVR系列的MCU,而后的系列将会对Linux下的其他方面内容进行探讨。

本文环境如下:

OS系统:ubuntu 12.04(原为10.04最近升级了)

编译器 :avr-gcc

烧录软件 :avrdude

调试软件:avarice ,GDB和ddd (可视界面)

开发板:

1.  xplain(xmega128a1)无法调试,只能烧录,因为官方没有公开其调试的协议。

2.  Mega16开发板。

仿真器or烧录器:dragon和usbasp(使用较多)

程序编写:Vim(升级版的记事本,很好用,很推荐)

 

关于使用前的准备和说明

  至于为什么要使用linux下开发avr,原因主要是因为比较有趣。其次便是win下的环境用起来其实并不是很方便。IAR是付费软件(但是的确好用),Avr-studio虽然是免费版,不过优缺点是太过庞大,并且是以vc2010为基础开发,这个也就算不上真正的免费了。至于win-avr其实蛮不错的。win下也可以搭建如下环境。

准备:

软件安装,软件安装建议使用ubuntu的软件中心,比较方便。需要avr-gcc,avrdude,avarice,gdb,ddd即可了。文本编辑什么都行。可以集成在codeblocks和eclipse里面。Codeblocks如此做用起来感觉不错,eclipse需要配置,但原理都是一样的。

对于命令行可以如下安装

[plain] view plaincopy
  1. sudo apt-get install gcc-avrbinuilts-avr avr-libc  
  2. sudo apt-get installvim  
  3. sudo apt-get installavrdude  

强烈建议顺便安上手册

[plain] view plaincopy
  1. sudo apt-get installavrdude-doc  
  2. sudo apt-get installavarice  
  3. sudo apt-get installgdb  
  4. sudo apt-get installddd  

然后就都安装完毕了。下一步就可以开始了。

开始之前需要先写一个.c的程序

代码会在文章最后和附件里提出。这是一个很简单让一个led亮的程序。

之后介绍一个makefile的东西,此物是简化操作流程的一个东西。让敲好多行命令才能完成的只需简单的一句话就行了。附件里会包含一个makefile的模板,是winavr下模板改的可用版。具体的内容是如何实现的,可以翻阅官方makefile手册和百度,谷歌。

简单介绍Makefile里面的几个命令,有过经验可以无视

[plain] view plaincopy
  1. AVRDUDE_PROGRAMMER = usbasp  
  2. #dragon_jtag  
  3. AVRDUDE_PORT = usb   # programmer connected to serial device  
  4. AVRDUDE_WRITE_FLASH = -Uflash:w:$(TARGET).hex  
  5. AVRDUDE_FLAGS = -p $(MCU) -P$(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)  
  6. AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)  
  7. AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)  
  8. AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)  

上面这些都是定义变量,makefile里的

[plain] view plaincopy
  1. program: $(TARGET).hex $(TARGET).eep  
  2.      $(AVRDUDE)$(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)  

当我们输入make program时就会执行上面这句之前的都不用关心了。翻译过来就变成了(如果叫main.hex)

[plain] view plaincopy
  1. avrdude -P usb -p m16 -c usbasp -U flash:w:main.hex  

就是说用usb下的usbasp烧录m16的flash,内容为main.hex

如果用dragon的话一般用jtag就是-c dragon_jtag。具体可以查看avrdude手册。

了解之后先打开终端,找到.c文件目录下。Makefile文件放在同一目录下

根据需要更改其内容

输入make

便会输出一些信息,最后会有提示编译成功

之后就可以烧录了

烧录之前看一下烧录器是否在

输入lsusb

显然,usbasp存在。那么输入sudo make program

会在很快的时间内烧录成功,比win快的多。最后提示你烧录成功

至于debug,usbasp没有这个功能。需要用dragon的jtag。

住:Debug其实不是很推荐使用,虽然比较高效,建议利用串口的信息输入输出(以后会介绍),这是因为在进入系统的嵌入后,常规的debug经常会无法使用。

实际的命令会是

[plain] view plaincopy
  1. avarice -g -j usb --erase --program --filemain.hex :4242  

不过如果makefile里已经写好的话直接输入sudo make debug就可以了

下面为命令的结果

现在属于等待GDB,可视化的话就是DDD的状态中了

比如在gdb.conf中添加

 

file main.elf

target remotelocalhost:4242

启动DDD

ddd–-debugger “avr-gdb -x gdb.conf”

也可以手起动,然后配置,ui界面比较友好。

还有一句话。makefile里面已经把上步骤都做好了~当然会根据需求要求更改的。尤其是debug的时候。

总结:本文所说有些简略了,Linux开发的困难主要在于搭建环境,因此需要多看一下相关的官方手册。

 

测试代码:

main.c

[cpp] view plaincopy
  1. // avr-gcc application builder : 2011-11-1   
  2. // Target : M16  
  3. // Crystal: 12.000Mhz  
  4.   
  5. #include <avr/io.h>  
  6. #include <util/delay.h>  
  7. #define SET(a,b) a|(1<<b)  
  8. #define CLR(a,b) a &~(1<<b)  
  9. void port_init(void)  
  10. {  
  11.  DDRA  = 0xff;//将PA0定义为输出  
  12.  PORTA = 0xff;  
  13.  PORTB = 0x00;  
  14.  DDRB  = 0x00;  
  15.  PORTC = 0x00; //m103 output only  
  16.  DDRC  = 0x00;  
  17.  PORTD = 0x00;  
  18.  DDRD  = 0x00;  
  19. }  
  20.   
  21. //call this routine to initialize all peripherals  
  22. void init_devices(void)  
  23. {  
  24.  //stop errant interrupts until set up  
  25.  //CLI(); //disable all interrupts  
  26.  port_init();  
  27.  MCUCR = 0x00;  
  28.  GICR  = 0x00;  
  29.  TIMSK = 0x00; //timer interrupt sources  
  30. // SEI(); //re-enable interrupts  
  31.  //all peripherals are now initialized  
  32. }  
  33.   
  34. //  
  35. void main(void)  
  36. {  
  37.  init_devices();  
  38.  //insert your functional code here...  
  39.  PORTA = CLR(PORTA,3);  
  40.  while(1);  //程序挂起        
  41. }