Proteus + Keil单片机仿真教程(三)简易流水灯

一、实例目的

  • 熟悉Protues电路原理图绘制
  • 熟悉Keil程序编写编译方法
  • 熟悉Keil C51 延时程序的用法
  • 熟悉Keil C51 位移的方法
  • 熟悉单片机引脚的控制方法

二、程序示例图

 

 三、绘制原理图

略,本节可以继续使用上节用的原理图,具体参考:

Proteus + Keil单片机仿真教程(二)炫彩灯_爱折腾的博客-CSDN博客

四、程序代码:

  1. 传统方式

这里可以继续沿用上节的方法,每个LED发光二极管点亮并熄灭,间隔为100ms,代码如下:

//添加头文件,C51必要文件,主要定义的是51/52系列单片机
#include "reg52.h"
//引用延时函数
void Delay1MS(unsigned int t);
//定义引脚,这里定义P0引脚
sbit P00 = P0^0;
sbit P01 = P0^1;
sbit P02 = P0^2;
sbit P03 = P0^3;
sbit P04 = P0^4;
sbit P05 = P0^5;
sbit P06 = P0^6;
sbit P07 = P0^7;

int main(void){
	//进入循环
	while(1){
		//点亮并熄灭P00,P00点亮0.5s
		P00 = 0;
		Delay1MS(500);
		P00 = 1;
		Delay1MS(100);
		
		//点亮并熄灭P01
		P01 = 0;
		Delay1MS(100);
		P01 = 1;
		Delay1MS(100);
		
		//点亮并熄灭P02
		P02 = 0;
		Delay1MS(100);
		P02 = 1;
		Delay1MS(100);
		
		//点亮并熄灭P03
		P03 = 0;
		Delay1MS(100);
		P03 = 1;
		Delay1MS(100);
		
		//点亮并熄灭P04
		P04 = 0;
		Delay1MS(100);
		P04 = 1;
		Delay1MS(100);
		
		//点亮并熄灭P05
		P05 = 0;
		Delay1MS(100);
		P05 = 1;
		Delay1MS(100);
		
		//点亮并熄灭P06
		P06 = 0;
		Delay1MS(100);
		P06 = 1;
		Delay1MS(100);
		
		//点亮并熄灭P07
		P07 = 0;
		Delay1MS(100);
		P07 = 1;
		Delay1MS(100);
		
		//所有LED点亮并熄灭
		P00 = 0;
		P01 = 0;
		P02 = 0;
		P03 = 0;
		P04 = 0;
		P05 = 0;
		P06 = 0;
		P07 = 0;
		Delay1MS(500);
		P00 = 1;
		P01 = 1;
		P02 = 1;
		P03 = 1;
		P04 = 1;
		P05 = 1;
		P06 = 1;
		P07 = 1;
		Delay1MS(500);
	}
}
//1m延时程序
void Delay1MS(unsigned int t){
	unsigned char i;
	while(--t != 0){
		for(i = 0; i < 125; i++);
	}
}

效果如下:

        到此,这个程序就结束了,如果需要单片机引脚进行批量且复杂控制的时候,这种程序方法显然是不合适的,这里我们可以使用位移的方式进行控制。

       2.位移方式

        位移是源自二进制的位移,8051单片机的P0~P3每个接口都对应着八个引脚,就是八位的二进制,将上面的程序转换一下就是:

011111110x7F
101111110xBF
110111110xDF
111011110xEF
111101110xF7
111110110xFB
111111010xFD
111111100xFE

        LED发光二极管点亮顺序就是每次都是位移一个位,那么在程序里面就可以使用位移方式进行控制,在这里可以调用“intrains.h”函数快速实现这个功能,关于“intrins.h”的具体说明如下所示:

intrins.h函数说明:应用于程序设计,一般出C51单片机编程中,一般程序中需要使用到空指令_nop_();字符循环移位指令_crol_等时使用,内部函数:
_crol_ 字符循环左移
_cror_ 字符循环右移
_irol_ 整数循环左移
_iror_ 整数循环右移
_lrol_ 长整数循环左移
_lror_ 长整数循环右移
_nop_ 空操作 (相当于8051 NOP 指令)
_testbit_ 测试并清零位 (相当于8051 JBC 指令)
函数名: _crol_,_irol_,_lrol_
举例:
_crol_,_cror_:将char型变量循环向左(右)移动指定位数后返回
_testbit_: 相当于JBC bitvar测试该位变量并跳转同时清除。
_chkfloat_: 测试并返回源点数状态。
就是汇编中的子函数。
_crol_,_cror_:如果二进制数为01010101 那么_crol_(1) 左移1位后将高位补低位。
结果10101010。
功 能:_crol_,_irol_,_lrol_以位形式将val 左移n 位,该函数与8051“RLA”指令相关,上面几个函数不同于参数类型。
例:
#include <intrins.h>
main()
{
    unsigned int y;
    y=0x00ff;
    y=_irol_(y,4);
}

 参照上面的方法,重新编写代码如下所示:

//添加头文件,C51必要文件,主要定义的是51/52系列单片机
#include "reg52.h"
#include "intrins.h"
//引用延时函数
void Delay1MS(unsigned int t);
unsigned char tmp,i;
int main(void){
	//进入循环
	while(1){
		//点亮并熄灭P00,P00点亮0.5s
		tmp = 0xfe; //对应的二进制为0111 1111
		Delay1MS(500);
		for(i=0;i<8;i++){
			P0 = tmp;
			tmp = _crol_(tmp,1);//每隔0.2s向左位移一位
			Delay1MS(200);
			
		}
		//所有LED发光二极管闪烁两次
		P0 = 0xFF;
		Delay1MS(200);
		P0 = 0x00;
		Delay1MS(200);
		P0 = 0xFF;
		Delay1MS(200);
		P0 = 0x00;
		Delay1MS(200);

	}
}
//1m延时程序
void Delay1MS(unsigned int t){
	unsigned char i;
	while(--t != 0){
		for(i = 0; i < 125; i++);
	}
}

效果如下所示:

思考:通过本节的内容优化上一节“炫彩灯”程序。 

  • 6
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个爱折腾的小人物

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值