来自小型AVR程序的大十六进制文件

jbl*_*lew 2 c microcontroller avr winavr avr-gcc

我现在正在教我的朋友如何编程AVR微控制器.我们编写了这个小程序,它发送简单的莫尔斯式代码.

问题是,在用AVR-GCC和WinAVR对其进行加工后,a.out文件几乎为30KB,十六进制文件为11KB,因此它不适合attiny2313闪存.

WinAVR CMD: avr-gcc -mmcu=attiny2313 -Os -g main.c

AVR-objcopy命令: avr-objcopy -O ihex a.out a.hex

这是代码:

#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>

void light_led(int ms)
{
 PORTD |= (1 << 4);
 _delay_ms(ms);
 PORTD &= ~(1 << 4);
 _delay_ms(1000);
}

void send_char(int c)
{
 int i;
 for(i = 1; i < 8+1; i++)
 {
  if(c & i) light_led(1000);
  else light_led(500); 
 }
}

int main(void)
{
 DDRD |= (1 << 4);
 //char text[] = {'t', 'e', 's', 't'};
 int i;
 for(i = 0; i < 1; i++) send_char(100);//text[i]);
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

Unc*_*leO 5

hex文件的大小具有误导性.它需要43个字节来表示16,所以你的可执行文件实际上只有4 K.

也就是说,将参数传递给_delay_ms()函数确实会破坏代码.我试过这个,总是用一个常量调用延迟函数,可执行文件小于190个字节.

#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>

void light_led(int longer)
{
 PORTD |= (1 << 4);
 if(longer) _delay_ms(1000);
 else  _delay_ms(500);
 PORTD &= ~(1 << 4);
 _delay_ms(1000);
}

void send_char(int c)
{
 int i;
 for(i = 1; i < 8+1; i++)
 {
  if(c & i) light_led(1);
  else light_led(0); 
 }
}

int main(void)
{
 DDRD |= (1 << 4);
 //char text[] = {'t', 'e', 's', 't'};
 int i;
 for(i = 0; i < 1; i++) send_char(100);//text[i]);
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 要扩展该答案,请从AVR libc [手册](http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html)"为了使这些函数按预期工作,编译器优化必须启用时,延迟时间必须是编译时已知常量的表达式.如果不满足这些要求,产生的延迟将更长(并且基本上不可预测),并且应用程序[..]将经历严重的由链接到应用程序的浮点库例程代码膨胀"这基本上就是您在代码中看到的内容. (2认同)