找回密码
 立即注册
查看: 1387|回复: 13

C251(KEIL5)和C51(KEIL4),写程序要注意那些问题?两者有啥不同

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2024-05-10 16:29:53

12

主题

66

回帖

285

积分

中级会员

积分
285
发表于 2024-5-10 16:22:52 来自手机 | 显示全部楼层 |阅读模式
以前用Keil4写8位单片机程序时发现“随心所欲”例如
void  ting ()
{
   unsigned char code SJH[]=
     {
         0x00,…………………
        
      };
}
这段程序用到8位单片机(KEIL4),种运行没有问题
用在KEIL5(32单片机),出现问题卡死在数组中
把数组定义在函数外就没有问题了!
发现KEIL5好严格,例如赋值定时器等寄存器时必须先高八位后低八位,否则就不正常
还有例如s=x<<8+y,KEIL4中可以完成代替
s=x*256+y,
在KEIL5中严格按符号优先级处理,这么写就不行必须是s=(x<<8)+y

本人小学毕业学历,不知道还有哪些严格的东西,
从8位到32位软件特别注意的有哪些!欢迎告知
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:403
  • 最近打卡:2025-04-29 08:28:43

12

主题

319

回帖

2017

积分

金牌会员

积分
2017
发表于 2024-5-10 17:21:53 | 显示全部楼层
我小学肄业,一起学习、成长
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:425
  • 最近打卡:2025-05-04 00:16:27
已绑定手机

19

主题

3191

回帖

4930

积分

论坛元老

积分
4930
发表于 2024-5-10 19:02:36 来自手机 | 显示全部楼层
没涉及到单片机寄存器等的操作,都是编程规范的问题。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:521
  • 最近打卡:2025-05-04 09:27:07
已绑定手机

46

主题

1694

回帖

2602

积分

金牌会员

积分
2602
发表于 2024-5-10 20:25:16 | 显示全部楼层
stc8h的改stc32按手册来就可以啊
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:524
  • 最近打卡:2025-05-04 02:13:29

10

主题

1161

回帖

5133

积分

论坛元老

积分
5133
发表于 2024-5-10 20:42:46 | 显示全部楼层
移植 C51 代码的技巧
移植 C51 代码时必须考虑 C51 和 C251 之间的一些细微差别。 以下是您可能遇到的典型问题的列表:

C251 生成的代码独立于当前选择的寄存器组,并且不再需要 C51 指令 NOAREGS 和 REGISTERBANK。
内存类型说明符必须设置在变量类型后面,如下例所示:


int xdata value;    /* correct in both C51 and C251     C51 和 C251 均正确           */
xdata int value;    /* illegal: old C51 form; not supported by C251  非法:旧的C51表格; C251 不支持 */



pdata 内存类型通常在 251 MCU 的 PAGE 模式下出现问题,在新应用中应忽略。
printf 库函数和变量参数列表默认提升为 int,即使对于 char 和 unsigned char 变量也是如此。 以下 printf 语句在 C251 中生成不正确的结果。


unsigned char c1;

     /* works in C51, but gives wrong output in C251:  在 C51 中工作,但在 C251 中给出错误的输出:      */
printf ("%bx %bi", c1, 1);

     /* C251 defaults to int and does not need the b prefix:  C251默认为int,不需要b前缀:*/
printf ("%x %i", c1, 1);

     /* the following two forms work in both C51 and C251:  以下两种形式在 C51 和 C251 中均适用:  */
printf ("%bx %bi", (unsigned char) c1, (char) 1);  /* optimal code */
printf ("%x %i", (unsigned int) c1, (int) 1);      /* passes int   */



const 常量
在 ANSI C 中,const 类型限定符用于定义和访问常量且不可更改的对象。 用 const 声明的变量不能在程序中赋值。

C251 编译器符合 const 对象的 ANSI 定义。

单独使用 const 类型限定符声明的变量存储在与其定义关联的内存区域(data、idata、xdata 等)中。
要在 ROM 中定位的变量必须使用代码内存类型进行声明。 例如:

code char test[] = "This is a text string";

用 const 声明的变量存储在 xCONST 内存类中(内存类型 data、idata、xdata 除外)。 有关详细信息,请参阅段命名约定。

对于使用 const 声明的变量,编译器会生成存储在 ROM 中的映像。 不会为此类变量生成运行时初始化记录。

常量对象通常在定义时(在源文件中)进行初始化。 以下变量定义显示了创建常量对象的不同方法:

/* table is stored in the default memory class */
const int table[2][2] =
  { 0, 2, 4, 8 };

/* pi is stored in the HCONST memory class */
const float far pi = 3.1415927;

/* The string is stored in the HCONST memory class */
printf("This is a string\n");

当使用指向 const 对象的指针时,可以在指针定义中排除 const 类型限定符。 例如:

const unsigned char mask [] =
  { 0x01, 0x02, 0x04, 0x08 };

const unsigned char *cp = mask;
      unsigned char  *p = mask;  /* same as cp */

.
.
.

*p = 'a';    // This has no effec.
             // It causes no error or warning

*cp = 'a';   // This causes an error


如上所示,可以将 const 对象(mask)的地址分配给非常量指针(p),然后使用该指针更改 const 对象。 在这种情况下,编译器确实会生成写入 const 对象的代码。 此代码的效果未定义,可能会或可能不会按预期工作。

不可能使用 const 指针来更改它指向的 const 对象。 尝试这样做将导致编译器错误。

const 的一个有趣的用途是定义一个不可更改的指针。 例如:

char text [] = "This is a string.";
char *const textp = text;
.
.
.
*textp = 'A';    // This is OK (it changes text[0])
textp++;         // This causes an error (textp is const)
textp[2] = 'B';  // This is OK (it changes text[2])

回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:402
  • 最近打卡:2025-05-04 00:31:29

2

主题

170

回帖

208

积分

中级会员

积分
208
发表于 2024-5-10 21:30:41 来自手机 | 显示全部楼层
对着手册避开差异就行了…
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:397
  • 最近打卡:2025-05-04 04:44:01

16

主题

702

回帖

2482

积分

金牌会员

积分
2482
发表于 2024-5-11 07:34:46 | 显示全部楼层
死机是不是数组占用内存溢出了
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2024-05-10 16:29:53

12

主题

66

回帖

285

积分

中级会员

积分
285
发表于 2024-5-12 22:52:21 来自手机 | 显示全部楼层
angmall 发表于 2024-5-10 20:42
移植 C51 代码的技巧
移植 C51 代码时必须考虑 C51 和 C251 之间的一些细微差别。 以下是您可能遇到的典型 ...

谢谢你的付出,又学习了点
也提醒大家从8位到32位的朋友
1.寄存器赋值严格做到先赋值高八位
再赋值低八位
2.函数名哪怕是乱写,也不要和单片机头文件里已经定义的名字一样
3.定义在程序区的数组,一定要先在使用函数外定义好再使用,否则用不了卡死在数组里
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2024-05-10 16:29:53

12

主题

66

回帖

285

积分

中级会员

积分
285
发表于 2024-5-12 22:54:31 来自手机 | 显示全部楼层
小飞侠 发表于 2024-5-11 07:34
死机是不是数组占用内存溢出了

不是,改为临时变量型数组也可以,或在函数外先定义好也可以
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:524
  • 最近打卡:2025-05-04 02:13:29

10

主题

1161

回帖

5133

积分

论坛元老

积分
5133
发表于 2024-5-13 08:01:46 | 显示全部楼层
创隆*** 发表于 2024-5-12 22:52
谢谢你的付出,又学习了点
也提醒大家从8位到32位的朋友
1.寄存器赋值严格做到先赋值高八位

很高兴能帮助到你。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-4 10:31 , Processed in 0.120489 second(s), 106 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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