LQB训练手打代码,以及演示效果01:控制LED,

该程序用于控制LED的闪烁,包括初始化关闭所有外设,LED闪烁8次,LED1和LED5特定频率闪烁,以及根据LEDbuf状态判断LED7和LED8的闪烁。使用了位操作来切换LED的状态,并通过全局变量LEDbuf存储LED的状态。同时,包含了一个延时函数用于控制闪烁间隔。
摘要由CSDN通过智能技术生成

任务:

1、控制LED,手打代码,
2、单片机上电,关闭所有外设LED,蜂鸣器,继电器,数码管;
3、然后LED全部一起闪烁8次,间隔300ms;
4,然后在while1里面,不断LED1闪烁5次,间隔500ms,然后LED全部关/1秒;
5、然后LED5慢闪5次,间隔1000ms;然后全部关闭1秒;
6、然后LEDbuf=0xBD,P0输出这个数据,等待5秒;
7、然后判断LED6是不是等于1,如果等于1,熄灭的状态,那么让LED7快闪5次,间隔200ms;如果等于0,点亮的状态,那么让LED8快闪5次;然后所有的LED关闭1秒钟。

关键代码:
选择不同的573的函数;
设置一个全局变量,负责LED的状态,LEDbuf,unsigned char类型;

让某一个位等于1,其他位保持不变;或1等于1,或0保持不变;
让某一个位等于0,其他位保持不变;与0清0,与1保持不变;
判断某一个位,是0还是1,;右移N位,再与0x01等结果
取反某个LED的状态,其他位保持不变,异或1取反,异或0保持不变。

理论看我的LQB原来的视频。或者先记着。现场问我。

关闭全部外设:
LED是等于1,熄灭,等于0点亮;
蜂鸣器和继电器都是等于0不响,不导通,等于1就是点亮,导通;
数码管是共阳数码管,COM口等于0x00,ABC数据口等于0xFF;

#include <stc15.h>
#include <intrins.h>
//类型定义,在stcISP软件复制过来的,提高编程效率,比如用u8代替unsigned char,不用打这么多字
typedef     unsigned char   u8;
typedef     unsigned int    u16;
typedef     unsigned long   u32;
//宏定义,注意不要有分号在后面
#define LED 4
#define ULN 5
#define COM 6
#define ABC 7

 //***********全局变量
u8 LEDbuf=0xFF;//这个数据等于0xFF,那么后面输出给P0,LED会全部熄灭
u8 ULNbuf=0x00;//ULN2003是反相器,0出1,输出给P0,蜂鸣器继电器都会不反应
//******************************背出来
void Select(u8 x)
{
    switch(x)
		{
			//0001 1111
			case 0:P2=P2&0x1F;break;//选择74HC138的Y0闲置口,相当于不选择任何一个支路
			case LED:P2=(P2&0x1F)|0x80;break;   //选择Y4,LED通道支路
			case ULN:P2=(P2&0x1F)|0xA0;break;   //选择Y5,ULN通道支路
			case COM:P2=(P2&0x1F)|0xC0;break;   //选择Y6,COM通道支路
			case ABC:P2=(P2&0x1F)|0xE0;break;   //选择Y7,ABC通道支路
		}
}
//延时1ms,stcISP软件生成,nop函数注意在KEIL的help文件里面搜索,得到头文件是intrins.h
void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	_nop_();
	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
}
//自己变成,用for循环进行多次一个毫秒的循环,注意括号最好用u16类型,因为可能超过1000数字,大于8位256数字
void delayms(u16 nms)
{
   u16 i=0;
	 for(i=0;i<nms;i++)
	{
		 Delay1ms();
	}
}

//*****************************main
void main()
{
	//局部变量
	 u8 i=0;
	 //关闭外设 ,初始化动作
	 //选择通道,更新数据,输出数据,关闭通道
	  Select(LED); LEDbuf=0xFF; P0=LEDbuf; Select(0);//LED通道,关闭熄灭LED
	  Select(ULN);ULNbuf=0x00;P0=ULNbuf;Select(0);
	  //ULN2003芯片,反相器,0x00经过ULN2003之后,数据是0xFF,输出后,蜂鸣器继电器熄灭
	  Select(COM);P0=0x00;Select(0);//选择数码管COM通道,这没有缓冲字节,因为数码管我们不需要随时读取哪个点亮
	  Select(ABC);P0=0xFF;Select(0);//选择数码管ABC段码通道,这没有缓冲字节,因为数码管我们不需要随时读取亮的是什么
	//开机之后,全部数码管闪烁8次,快速闪烁
	 for(i=0;i<8;i++)
	{
	    Select(LED); LEDbuf=0x00; P0=LEDbuf; Select(0);
		  delayms(300);
		  Select(LED); LEDbuf=0xFF; P0=LEDbuf; Select(0);
		  delayms(300);
	}
	
	while(1)
	{
		    //让LED1闪烁8次,,注意为什么用取反0x01,目的是为了简化,
		//方便理解。0000 0001取反等于1111 1110,bit0与0等于0,其他位与1保持不变
			 for(i=0;i<8;i++)
			{
				Select(LED); LEDbuf=LEDbuf &(~0x01) ; P0=LEDbuf; Select(0);
				//~0x01,对0x01进行取反,得到1111 1110,LEDbuf与1111 1110,将最低位清0,其他位保持不变,
				//目的是让LED1=0,点亮LED1;为什么我这里要采用取反的方法呢,主要是为了方便记忆,我们习惯用1进行计算,当然你也
				//可以不采用这种方法;而直接采用LEDbuf=LEDbuf &0xFE;(开发板没有LED0,而是从LED1开始的。。)
				delayms(500);
				//或0x01,将最低LED1=1,其他位保持不变,熄灭LED1;
				Select(LED); LEDbuf=LEDbuf |0x01; P0=LEDbuf; Select(0);
				delayms(500);
			}
			 //让LED5闪烁8次,注意为什么用取反0x10,目的是为了简化,方便理解。
			for(i=0;i<8;i++)
			{
			//~0x10,对0x10进行取反,得到1110 1111,LEDbuf与1110 1111,将LED5=0,其他位保持不变,
				//目的是让LED5=0,点亮LED5;为什么我这里要采用取反的方法呢,主要是为了方便记忆,我们习惯用1进行计算,当然你也
				//可以不采用这种方法;而直接采用LEDbuf=LEDbuf &0xFE;(开发板没有LED0,而是从LED1开始的。。)
				Select(LED); LEDbuf=LEDbuf &(~0x10) ; P0=LEDbuf; Select(0);   //0001  0000
				delayms(1000);
				Select(LED); LEDbuf=LEDbuf |0x10; P0=LEDbuf; Select(0);
				delayms(1000);
			}
			  //关闭LED灯一秒钟
				Select(LED); LEDbuf=0xFF; P0=LEDbuf; Select(0);
				delayms(1000);
			
			  LEDbuf=0xBD;
//学会判断哪一位是0还是1?
			//判断LED7是不是1;等于1,让LED7闪烁5次;
			//将LEDbuf右移7位,原来右边的7位移动右边,没有了,左边补0,得到的数,和0x01与,只剩下最后一位,可以判断了。
			//如LEDbuf假如是0xa7=1010 0111,LED7是bit6位,因为开发板没有LED0,而是从LED1开始的;
			//bit7----bit0,bit6=0,右边移动6位,00000010,和0x01与,与0得到0,与1保持不变,所以结果就是剩下最后的bit6位。
			//假如判断哪一位,右移x位,再与0x01,记住了吗?
			  if(((LEDbuf>>6)&0x01)==1)
				{
				   		for(i=0;i<5;i++)
							{
							//0x40=0100 0000
								Select(LED); LEDbuf=LEDbuf &(~0x40) ; P0=LEDbuf; Select(0);   //0100  0000
								delayms(300);
								Select(LED); LEDbuf=LEDbuf |0x40; P0=LEDbuf; Select(0);
								delayms(300);
							}
				}
				//等于0,让LED8闪烁5次
				else
				{
				  	for(i=0;i<5;i++)
							{
								Select(LED); LEDbuf=LEDbuf &(~0x80) ; P0=LEDbuf; Select(0);   //0100  0000
								delayms(300);
								Select(LED); LEDbuf=LEDbuf |0x80; P0=LEDbuf; Select(0);
								delayms(300);
							}
				}
				//关闭所有的LED灯;
				Select(LED); LEDbuf=0xFF; P0=LEDbuf; Select(0);
				delayms(1000);
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值