蓝桥杯单片机CT107D_13_工厂灯光控制系统

   日期:2021-02-17     浏览:105    评论:0    
核心提示:#include<reg52.h>sfr AUXR = 0x8e; //设置辅助寄存器AUXRsbit S7 = P3^0; //独立按键S7sbit S5 = P3^2; //独立按键S5unsigned char command; //接收串口数据unsigned char state = 0xff; //LED当前状态unsigned char hour = 0;

需求:(题目来自小蜜蜂老师)

#include<reg52.h>
sfr AUXR = 0x8e;               //设置辅助寄存器AUXR
sbit S7 = P3^0;	               //独立按键S7
sbit S5 = P3^2;				   //独立按键S5
unsigned char command;         //接收串口数据
unsigned char state = 0xff;    //LED当前状态
unsigned char hour = 0;        //时
unsigned char minute = 0;      //分
unsigned char second = 0;      //秒
unsigned char count = 0; 	   //50ms定时计数
unsigned char code SEG_code[19] = 
	{ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
	 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
	 0xbf,0x7f,0x00};	           //定义共阳数码管段码内容:0~F,—,.


//端口选择
void Select_HC138(unsigned char n)     
{ 
	switch(n)
	{ 
		case 0:
			P2 = (P2 & 0x1f) | 0x00;   //不选择
			break;
		case 4:
			P2 = (P2 & 0x1f) | 0x80;   //选择LED
			break;
		case 5:
			P2 = (P2 & 0x1f) | 0xa0;   //选择蜂鸣器和继电器
			break;
		case 6:
			P2 = (P2 & 0x1f) | 0xc0;   //选择数码管的位置
			break;
		case 7:
			P2 = (P2 & 0x1f) | 0xe0;   //选择数码管的值
			break;
	}
}

//普通延时函数
void Delay_common(unsigned int t)      
{ 
	while(--t);		  //--t
}

//初始化
void Init_system()	  
{ 
	Select_HC138(5);
	P0 = 0x00;        //关闭蜂鸣器和继电器
	Select_HC138(4);
	P0 = state;       //关闭LED
	Select_HC138(0);
}

//LED检测
void Check_LED()      
{ 
	unsigned char i;
	Select_HC138(4);
	for(i=1;i<=8;i++)	  //依次点亮LED
	{ 
		P0 = state << i;
		Delay_common(60000);
		Delay_common(60000);
		Delay_common(60000);
	}
	for(i=1;i<=8;i++)	  //依次熄灭LED
	{ 		
		P0 = ~(state << i);
		Delay_common(60000);
		Delay_common(60000);
		Delay_common(60000);
	}
	Select_HC138(0);
}
		 
//数码管检测
void Check_SMG()	  
{ 	 	
	unsigned char j;
	for(j=1;j<=8;j++)
	{ 
		Select_HC138(6);         
		P0 = ~(0xff << j);		 //依次点亮数码管
		Select_HC138(7);
		P0 = SEG_code[18];
		Delay_common(60000);
		Delay_common(60000);
		Delay_common(60000);
	}
	for(j=1;j<=8;j++)
	{ 
		Select_HC138(6);         
		P0 = 0xff << j;			 //依次熄灭数码管
		Select_HC138(7);
		P0 = SEG_code[18];
		Delay_common(60000);
		Delay_common(60000);
		Delay_common(60000);
	}
	Select_HC138(0);
}




//数码管显示
void Show_tube(unsigned char position,unsigned char value)
{ 
	Select_HC138(6);
	P0 = 0x01 << position;
	Select_HC138(7);
	P0 = value;
}

//数码管动态显示
void Dynamic_display()
{ 
	Show_tube(0,SEG_code[hour/10]);     //显示时的十位
	Delay_common(500);
	Show_tube(1,SEG_code[hour%10]);     //显示时的个位
	Delay_common(500);
	
	Show_tube(2,SEG_code[16]);          //显示分隔符
	Delay_common(500);
	
	Show_tube(3,SEG_code[minute/10]);   //显示分的十位 
	Delay_common(500);
	Show_tube(4,SEG_code[minute%10]);   //显示分的个位
	Delay_common(500);
	
	Show_tube(5,SEG_code[16]);			//显示分隔符
	Delay_common(500);	

	Show_tube(6,SEG_code[second/10]);   //显示秒的十位 
	Delay_common(500);
	Show_tube(7,SEG_code[second%10]);   //显示秒的个位
	Delay_common(500);
}




//去抖动延时函数
void Delay_keys()     
{ 
	unsigned char m = 108,n = 145;
	while(--m)
	{ 
		while(--n);
	}
}

//独立按键
void Press_keys()
{ 
	if(S7 == 0)			 //按下S7,点亮L8
	{ 
		Delay_keys();	 //去抖动
		if(S7 == 0)
		{ 
			Select_HC138(4);
			state = (state & 0x7f) | (~state & 0x80);  //将最高位取反:将最高位置0、保留state低7位,然后取state取反后的最高位、其他位置0,最后组合
			P0 = state;	             //将当前状态赋值给P0
			Select_HC138(0);
			while(S7 == 0)
			{ 
				Dynamic_display();   //保证数码管动态显示
			}
		}
	}

	else if(S5 == 0)     //按下S5,点亮L7
	{ 
		Delay_keys();	 //去抖动
		if(S5 == 0)
		{ 
			Select_HC138(4);
			state = (state & 0xbf) | (~state & 0x40);  //将第7位取反:将第7位置0、保留state其他位,然后取state取反后的第7位、其他位置0,最后组合
			P0 = state;				 //将当前状态赋值给P0
			Select_HC138(0);
			while(S5 == 0)
			{ 
				Dynamic_display();	 //保证数码管动态显示
			}
		}
	}
}




//定时器timer0中断初始化
void Init_timer0()
{ 
	TMOD = 0x21;                   //注意:同时给定时器0和定时器1赋值
	TH0 = (65535 - 50000) / 256;   //定时50ms
	TL0 = (65535 - 50000) % 256; 

	EA =1;     //打开总中断
	ET0 = 1;   //打开定时器0的中断
	TR0 = 1;   //启动定时器0
}

//定时器0中断服务函数
void Service_timer0() interrupt 1
{ 
	TH0 = (65535 - 50000) / 256;   //重新赋值
	TL0 = (65535 - 50000) % 256;  
	count++;                       //定时满50ms加1

	if(count == 20)
	{ 
		count = 0; 
		second++;				   //定时满1s加1
	}
	if(second == 60)
	{ 
		second = 0;
		minute++;				   //定时满1min加1
	}
	if(minute == 60)
	{ 
		minute = 0;
		hour++;					   //定时满1h加1
	}
}




//发送字节
void Send_byte(unsigned char dat)
{ 
	SBUF = dat;		  //注意:串口自动转换输出16进制数
	while(TI == 0);   //等待发送
	TI = 0;           //清0
}

//发送字符串
//void Send_string(unsigned char *str)
//{ 
// while(*str != '\0')
// { 
// Send_byte(*str++);
// }
//}

//串口中断初始化
void Init_uart() 
{ 
	SCON = 0x50;	//8位异步uart并允许接收
	AUXR = 0x00;	//将AUXR置0
	TMOD = 0x21;    //注意:同时给定时器0和定时器1赋值
	TH1 = 0xfd;
	TL1 = 0xfd;

	EA = 1;         //打开总中断
	ES = 1;         //打开串口中断
	TR1 = 1;		//启动定时器1
}

//串口中断服务函数
void Service_uart() interrupt 4
{ 
	if(RI == 1)     
	{ 
		RI = 0;           //清0
		command = SBUF;	  //接收数据
	}
}




//对串口接收的命令进行相应处理
void Command_process()
{ 
	if(command)
	{ 
		switch(command & 0xf0)	      //取command的高4位,低4位清0
		{ 
			case 0xa0:				  //远程灯光控制
				Select_HC138(4);
				state = (state & 0xf0) | (~command & 0x0f);     //保留state高4位,取~command的低4位,然后组合
				P0 = state;			  //将当前状态赋值给P0
				Select_HC138(0);
				break;

			case 0xb0:				  //读取系统运行时间
				Send_byte((hour/10 << 4) | (hour%10));       //发送时
				//Send_string("-"); //分隔符
				Send_byte((minute/10 << 4) | (minute%10));   //发送分
				//Send_string("-"); //分隔符
				Send_byte((second/10 << 4) | (second%10));   //发送秒
				//Send_string("\r\n"); //换行 
				break;
		}
		command = 0;
	}
}




void main()
{ 
	Init_system();           //初始化
	Check_LED();	         //LED检测
	Check_SMG();	         //数码管检测
	Init_uart();	         //串口初始化
	Init_timer0();	         //定时器0初始化
	while(1)
	{ 
		Dynamic_display();   //数码管动态显示
		Press_keys();		 //独立按键
		Command_process();   //命令处理
	}
}
	

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服