我在AVR的微控制器上写了一个程序。它应该检查实际温度并在7段显示器上显示。这就是我所遇到的问题:我制作了一个所有变量都参考温度(温度,指针位置,符号和单位)的结构,并看到了例如执行时间。除非使用正常局部变量,否则除以10或mod 10要长得多。我不知道为什么。我使用的是Atmel Studio 6.2。
struct dane
{
int32_t temperature;
int8_t pointer;
int8_t sign;
int8_t unit;
};
//************************************
//inside function of timer interrupt
static struct dane present;
//*****************************
//tested operations:
present.temperature % 10; //execution time: ~380 processor's cycles, on normal local variable ~4 cycles.
present.temperature /= 10; //execution time: ~611 cycles
我给你这个功能,我使用它和一些汇编代码。
ISR(TIMER0_OVF_vect)
{
static int8_t i = 4;
static struct dane present;
if(i == 4 && (TCCR0 & (1 << CS01)))
{
i = 0;
present = current;
if(present.temperature < 0)
present.temperature = -present.temperature;
}
if((TCCR0 & ((1 << CS00) | (1 << CS02))) && i != 0)
{
i = 0;
}
if(present.unit == current.unit) //time between here and fist instruction in function print equals about 300 cycles.
{
print((i * present.sign == 3 && present_temperature % 10 == 0) ? 16 : present_temperature % 10, displays[i], i == present.pointer);
}
else
{
print(current.unit, displays[i],0);
if(i == 4)
{
i = 3;
TCCR0 = (1 << CS01);
present.unit = current.unit;
}
}
present.temperature /= 10;
i++;
}
最后一条指令前的汇编代码:
present.temperature /= 10;
0000021F LDI R28,0x7D Load immediate
00000220 LDI R29,0x00 Load immediate
00000221 LDD R22,Y+0 Load indirect with displacement
00000222 LDD R23,Y+1 Load indirect with displacement
00000223 LDD R24,Y+2 Load indirect with displacement
00000224 LDD R25,Y+3 Load indirect with displacement
00000225 LDI R18,0x0A Load immediate
00000226 LDI R19,0x00 Load immediate
00000227 LDI R20,0x00 Load immediate
00000228 LDI R21,0x00 Load immediate
00000229 RCALL PC+0x01AC Relative call subroutine
0000022A STD Y+0,R18 Store indirect with displacement
0000022B STD Y+1,R19 Store indirect with displacement
0000022C STD Y+2,R20 Store indirect with displacement
0000022D STD Y+3,R21 Store indirect with displacement
我不能将int16_t用于温度,因为我在内部使用相同的结构来转换传感器的温度,当我乘以适当数量的10时,它更容易操作带小数部分的数字。
答案 0 :(得分:0)
你的时间一定有问题:
present.temperature % 10; //execution time: ~380 processor's cycles, on normal local variable ~4 cycles.
present.temperature /= 10; //execution time: ~611 cycles
对于32位值的模10操作永远不会在AVR的4个时钟周期内发生。 380个周期听起来很多,但对于32:32的分组操作更为现实。我担心即使AVR上的整数除法也会花很多时间用长整数。
对模块静态变量的操作需要更长的时间是很自然的,因为它们必须被取出并存储在RAM中。与寄存器变量相比,每个字节可能需要10个额外的时钟周期(局部变量通常在寄存器中。结构中的变量在这种情况下不应该改变时序(指向结构的指针可能有一个效果)。
了解正在发生的事情的唯一真正方法是查看编译器在每种情况下生成的汇编代码。
而且,请在您的问题中包含两个案例的最小但完整的示例。然后更容易看出是否有明显的错误。
如果您对提高代码速度感兴趣,建议您尝试使用int16_t作为温度。您的温度测量动态范围几乎不超过12位(例如,对于-100°C .. + 300°C之间的温度,这将是0.1°C。)因此16位整数应该足够了。