51单片机入门_06_流水灯(宏定义;函数定义;延时函数;标准库函数中的循环移位函数及与左移和右移运算符区别;Keil中Debug的用法;单片机小精灵方便延时函数程序生成)

本篇主要介绍程序设计课程,利用LED实现流水灯的效果,也就是实现每个LED灯循环移动点亮。本篇将会介绍一些编程上的知识,利用标准库函数中的循环移位函数实现LED循环移位达到流水灯的效果,循环移位函数与左移和右移运算符的区别及keil中Debug的用法。

文章目录

  • 1. 宏定义
  • 2. 函数的定义
  • 3. 延时函数
  • 4. 标准库函数中的循环移位函数
  • 5. 循环移位函数与左移和右移运算符的区别
  • 6. keil中Debug的用法
  • 7. 单片机小精灵
  • 1. 宏定义

    用define进行宏定义的典型用法 #define uchar unsigned char

    注意宏定义后面不能加分号,它是预处理指令不是语句
    其中用“uchar”直接替换了unsigned char
    此时我们可以用uchar去定义变量类型如:uchar i; 等价于unsigned char i;

    对于上面的宏定义我们是用来给已有数据类型取别名。

    对已有数据类型取别名一般还有使用关键字typedef,定义方法如下:
    typedef 已有数据类型 新的数据类型;(要加分号)

    2. 函数的定义

    函数就是将多条语句集合在一块,来完成一种特定功能。

    函数分为标准函数库,和用户自定义函数。
    标准函数库: keil编译器提供的,不需要用户进行定义。
    自定义函数: 用户根据自己需要编写的函数,它必须在使用前先定义

    自定义函数一般格式为:

    函数类型 函数名 (形式参数表)
    {
    	局部变量定义
    	函数体语句
    }
    

    3. 延时函数

    自定义函数:延时函数delay(毫秒级)

    void delay(unsigned int z)
    {
    	unsigned int x,y;
    	for(x=z;x〉0;x--) //只控制下面一句,无需花括号
    		for(y = 114;y>0;y--);//嵌套循环
    }		
    

    给形参z赋值,如延时100毫秒:delay(100); (根据上面的循环语句,总共会循环11400次,对应时间为100ms,实现软件延时的功能)

    在高级程序中使用delay函数(软件延时)的机会很少,这种方式会耗费CPU时间,我们可以使用定时器或者其他方法来实现延时功能
    后期如果需要使用延时,可以直接将这个函数copy过来,在keil中通过debug查看一次for循环得多长时间,然后加入嵌入的for循环,看嵌入后一次for循环的时间来计算y的值,利用y的值来控制内部for循环一次为1ms。

    4. 标准库函数中的循环移位函数

    标准库函数:intrins.h

    内部函数
    字符型循环左移: _crol_,参与运算的数据是char型的就可以来用执行循环左移,不适用于整型数据,具体使用方法见下面的例子
    字符型循环右移: _cror_,参与运算的数据是char型的就可以来用执行循环右移,不适用于整型数据

    为什么目前常使用char类型,这是因为51单片机中有4组8位的IO口,8位对应一个字节,也就是一个char类型

    #include <intrins.h>
    void tets_crol (void)
    {
    	unsigned char a;
    	unsigned char b;
    	a = 0xFE; //1111 1110
    	b = _crol_(a,1); //b now is 0xFD 二进制为1111 1101,左移一位,最高位移动到最低位
    }
    

    5. 循环移位函数与左移和右移运算符的区别

    使用字符型循环左移:

    #include <intrins.h>
    void tets_crol (void)
    {
    	unsigned char a;
    	unsigned char b;
    	a = 0xFE; //1111 1110
    	b = _crol_(a,1); //b now is 0xFD 二进制为1111 1101
    }
    

    使用左移运算符

    a = 0xFE; //1111 1110
    b = a<<1; //b now is 0xFC 二进制为1111 1100,左移一位,使用0填充最低位
    

    区别:循环左移是把最高位移到最低位上,左移运算符是把最高位移除最低位补0

    6. keil中Debug的用法

    通过以下代码可以实现流水灯的效果,下载到开发板也是可以正常运行的。

    #include <reg52.h>
    #include <intrins.h>
    
    
    #define uint unsigned int
    #define uchar unsigned char
    
    uchar temp; //LED灯相关变量
    
    //毫秒级延时函数定义
    void delay(uint z)
    {
    	uint x,y;
    	for(x = z; x > 0; x--) //只控制下面一句,无需花括号
    		for(y = 114; y > 0; y--);//嵌套循环
    }	
    
    void main()
    {
    	temp = 0xfe; //1111 1110
    	P1 = temp;
    	delay(100);
    	while(1)
    	{
    		temp = _crol_(temp, 1);
    		P1 = temp;
    		delay(100);
    	}
    
    }
    

    下面将如何使用keil中的debug,通过debug功能可以看到IO口执行完每条语句之后的变化

  • 开启debug之前需要修改晶振频率为实际使用时间

  • 在debug之前需要先点击“Rebuild”

  • 以下为开启Debug的按钮:

  • 开启之后界面图如下:可以看到汇编语言代码、寄存器及值、运行时间(运行至当前代码所需时间,通过记录求差值可以得到一段代码运行所需时间)

  • 打开需要观察的P1口的值,通过单步可以看到每一行代码执行后IO口值的变化,同时观察时间变化,如果时间和预期不对应的话,需要检查晶振频率设置是否正确

  • P1的0~7都打钩,表示均为1,这也是前面提到的IO口打开后默认均为1,P1的值等价于0xFF,

  • 可以通过右下角“Watch1”位置添加需要监控的变量,通过右键设置显示的进制。

  • 左上角为"重置",点击左上角的“step”后就会回到程序的起始位置

  • 通过左侧双击可以设置断点

  • 7. 单片机小精灵

    下面的视频介绍了一个延时函数代码生成和多种功能的工具以及为了使得串口的波特率更为精准采用了晶振频率为11.05926的晶振

    作者:十月旧城

    物联沃分享整理
    物联沃-IOTWORD物联网 » 51单片机入门_06_流水灯(宏定义;函数定义;延时函数;标准库函数中的循环移位函数及与左移和右移运算符区别;Keil中Debug的用法;单片机小精灵方便延时函数程序生成)

    发表回复