大学生必学的c51点灯

1.流水灯

        方法一:

#include <REGX52.H> 
//也可以使用<REG52.H> 缺点是只能对P2整体操作,不能操作单独操作一位,如P2_0
#include <INTRINS.H>
//这个库里面有_nop_()
void Delay1ms(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
	while(time--){
		_nop_();
		_nop_();
		_nop_();
		i = 11;
		j = 190;
		do
		{
			while (--j);
		} while (--i);
	}
}
int main(){
	while(1)
	{
		/*51单片机是大段存储,
		因此1111 1110是点亮P27~P20中的P20*/
		P2=0xFE;//1111 1110 P20对应原理图的D1(第一个灯)
		Delay1ms(100);
		P2=0xFD;//1111 1101
		Delay1ms(100);
		P2=0xFB;//1111 1011
		Delay1ms(100);
		P2=0xF7;//1111 0111
		Delay1ms(100);
		P2=0xEF;//1110 1111
		Delay1ms(100);
		P2=0xDF;//1101 1111
		Delay1ms(100);
		P2=0xBF;//1011 1111
		Delay1ms(100);
		P2=0x7F;//0111 1111
		Delay1ms(100);
	}
}

        方法二:

        使用位运算的方法(非逻辑运算)

        增:|         a=xxxx xxxx,把D0位变成1            a |= 1<<0

        删:&~     a=xxxx xx1x,把D1位变成0            a &=~(1<<1)

        查:&       a=xxxx x1xx,查D2位是否为1         a &=(1<<2)  如果a不为零,说明D2位是1

#include <REGX52.H> 
#include <INTRINS.H>
void Delay1ms(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
	while(time--){
		_nop_();
		_nop_();
		_nop_();
		i = 11;
		j = 190;
		do
		{
			while (--j);
		} while (--i);
	}
}
int main(){
	unsigned char LedFlg=0;
	while(1)
	{
		char count=0;
		for(count=0;count<8;count++){
			P2=~(LedFlg|(1<<count));
			Delay1ms(100);
		}
	}
}

2.按键控制led灯

         1.K1长按亮灯,松手不亮:

#include <REGX52.H> 
//不可以使用<REG52.H> 只能对P2整体操作,不能操作单独操作一位,如P2_0
void main(){
	while(1)
	{
		if(P3_1==0)	//如果K1按键
			P2_0=0;	
		else
			P2_0=1;	
	}
}

       2.K1按下切换亮灭

#include <REGX52.H> 
#include <INTRINS.H>
void Delay1ms(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
	while(time--){
		_nop_();
		_nop_();
		_nop_();
		i = 11;
		j = 190;
		do
		{
			while (--j);
		} while (--i);
	}
}
void main(){
	while(1)
	{
		if(P3_1==0){	//如果K1按键
			Delay1ms(10);//按下消抖
			while(P3_1==0);
			Delay1ms(10);//抬起消抖
			P2_0=~P2_0;			
		}
	}
}
	

         3.K1按下led灯右移,

3.控制八个LED灯实现二进制加法

#include <REGX52.H> 
#include <INTRINS.H>
void Delay1ms(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
	while(time--){
		_nop_();
		_nop_();
		_nop_();
		i = 11;
		j = 190;
		do
		{
			while (--j);
		} while (--i);
	}
}
void main(){
	unsigned char num=0;
	while(1)
	{
		if(P3_1==0){	//如果K1按键
			Delay1ms(10);//按下消抖
			while(P3_1==0);
			Delay1ms(10);//抬起消抖
			num++;
			P2=~num;
		}
	}
}

要按2^{8} (256)次才能实验按完,太累了,如果按着不动就可以自动加,只需要去掉抬手的代码(24和25行)。

4.思考

1.

#include <REGX52.H> 
#include <INTRINS.H>
void Delay1ms(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
	while(time--){
		_nop_();
		_nop_();
		_nop_();
		i = 11;
		j = 190;
		do
		{
			while (--j);
		} while (--i);
	}
}
void main(){
	unsigned char num=0;
	while(1)
	{
		if(P3_1==0){	//如果K1按键
			Delay1ms(10);//按下消抖
			num++;
			
		}else if(P3_0==0){
			num--;
			Delay1ms(10);
		}
		P2=~num;
	}
}
	

上述代码按键同时按下的话是只能加,不能减。如何实现同时按下不加也不减。(判断的先后顺序很重要)

驱动库分享整理(1)——用于单片机中的小巧多功能按键支持库_单片机 state machine 库-CSDN博客

2.如果led灯不进行加法,而是进行移位,需要改哪些。

#include <REGX52.H> 
#include <INTRINS.H>
void Delay1ms(unsigned int time)		//@11.0592MHz
{
	unsigned char i, j;
	while(time--){
		_nop_();
		_nop_();
		_nop_();
		i = 11;
		j = 190;
		do
		{
			while (--j);
		} while (--i);
	}
}

void main(){
	unsigned char count=0;
	P2=0xFE;
	while(1)
	{
		if(P3_1==0){	//如果K1按键
			Delay1ms(20);//按下消抖
			while(P3_1==0);
			Delay1ms(20);
			if(count==7)
				count=0;//加之前一定要先检查count的值快超了吗
			else 
				count++;
			P2=~(0x01<<count);
		}else if(P3_0==0){
			Delay1ms(20);
			while(P3_0==0);
			Delay1ms(20);					
			if(count==0)
				count=7;
			else 
				count--;
			P2=~(0x01<<count);
		}
		
	}
}
	

  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值