【蓝桥杯单片机进阶强化-03】PCF8591与24C02综合应用-智能照明自动控制器

【蓝桥杯单片机进阶强化-03】PCF8591与24C02综合应用-智能照明自动控制器

内容来自小蜜蜂老师

在这里插入图片描述

前面已经讲解了PCF8591 和AT24C02的基本使用原理有需要可以看看这两
篇博文

通过该题目的练习更熟悉了PCF8591 IIC读取数据程序的编写,和AT24C02 
IIC 读操作和写操作程序的编程。在练习过程中更重要的一点是锻炼了我们
编程的逻辑 相信在后面的学习中对题目的理解和功能的实现会有更好的思考

#include "reg52.h"
#include "iic.h"


/********************************************
Date:2022-1-15
Author:小殷同学
Learn From:B 站小蜜蜂老师
*********************************************/


//led 灯定义
sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;
sbit L5 = P0^4;
sbit L6 = P0^5;
sbit L7 = P0^6;
sbit L8 = P0^7;

unsigned char Rd1 = 0; //记录光敏实时数值
unsigned char Rd1_old = 0; //记录历史光敏值
unsigned char Level = 0; //记录灯光实时等级
unsigned char Level_old = 0; //记录灯光历史等级

//按键定义
sbit S4 = P3^3;
sbit S5 = P3^2;

//共阳数目管段码
//0-f  0xbf代表 -
unsigned char code SMG_Duan[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
															   0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xbf};





//---------------------------------简单延时函数-------------------------
void Delay(unsigned int t)
{
 	while(t--);
}

//-------------------------------74HC138初始化---------------------------
void Init_74HC138(unsigned char n)
{
 	switch(n)
	{
	 	case 4:P2 = P2| 0x1f; P2 = 0x80; break;
		case 5:P2 = P2| 0x1f; P2 = 0xa0; break;
		case 6:P2 = P2| 0x1f; P2 = 0xc0; break;
		case 7:P2 = P2| 0x1f; P2 = 0xe0; break;
		case 0:P2 = P2| 0X1f; P2 = 0x00; break; //所有锁存器都不选择
	}
}

//----------------------------------系统初始化---------------------------
void InitSystem(void)
{
 	 Init_74HC138(5);
	 P0 = 0x00;			 //关闭继电器与蜂鸣器
	 Init_74HC138(4);
	 P0 = 0xff;   //关闭led
}



//---------------------------------数码管安位显示--------------------------
void SMG_DisplayBit(unsigned char pos ,unsigned char dat)
{
 		Init_74HC138(6);
		P0 = 0x01 << pos ;//位选
		Init_74HC138(7);
		P0 = dat;        //段码
}

//-------------------------------关闭所有数码管---------------------------
void SMG_CLOSEALL(unsigned char dat)
{
	 Init_74HC138(6);
	 P0 = 0xff; //选中所有数码管
	 Init_74HC138(7);
	 P0 = dat; //关闭
}

//----------------------------光敏数据读取函数----------------------------
void Read_Rd1_Data()
{
	IIC_Start();		  //IIC起始信号
	IIC_SendByte(0x90);	 //写入设备地址
	IIC_WaitAck();		 //等待应答
	IIC_SendByte(0x01);	 //写入通道 AIN1
	IIC_WaitAck();		 //等待应答
	IIC_Stop();			//IIC停止信号

	IIC_Start();		//IIC起始信号
	IIC_SendByte(0x91);	 //读取设备地址
	IIC_WaitAck();		//等待应答
	Rd1 = IIC_RecByte(); //读取数据
	IIC_SendAck(1);		//非应答
	IIC_Stop();		    //IIC停止信号
}

//--------------------------------光敏等级Led控制---------------------------
/*
		等级1:255 <= 光照数据 < 200,L1点亮。

       等级2:200 <= 光照数据 < 150,L1~L2点亮。

       等级3:150 <= 光照数据 < 100,L1~L4点亮。

       等级4:100 <= 光照数据 < 50,L1~L6点亮。

       等级5:50 <= 光照数据 < 0,L1~L8点亮。

*/
void Led_Level_Tackle(void)
{
	Init_74HC138(4);
	Read_Rd1_Data();
	if(Rd1 > 200 && Rd1 <= 250)
	{
	  //L1 = 0;
		P0 = 0xfe;
		Level = 5;
	}
	else if(Rd1 > 150 && Rd1 <= 200) 
	{
	 	//L1 = L2 = 0;
		P0 = 0xfc;
		Level = 4;
	}
	else if(Rd1 > 100 && Rd1 <= 150) 
	{
	 	//L1 = L2 = L3 = L4 = 0;
		P0 = 0xf0;
		Level = 3;
	}
	else if(Rd1 > 50 && Rd1 <= 100) 
	{
	 	//L1 = L2 = L3 = L4 = L5 = L6 = 0;
		P0 = 0xc0;
		Level = 2;
	}
	else if(Rd1 > 0 && Rd1 <= 50) 
	{
	 	//L1 = L2 = L3 = L4 = L5 = L6 = L7 = L8 = 0;
		P0 = 0x00;
		Level = 1;
	}

}

//----------------------------------24c02写操作-----------------------------
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停止信号
}

//----------------------------------24c02读操作-------------------------------
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_SendAck(1);				//非应答
		IIC_Stop();					//IIC停止信号
		return temp	;		        //返回数据
}

//----------------------------------数码管数据显示---------------------------
void SMG_Dispaly_New_Data(void)
{
	 SMG_DisplayBit(0,SMG_Duan[16]);
	 Delay(200);
	 SMG_DisplayBit(1,SMG_Duan[Level]);
	 Delay(200);
	 SMG_DisplayBit(2,SMG_Duan[16]);
	 Delay(200);
	 SMG_DisplayBit(3,0xff);
	 Delay(200);
	 SMG_DisplayBit(4,0xff);
	 Delay(200);
	 SMG_DisplayBit(5,SMG_Duan[Rd1/100]);
	 Delay(200);
	 SMG_DisplayBit(6,SMG_Duan[Rd1/10%10]);
	 Delay(200);
	 SMG_DisplayBit(7,SMG_Duan[Rd1%10]);
	 Delay(200);
}

//显示旧值
void SMG_Dispaly_Old_Data(void)
{
	 SMG_DisplayBit(0,SMG_Duan[16]);
	 Delay(200);
	 SMG_DisplayBit(1,SMG_Duan[Level_old]);
	 Delay(200);
	 SMG_DisplayBit(2,SMG_Duan[16]);
	 Delay(200);
	 SMG_DisplayBit(3,0xff);
	 Delay(200);
	 SMG_DisplayBit(4,0xff);
	 Delay(200);
	 SMG_DisplayBit(5,SMG_Duan[Rd1_old/100]);
	 Delay(200);
	 SMG_DisplayBit(6,SMG_Duan[Rd1_old/10%10]);
	 Delay(200);
	 SMG_DisplayBit(7,SMG_Duan[Rd1_old%10]);
	 Delay(200);
}
//---------------------------------------按键读写操作------------------------
//按下S4按键将当前的灯光控制等级和光敏电阻的数据保存到存储器24C02的0x01和0x02内存单元中。
// 按下S5按键时,读取存储在24C02的历史数据并显示在数码管上,松开S5按键后,恢复显示实时数据。
void Key_Tackle(void)
{
	 if(S4 == 0)
	 {
			Delay(20);
			if(S4 == 0)
			{
			 	Write_24C02(0x01,Level);	  //写入灯光等级
				Delay(200);
				Write_24C02(0x02,Rd1);			//写入光敏数值
				while(S4 == 0)
				{
					 SMG_Dispaly_New_Data();	 //实时数据显示
				}
			}
	 }

	 if(S5 == 0)
	 {
			Delay(20);
			if(S5 == 0)
			{
			 	Level_old = Read_24C02(0x01);	 //读取灯光等级
				Delay(200);
				Rd1_old   =  Read_24C02(0x02); //读取光敏数值
				while(S5 == 0)
				{
					SMG_Dispaly_Old_Data();		 //历史数据显示
				}
			}
	 }
}
//-------------------------------------主函数----------------------------------
void main(void)
{
	InitSystem();	      //系统初始化
 	while(1)
	{
		
		Led_Level_Tackle();		//灯光等级获取
		SMG_Dispaly_New_Data();	 //数码管实时显示
		Key_Tackle();		  //按键切换
	}

}

路漫漫其修远兮 加油

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小殷学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值