蓝桥杯单片机CT107D_20_智能照明控制器

   日期:2021-02-18     浏览:96    评论:0    
核心提示:驱动://IIC.h#include<reg52.h>sbit SDA = P2^1; //数据线sbit SCL = P2^0; //时钟线void Delay_IIC(unsigned char t); //延时函数void IIC_Start(void); //起始信号void IIC_Stop(void); //停止信号void IIC_Ack(unsigned

驱动:

//IIC.h
#include<reg52.h>
sbit SDA = P2^1;      //数据线
sbit SCL = P2^0;      //时钟线

void Delay_IIC(unsigned char t);        //延时函数
void IIC_Start(void);                   //起始信号
void IIC_Stop(void);                    //停止信号
void IIC_Ack(unsigned char ackbit);     //产生应答
bit IIC_WaitAck(void);                  //等待应答
void IIC_SendByte(unsigned char byte);	//发送数据
unsigned char IIC_RecByte(void);        //接收数据

//IIC.c
#include<IIC.h>

void Delay_IIC(unsigned char time)
{ 
	while(time--);
}

void IIC_Start(void)
{ 
	SDA = 1;
	SCL = 1;
	Delay_IIC(5);
	SDA = 0;        //在SCL高电平期间,SDA由高变低
	Delay_IIC(5);
	SCL = 0;	
}

void IIC_Stop(void)
{ 
	SDA = 0;
	SCL = 1;
	Delay_IIC(5);
	SDA = 1;	//在SCL高电平期间,SDA由高变低
	Delay_IIC(5);
}

void IIC_Ack(unsigned char ackbit)
{ 
	if(ackbit) 	
		SDA = 0;	//产生应答信号
	else 
		SDA = 1;	//产生非应答信号
	Delay_IIC(5);
	SCL = 1;
	Delay_IIC(5);	        //第9个时钟周期
        SCL = 0;
	SDA = 1; 		//释放SDA线
	Delay_IIC(5);
}

bit IIC_WaitAck(void)
{ 
	SDA = 1;
	Delay_IIC(5);
	SCL = 1;
	Delay_IIC(5);	
 
	if(SDA)    		//在SCL高电平期间,SDA为高电平,从机非应答。
	{    
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else 			//在SCL高电平期间,SDA为低电平,从机有应答。
	{  
		SCL = 0;
		return 1;
	}	
}

void IIC_SendByte(unsigned char byt)
{ 
	unsigned char i;
	for(i=0;i<8;i++)		//循环发送8位数据
	{    
		if(byt & 0x80) 		//数据位是高电平
		{ 	
			SDA = 1;
		}
		else 			//数据位是低电平
		{ 
			SDA = 0;
		}
 
		Delay_IIC(5);
		SCL = 1;		//SCL高电平期间,SDA的数据要保持稳定
		byt <<= 1;		//发送的数据左移,准备发送下一位
		Delay_IIC(5);		//等待SDA的数据被读取
		SCL = 0;
	}
}

unsigned char IIC_RecByte(void)
{ 
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++)
	{    
		SCL = 1;
		Delay_IIC(5);		//在SCL高电平期间,读取SDA的数据
		da <<= 1;
		if(SDA) 
			da |= 0x01;
		SCL = 0;
		Delay_IIC(5);
	}
	return da;
}

主程序:

#include<reg52.h>
#include"IIC.h"

sbit S4 = P3^3;
sbit S5 = P3^2;          //定义独立按键
unsigned char level;  	 //灯光等级
unsigned char voltage;   //Rd1电压
unsigned char record_l;  //存放灯光等级历史数据
unsigned char record_v;  //存放Rd1电压历史数据
unsigned char code SEG_code[18] = 
	{ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
	 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
	 0xbf,0x7f};	     //定义共阳数码管段码内容:0~F,—,.

void Select_HC138(unsigned char n)
{ 
	switch(n)
	{ 
		case 0:
			P2 = (P2 & 0x1f) | 0x00;
			break;
		case 4:
			P2 = (P2 & 0x1f) | 0x80;
			break;
		case 5:
			P2 = (P2 & 0x1f) | 0xa0;
			break;
		case 6:
			P2 = (P2 & 0x1f) | 0xc0;
			break;
		case 7:
			P2 = (P2 & 0x1f) | 0xe0;
			break;
	}
}

void Delay(unsigned int t)
{ 
	while(t--);
}

void Show_tube(unsigned char position,unsigned char value)
{ 
	Select_HC138(7);
	P0 = 0xff;
	Select_HC138(6);
	P0 = 0x01 << position;
	Select_HC138(7);
	P0 = value;
}

void Show_all()
{ 
	Select_HC138(7);
	P0 = 0xff;
	Select_HC138(6);
	P0 = 0xff;
}

void Display_tube(unsigned char led,unsigned char rd1)
{ 
	Show_tube(0,SEG_code[16]);
	Delay(100);
	Show_tube(1,SEG_code[led]);
	Delay(100);
	Show_tube(2,SEG_code[16]);
	Delay(100);

	Show_tube(5,SEG_code[rd1/100]);
	Delay(100);
	Show_tube(6,SEG_code[(rd1/10)%10]);
	Delay(100);
	Show_tube(7,SEG_code[rd1%10]);
	Delay(100);

	Show_all();
}

void Read_Rd1()
{ 
	IIC_Start();             //IIC总线起始信号
	IIC_SendByte(0x90);		 //写设备地址
	IIC_WaitAck();           //等待从机应答
	IIC_SendByte(0x01);      //写控制字
	IIC_WaitAck();           //等待从机应答
	IIC_Stop();              //IIC总线停止信号

	IIC_Start();               //IIC总线起始信号
	IIC_SendByte(0x91);        //读设备地址
	IIC_WaitAck();             //等待从机应答
	voltage = IIC_RecByte();   //读取PCF8591通道1的数据
	IIC_Ack(0);                //产生一个非应答信号
	IIC_Stop();                //IIC总线停止信号
}

void Write_24C02(unsigned char addr,unsigned char dat)
{ 
	IIC_Start();      		 //IIC总线起始信号
	IIC_SendByte(0xa0);      //写设备地址
	IIC_WaitAck();           //等待从机应答
	IIC_SendByte(addr);      //写内存字节地址
	IIC_WaitAck();           //等待从机应答
	IIC_SendByte(dat);       //写入目标数据
	IIC_WaitAck();           //等待从机应答
	IIC_Stop();              //IIC总线停止信号
}  

unsigned char Read_24C02(unsigned char addr)
{ 
	unsigned char temp;
	//进行一个伪写操作
	IIC_Start();   			 //IIC总线起始信号
	IIC_SendByte(0xa0);      //写设备地址
	IIC_WaitAck();           //等待从机应答
	IIC_SendByte(addr);      //写内存字节地址
	IIC_WaitAck();           //等待从机应答
	
	IIC_Start();             //IIC总线起始信号
	IIC_SendByte(0xa1);      //读设备地址
	IIC_WaitAck();           //等待从机应答
	temp = IIC_RecByte();    //读取目标数据
	IIC_Ack(0);              //产生一个非应答信号
	IIC_Stop();              //IIC总线停止信号
	return temp;
}

void Led_light()
{ 
	Read_Rd1();
	if(voltage>200 && voltage<=255)
	{ 
		level = 1;
		Select_HC138(4);
		P0 = 0xfe;	         //点亮L1
		Select_HC138(0);
	}
	else if(voltage>150 && voltage<=200)
	{ 
		level = 2;
		Select_HC138(4);
		P0 = 0xfc;			 //点亮L1、L2
		Select_HC138(0);
	}
	else if(voltage>100 && voltage<=150)
	{ 
		level = 3;
		Select_HC138(4);
		P0 = 0xf0;			 //点亮L1~L4
		Select_HC138(0);
	}
	else if(voltage<=100)
	{ 
		level = 4;
		Select_HC138(4);
		P0 = 0x00;			 //点亮L1~L8
		Select_HC138(0);
	}
}

void Access()
{ 
	Write_24C02(0x01,level);      //保存level
	Delay(1000);
	Write_24C02(0x02,voltage);	  //保存voltage
	Delay(1000);
}

void Show()
{ 
	record_l = Read_24C02(0x01);
	record_v = Read_24C02(0x02);
}

void Delay_keys()
{ 
	unsigned char i,j;
	i = 108;
	j = 145;
	do
	{ 
		while(--j);
	}while(--i);
}

void Press_keys()
{ 
	if(S4 == 0)
	{ 
		Delay_keys();
		if(S4 == 0)
		{ 
			Access();	  //存储
			while(S4 == 0)
			{ 
				Display_tube(level,voltage);
			}
		}
	}

	else if(S5 == 0)
	{ 
		Delay_keys();
		if(S5 == 0)
		{ 
			Show();
			while(S5 == 0)
			{ 
				Display_tube(record_l,record_v);
			}
		}
	}
}

void main()
{ 
	Select_HC138(5);
	P0 = 0x00;           //关闭蜂鸣器和继电器
	Select_HC138(0);
	while(1)
	{ 
		Led_light();
		Display_tube(level,voltage);
		Press_keys();
	}
}

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

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

13520258486

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

24小时在线客服