找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2200|回复: 4
收起左侧

单片机学习实验笔记:移位操作程序

  [复制链接]
ID:815459 发表于 2022-10-8 00:27 | 显示全部楼层 |阅读模式
单片机源程序如下:
  1. #include<reg52.h>  //52系列单片机头文件
  2. #include<intrins.h>  //包含 _crol_   _cror_(函数所在的头文件 )
  3. #define uint unsigned int  //宏定义
  4. #define uchar unsigned char  //宏定义
  5. uchar a; //定义a变量, 用来给P1赋值

  6. //********延时程序***********
  7. void delayms(uint xms)
  8. {
  9. uint i,j;
  10.    for(i=xms;i>0;i--)        //i=xms 即延时约xms亳秒
  11.       for(j=110;j>0;j--);
  12. }
  13. //***************************
  14. void main() //主函数
  15. {
  16. a=0xfe;            //二进制: 1111 1110
  17. while(1)  //大循环
  18. {
  19. P1=a; //点亮发光管
  20. delayms(500);  //延时500毫秒
  21. a=_cror_(a,1);        //将a循环右移1位后再赋给a
  22. }
  23. }
  24. //循环右移,被移出的放在最高位,来回循环,所以P1中0和1的位数不变,只
  25. //是改变了0 1的位置,因此在右移过程中亮灯的数量不变,只是改变了亮灯的位置.



  26. /***********************************************************************************************************************
  27. 知识点:移位操作
  28. (1)        左移:C52中操作符为“<<”,每执行一次左移指令,被操作的数将最高位移入单片机PSW寄存器的
  29. CY位,CY位中原来的数丢弃,最低位 补0,其他位依次向左移动一位,如实例一所示:

  30. //***** 实例一 ****   8位单片机一次就只能处理8位二进制 , 如果是16位单片机,一次能处理16位。
  31. void main() //主函数
  32. {
  33. a=0xcc;         //二进制:移位前 CY  1100 1100    从CY位,最高位到最低位         , 十六进制为:0xcc
  34. while(1)  //大循环
  35. {
  36. P1=a<<1; //二进制:左移后为:0001 1001 1000  十六进制为:0x198
  37.     //(利用前面所学的实验板8灯来认证,P1:刚好有8个灯显示后8位,从低位至高位显示,0为灯亮。 a的变量,左移1位。)
  38. }
  39. }

  40. ***********************************************************************************************************************
  41. (2)右移:C52中操作符为“>>”,每执行一次右移指令,被操作的数将最低位移入单片机PSW寄存器的
  42. CY位,CY位中原来的数丢弃,最高位 补0,其他位依次向右移动一位,如实例二所示:

  43. //***** 实例二 ****
  44. void main()    //主函数
  45. {
  46.     a=0xcc;         //二进制:移位前 1100 1100  CY    ; 最高位到最低位 CY位 ; 十六进制为:0xcc
  47. while(1)   //大循环
  48.     {
  49.     P1=a>>1; //二进制:右移后为:0110 0110 0      十六进制为:0x66
  50. //P1=0x66; //(利用前面所学的实验板8灯来认证,P1:因为只有8个灯显示前8位,从低位至高位显示,0为灯亮。 a的变量,右移1位。)
  51.     }
  52. }

  53. *************************************************************************************************************************
  54. (3)循环左移:最高位移入最低位,其他位依次向左移一位。C语言中没有专门的指令,通过移位指令与简单逻辑运算可以
  55. 实现循环左移,或直接利用C52库中自带的函数  _cril_  实现; 如实例三所示:

  56. //***** 实例三 ****
  57. void main() //主函数
  58. {
  59. a=0xfe;            //二进制: 1111 1110
  60. while(1)  //大循环
  61. {
  62. P1=a; //点亮发光管
  63. delayms(500);  //延时500毫秒
  64. a=_crol_(a,1);        //将a循环左移1位后再赋给a
  65. }
  66. }
  67. /*
  68. a=_crol_(a,1);        语句;因为_crol_是一个带返回值的函数,本句在执行时,先执行等号右边的表达式,即a这个变量循环左移
  69. 一位,然后将结果再重新赋给a变量,如a初值为0xfe,二进制为1111 1110,执行此函数时,将它循环左移一位后为1111 1101,即
  70. 0xfd,然后再将0xfd重新赋值给a变量,等while(1)中的最后一条语句执行完后,将返回到while(1)中的第一语句重新执行,此
  71. 时a的值变成了0xfd.
  72. ***************************************************************************************************************************/      
  73. /*
  74. (4)循环右移:最低位移入最高位,其他位依次向右移一个位。C语言中没有专门的指令,通过移位指令与简单逻辑运算可以
  75. 实现循环右移,或直接利用C52库中自带的函数  _crir_  实现; 如实例四所示:

  76. //***** 实例四 ****
  77. void main() //主函数
  78. {
  79. a=0xfe;            //二进制: 1111 1110
  80. while(1)  //大循环
  81. {
  82. P1=a; //点亮发光管
  83. delayms(500);  //延时500毫秒
  84. a=_cror_(a,1);        //将a循环右移1位后再赋给a
  85. }
  86. }
  87. //循环右移,被移出的放在最高位,来回循环,所以P1中0和1的位数不变,只
  88. //是改变了0 1的位置,因此在右移过程中亮灯的数量不变,只是改变了亮灯的位置.
  89. *************************************************************************************************************************/
  90. /*************************************************************************************************************************
  91. 知识点:PSW寄存器.
  92.    PSW (Program Status Word)全称为程序状态字标志寄存器,是一个8位寄存器,位于单片机内的特殊功能寄存器区,字节地址D0H,用
  93. 来存放运算结果的一此特征,如有无进位,借位等,使用汇编编程时PSW寄存器很有用,但在利用C语言编程时,编绎器会自动控制该寄存器,
  94. 很少人为操作它,只需要简单了解即可,其每位的具体含义如下:
  95.      
  96.          _D7___D6___D5___D4____D3____D2___D1___D0__
  97. PSW        | CY | AC |        F0 | RS1 | RS0 | OV        | …  | P   |  D0H
  98.          ——————————————————————————————————————————

  99.   ① CY 进位标志位,它表示运算是否有进位(或借位)。如果操作结果在最高位有进位(加法)或者借位(减法),则该位为1,否则为0。
  100.   ② AC 辅助进位标志,又称半进位标志,它指两个8位数运算低四位是否有半进位,即低四位相加(或相减)是否进位(或借位),如
  101. 有AC为1,否则为0。
  102.   ③ F0  由用户使用的一个状态标志位,可用软件来使它置1或清0,也可由软件来测试它,以控制程序的流向。
  103.   ④ RS1、RS0  4组工作寄存器区选择控制位,在汇编语言中这两位用来选择4组工作寄存器区中的哪一组为当前工作寄存区。
  104.   ⑤ OV  溢出标志位,反映带符号数的运算结果是否有溢出。有溢出时,此位为1,否则为0。
  105.   ⑥ P 奇偶标志位,反映累加器ACC内容的奇偶性,如果ACC中的运算结果有偶数个1(如11001100B,其中有4个1),则P为0,否则P为1。  

  106. *************************************************************************************************************************/

复制代码

您可以直接复制以上代码到Keil或者下载创建好的Keil工程文件: 以上代码.7z (14.04 KB, 下载次数: 15)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1047308 发表于 2022-10-11 20:08 | 显示全部楼层
学习使人进步
回复

使用道具 举报

ID:260656 发表于 2022-10-19 10:22 | 显示全部楼层
请问这个延时的时间误差大吗?
回复

使用道具 举报

ID:815459 发表于 2022-10-21 00:18 | 显示全部楼层
zzzzz8840 发表于 2022-10-19 10:22
请问这个延时的时间误差大吗?

延时的时间误差没计算过,好像是用的晶振和下载到单片机的设置有关。
回复

使用道具 举报

ID:911522 发表于 2023-1-3 08:22 | 显示全部楼层
zzzzz8840 发表于 2022-10-19 10:22
请问这个延时的时间误差大吗?

采用定时器或计数器中断,时间精准点
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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