第二次作业解答

3. 在C51中为何要尽量采用无符号的字节变量或位变量?

答:C51的基本数据类型主要有字符型char、整型int和长整型long,又可分别分为有符号signed和无符号unsigned。MCS-51单片机是8位机,本身不支持有符号运算。若变量使用有符号格式,C51编译器要进行符号位检测并需调用库函数,生成的代码比无符号长得多,占用的存储空间会变大,程序运行速度会变慢,出错的机会也会变多。MCS-51单片机主要用于实时控制,变量一般为8bit无符号格式,16bit较少,有符号和有小数点的数值计算也较少,因此,在已知变量长度和正整数的情况下,应尽量采用无符号格式:unsigned char。

错误:
主要是没有看懂题目的侧重点,基本答成为什么尽量采用字节变量或变量,而对为什么无符号没有涉及。
比如:采用无符号的字节变量或位变量可提高代码效率的方法就是减小变量的长度,使用ANSI C 编程时,一般习惯于对变量使用 int 类型,而对于像 80C51 这类 8 位的单片机来说这是一种极大的浪费。80C51 单片机机器指令只支持字节和位变量,所以应该仔细考虑所声明的变量值的可能的取值范围,然后选择合适的变量类型。尽可能地选择变量类型为char、unsigned;
或者:在char、int、和long int三种类型的变量中char型最短,long int型最长。能使用长度短的类型变量,尽量使用段类型的变量,这样可以提高代码效率。

4. 为了加快程序的运行速度,C51中频繁操作的量应定义在哪个存储区?

答:访问内部存储器比访问外部存储器快很多,同时,写外部存储器的寻址指令相对要复杂些,因而,为了加快程序的运行速度,C51中频繁操作的量应定义在片内RAM中,简化编程,提高存储速度,进而加快程序的运行速度。

错误:
(1)根据前面的讨论,你在哪里讨论的?麻烦抄的时候认真一点;
(2)推荐读者按 data→idata→pdata→xdata 的顺序使用存储器,当然要记得在idata 空间中留出足够的堆栈空间。你自己不是读者吗? 这一句好像是题目也没有多少关系?

6. 如何定义C51的中断函数?

答:80C51 的中断系统十分重要,C51 编译器允许在 C 语言源程序中声明中断和编写中断服务程序,从而减轻了采用汇编程序编写中断服务程序的烦琐程度。通过使用 interrupt 关键字来实现。定义中断服务程序的一般格式如下: 
void 函数名()interrupt n [using m]
中断函数没有返回值,即使强制定义一个返回值,也不会得到一个正确的结果,因此一般将中断函数的返回类型定义为void。
中断函数不能进行参数传递,其无论包含任何的参数声明,都将导致编译错误,因而其不能包含形参。
关键字 interrupt 后面的 n 是中断号,n 的取值范围为 0~31。编译程序从 8n+3 处产生中断向量,即在程序存储器 8n+3 地址处形成一条长跳转指令,转向中断号 n 的中断服务程序。中断号对应着 IE 寄存器中的使能位,换句话说 IE 寄存器中的 0 位对应着外部中断 0,相应的外部中断 0 的中断号是 0。
using m 指明该中断服务程序所对应的工作寄存器组,取值范围为 0~3。指定工作寄存器组的缺点是所有被中断调用的过程都必须使用同一个寄存器组, 否则参数传递会发生错误。通常不设定 using m,除非保证中断程序中未调用其他子程序。    
使用 C51 编写中断服务程序,程序员无须关心 ACC、B、DPH、DPL、PSW 等寄存器的保护,C51 编译器会根据上述寄存器的使用情况在目标代码中自动增加压栈和出栈。

错误:
(1)只答:80C51 的中断系统十分重要,C51 编译器允许在 C 语言源程序中声明中断和编写中断服务程序,从而减轻了采用汇编程序编写中断服务程序的烦琐程度。这只是回答了为何定义中断函数而不是如何定义中断函数;
(2) using m 写成using n,和中断号重复,不符合使用习惯;
(3) 没有回答m和n的取值方法;
(4)没有回答返回类型为什么是void,为什么没有形参,为什么m通常不设定;

7. 写出完成下列要求的C程序。

(1)将地址为4000H的片外数据存储单元内容,送入地址为30H的片内数据存储单元中。

void main()
 {
  unsigned char xdata *xdp;
  unsigned char data *dp;
  xdp=0x4000;
  dp=0x30;
  *dp=*xdp;
 }
(2)将地址为4000H的片外数据存储单元内容,送入地址为3000H的片外数据存储单元中。
void main()
 {
  unsigned char xdata *xdp1;
  unsigned char xdata *xdp2;
  xdp1=0x4000;
  xdp2=0x3000;
  *xdp2=*xdp1;
 }
(4)将片内数据存储器中的地址为30H与40H的单元内容交换。
void main()
 {
  unsigned char data *dp1,dp2;
  unsigned char data temp;
  dp1=0x30;
  dp2=0x40;
  temp=*dp1;
  *dp1=*dp2;
  *dp2=temp;
 }

错误:
(1)没有看懂题目,直接照抄例题4.2;
(2)只写个别语句,没有写完整的程序;
(3)采用宏定义方式时没有引用库函数;