我目前正在用C语言编程8051 µC(使用编译器:Wickehaeuser µC / 51),因此,我认为哪种方法最好是对结构进行伪造。在我目前的情况下,我有一个时间/日期结构,应该通过SFR从RTC中使用当前的时间/日期来构造。
所以我正在考虑执行此操作的最佳方法:
以下代码仅是一个示例(注意:当前在最后一次打印中出现故障,不会打印出atm值)
哪种方法最好?
typedef struct {
unsigned char foo;
unsigned char bar;
unsigned char baz;
}data_foo;
data_foo get_foo_create(void) {
data_foo foo;
foo.bar = 2;
return foo;
}
void get_foo_by_reference(data_foo *foo) {
// Read values e.g. from SFR
foo->bar = 42; // Just simulate SFR
}
data_foo *get_foo_pointer_return(data_foo *foo) {
// Read values e.g. from SFR
(*foo).bar = 11; // Just simulate SFR
return foo;
}
/**
* Main program
*/
void main(void) {
data_foo struct_foo;
data_foo *ptr_foo;
seri_init(); // Serial Com init
clear_screen();
struct_foo = get_foo_create();
printf("%d\n", struct_foo.bar);
get_foo_by_reference(&struct_foo);
printf("%d\n", struct_foo.bar);
ptr_foo = get_foo_pointer_return(&ptr_foo);
//Temp problem also here, got 39 instead 11, tried also
//printf("%d\n",(void*)(*ptr_foo).bar);
printf("%d\n",(*ptr_foo).bar);
SYSTEM_HALT; //Programm end
}
答案 0 :(得分:1)
在8051上,应避免尽可能使用指针。相反,通常最好(如果您负担得起)拥有一些可以由各种功能操作的全局结构。具有“从地址加载thing
到地址”和“将thing
存储到地址”的功能,以及操纵thing
的各种功能,比尝试拥有可以操作的功能要有效得多。在“就地”类型的对象上。
对于您的特定情况,我建议您使用一个名为“时间”的全局结构,以及一个名为“ ldiv_acc”的全局联合,该联合将一个uint_32,两个uint16_t和四个uint8_t组合在一起。我还建议您使用一个“ ldivmod”函数,该函数将ldiv_acc中的32位值除以8位参数,然后将商保留在ldiv_acc中并返回余数,还有一个“ lmul”函数将32- ldiv_acc中的位值乘以8位值。自从对8051进行编程以来已经有很长的时间了,所以我不确定编译器需要什么来生成良好的代码,但是与8x8乘法和除法的组合相比,32x32的除法和乘法将是昂贵的。 / p>
在8051上,代码如下:
uint32_t time;
uint32_t sec,min,hr;
sec = time % 60;
time /= 60;
min = time % 60;
time /= 60;
hr = time % 24;
time /= 24;
可能很大且很慢。使用类似的东西:
ldiv_acc.l = time;
sec = ldivmod(60);
min = ldivmod(60);
hr = ldivmod(24);
易于紧凑,如果您很聪明,也可以更快。如果速度真的很重要,则可以利用divmod60(h + 256 * l)等于h * 4 + divmod60(h * 16 + 1)的事实,使用函数执行divmod6,divmod10,divmod24和divmod60。 。第二次加法可能会产生大于256的值,但是如果这样做,则应用相同的技术将使操作数低于256。将unsigned char
除以另一个unsigned char
的速度要快于涉及{{1}的除法}。