找回密码
 立即注册
查看: 858|回复: 11

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

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-01 23:18:33

15

主题

139

回帖

979

积分

高级会员

积分
979
发表于 2024-8-30 12:33:07 | 显示全部楼层 |阅读模式
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[8] = {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[8] = {1,2,3,4,5,6,7,8};放在函数外,即变为全局变量,结果就对了。
另外,在函数内用const unsigned char TAB[8] = {1,2,3,4,5,6,7,8};这样运行结果是对的,但是不会将数组放在code区,而是放在data区然后用代码逐个赋初值。

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


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


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

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-01 23:18:33

15

主题

139

回帖

979

积分

高级会员

积分
979
发表于 2024-8-30 13:27:49 | 显示全部楼层
C51好歹有bug还修复一下。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15632
发表于 2024-8-30 13:48:28 | 显示全部楼层
从 SDCC-AI8051U-8Bit 出发,到 SDCC-AI8051U-32Bit
===总会有代替 KEIL C251 的路
回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-01 23:18:33

15

主题

139

回帖

979

积分

高级会员

积分
979
发表于 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保留个位)
结果不对,没啥价值。
回复 支持 反对

使用道具 举报 送花

2

主题

185

回帖

1048

积分

金牌会员

积分
1048
发表于 2024-8-30 16:54:50 | 显示全部楼层
第2个问题应该这样:const unsigned char code TAB[8] = {1,2,3,4,5,6,7,8};
251架构和51不同,code空间也是可写的,想不可写就要加const,完全用51的方式代入就可能会出错
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-01 23:18:33

15

主题

139

回帖

979

积分

高级会员

积分
979
发表于 2024-8-30 18:04:16 来自手机 | 显示全部楼层
code区域可写应该不可能。这种情况编译器直接在常量区定义数据就可以,没必要编译出来一大坨代码。
回复 支持 反对

使用道具 举报 送花

2

主题

185

回帖

1048

积分

金牌会员

积分
1048
发表于 2024-8-30 19:06:40 | 显示全部楼层
hea*** 发表于 2024-8-30 18:04
code区域可写应该不可能。这种情况编译器直接在常量区定义数据就可以,没必要编译出来一大坨代码。 ...

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

使用道具 举报 送花

2

主题

185

回帖

1048

积分

金牌会员

积分
1048
发表于 2024-8-30 19:12:50 | 显示全部楼层
code区只是指FF0000-FFFFFF这段区域,这段区域在251架构中又没规定不可写,并且还提供有可写指令,以前无内置闪存的251这段区域就是可写的
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-01 23:18:33

15

主题

139

回帖

979

积分

高级会员

积分
979
发表于 2024-8-30 19:35:30 | 显示全部楼层
本帖最后由 health 于 2024-8-30 19:50 编辑

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

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:322
  • 最近打卡:2025-05-02 10:02:36
已绑定手机

21

主题

487

回帖

1041

积分

金牌会员

积分
1041
发表于 2024-9-21 18:42:30 | 显示全部楼层
感觉C251强大,但是BUG有点多啊
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 03:15 , Processed in 0.139699 second(s), 100 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表