health 发表于 2024-8-30 12:33:07

初试AI8051U,感觉251指令比51强大很多,可惜被Keil限制了手脚。

keil c51用着一直没问题,c251用一下感觉让人有点怀疑。


有几个小例子请专家帮忙指点
问题1

void test1(void)
{
      unsigned char i8;
      unsigned int i16;
      unsigned long i32;
      
      i8 = 255;
      i16 = 12345;
      i32 = 70000;
      printf("%bu %u %lu\n", i8, i16, i32);
}

上面的printf输出结果是错误的,printf的参数u8类型不可用%bu输出,会导致后续所有输出出错。
u8和u16均用%d才可正确输出。

在c51中,单字节变量在printf中要用%bd。C251即使弃用b前缀也可以,但是在keil c251的帮助文件和例子中,都是规定用%bd。
Note
[*]The optional characters l or L may immediately precede the type character to respectively specify long types for d, i, u, o, x, and X.
[*]The optional characters b or B may immediately precede the type character to respectively specify char types for d, i, u, o, x, and X.



问题2
函数内局部变量不能用code属性。

void test(void)
{
      unsigned char code TAB = {1,2,3,4,5,6,7,8};
      
      unsigned char i, value;
      
      for(i=0; i<8; i++)
      {
                value = TAB;
                printf("TAB[%d] = %d\n", i, value);
      }
}

上述程序在C51中运行无问题,在C251中编译通过但运行出错,看C编译后的汇编代码就很离谱,其向FF地址区域即CODE区域写数据。
将这句unsigned char code TAB = {1,2,3,4,5,6,7,8};放在函数外,即变为全局变量,结果就对了。
另外,在函数内用const unsigned char TAB = {1,2,3,4,5,6,7,8};这样运行结果是对的,但是不会将数组放在code区,而是放在data区然后用代码逐个赋初值。

问题3
sbit LED1 = P1^0;
LED1 = !LED1;
LED1 = ~LED1;


关于两种取反的区别,之前已有专家提过了,这里就不多做解释了。


感觉现在STC,内部人才济济,能够做出异常强大的芯片设计,但受限于编译器落后,很多技能无法施展。

health 发表于 2024-8-30 13:27:49

C51好歹有bug还修复一下。

神农鼎 发表于 2024-8-30 13:48:28

从 SDCC-AI8051U-8Bit 出发,到 SDCC-AI8051U-32Bit
===总会有代替 KEIL C251 的路

health 发表于 2024-8-30 14:19:56

C51 C251没有long long类型,32位整数乘以32位整数结果只保留低32位。
MDU32应该是为了兼容keil的接口,把MDU32的设计也带偏了。
32位*32位结果应该是64位,丢弃高32位,只保留低32位,算得再快也没用。

就比如1位数乘1位数,结果应该保留十位和个位。
只保留1位结果,
就像9 x 9 = 1;(81保留个位)
7 x 8 = 6;(56保留个位)
结果不对,没啥价值。

zxcv1973 发表于 2024-8-30 16:54:50

第2个问题应该这样:const unsigned char code TAB = {1,2,3,4,5,6,7,8};
251架构和51不同,code空间也是可写的,想不可写就要加const,完全用51的方式代入就可能会出错

health 发表于 2024-8-30 18:04:16

code区域可写应该不可能。这种情况编译器直接在常量区定义数据就可以,没必要编译出来一大坨代码。

zxcv1973 发表于 2024-8-30 19:06:40

health 发表于 2024-8-30 18:04
code区域可写应该不可能。这种情况编译器直接在常量区定义数据就可以,没必要编译出来一大坨代码。 ...

没什么不可能,251指令集架构是可以写code代码区的,甚至RAM区也可以运行代码

zxcv1973 发表于 2024-8-30 19:12:50

code区只是指FF0000-FFFFFF这段区域,这段区域在251架构中又没规定不可写,并且还提供有可写指令,以前无内置闪存的251这段区域就是可写的

health 发表于 2024-8-30 19:35:30

本帖最后由 health 于 2024-8-30 19:50 编辑

keil软仿真,如果写ROM区域,它会报错,停在那里。
实物芯片没法弹出窗口报错,一般就忽略过去。

llyymm 发表于 2024-9-21 18:42:30

感觉C251强大,但是BUG有点多啊
页: [1] 2
查看完整版本: 初试AI8051U,感觉251指令比51强大很多,可惜被Keil限制了手脚。