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

驱动:

//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();
	}
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值