蓝桥杯15——PCF8591与24C02综合应用:智能照明自动控制器
Posted 谏书稀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯15——PCF8591与24C02综合应用:智能照明自动控制器相关的知识,希望对你有一定的参考价值。
智能照明自动控制器
在蓝桥杯大赛“单片机设计与开发”的在CT107D综合训练平台上,利用竞赛提供的IIC底层驱动代码,设计程序,实现以下的功能:
-
系统上电后,通过采样PCF8591通道1中光敏电阻RD1的实时数据,并根据该数据控制8个LED灯的亮灭情况。
-
灯光的控制分为5个等级:
等级1:200 <= 光照数据 < 255,L1点亮。
等级2:150 <= 光照数据 < 200,L1~L2点亮。
等级3:100 <= 光照数据 < 150,L1~L4点亮。
等级4:50 <= 光照数据 < 100,L1~L6点亮。
等级5:0 <= 光照数据 < 50,L1~L8点亮。 -
灯光控制等级和光敏数据实时显示在数码管上,如下如所示,灯光等级在左,光敏实时数据在右。
-
按下S4按键,将当前的灯光控制等级和光敏电阻的数据保存到存储器24C02的0x01和0x02内存单元中。
-
按下S5按键时,读取存储在24C02的历史数据并显示在数码管上,松开S5按键后,恢复显示实时数据。
#include <STC15F2K60S2.H>
#include <IIC.H>
#include <absacc.h>
void show(unsigned char pos, unsigned char value);
void delay(unsigned int t);
void show_now();
void show_old();
void LED_Level();
void Read_AIN1();
void Write_24C02(unsigned char addr, unsigned char dat);
unsigned char Read_24c02(unsigned char dat);
void key();
sbit s4=P3^3;
sbit s5=P3^2;
unsigned char table[]=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf;
unsigned char level=0; //存放实时灯光控制等级
unsigned char rd1=0; //存放实时光敏数据
unsigned char old_level=0; //存放历史灯光控制等级
unsigned char old_rd1=0; //存放历史光敏数据
void main()
XBYTE[0xa000]=0x00;
while(1)
LED_Level();
show_now();
key();
//按键控制显示函数
void key()
if(s4==0)//按下S4按键,将当前的灯光控制等级和光敏电阻的数据保存到存储器24C02的0x01和0x02内存单元中。
delay(200);
if(s4==0)
Write_24C02(0x01,level);
delay(1000);
Write_24C02(0x02,rd1);
while(s4==0)//在等待按键松开时后刷新数码管显示历史数据。
show_now();
if(s5==0)//按下S5按键时,读取存储在24C02的历史数据并显示在数码管上,松开S5按键后,恢复显示实时数据。
delay(200);
if(s5==0)
old_level=Read_24c02(0x01);
old_rd1=Read_24c02(0x02);
while(s5==0) //在按键松开后,恢复显示实时数据
show_old();
//灯光等级控制函数
/* 等级1:200 <= 光照数据 < 255,L1点亮。
等级2:150 <= 光照数据 < 200,L1~L2点亮。
等级3:100 <= 光照数据 < 150,L1~L4点亮。
等级4:50 <= 光照数据 < 100,L1~L6点亮。
等级5:0 <= 光照数据 < 50,L1~L8点亮。
*/
void LED_Level()
Read_AIN1();
if(rd1>200)
XBYTE[0x8000]=0xfe; //1111 1110 点亮L1
level=1;
else if(rd1>150)
XBYTE[0x8000]=0xfc;
level=2;
else if(rd1>100)
XBYTE[0x8000]=0xf0;
level=3;
else if(rd1>50)
XBYTE[0x8000]=0xc0;
level=4;
else if(rd1>=0)
XBYTE[0x8000]=0x00;
level=5;
//采样PCF8591通道1的数据
void Read_AIN1()
//先进行写操作,选择光敏传感器AIN1,通道1
IIC_Start();
IIC_SendByte(0x90); //PCF8591的写设备地址
IIC_WaitAck(); //等待从机应答
IIC_SendByte(0x01); //写入PCF8591的控制字节
IIC_WaitAck();
IIC_Stop();
//再进行读操作,通道1
IIC_Start();
IIC_SendByte(0x91); //PCF8591的读设备地址
IIC_WaitAck();
rd1=IIC_RecByte(); //读取PCF8591通道1的数据
IIC_Ack(0); //产生非应答信号
IIC_Stop();
//24c02写字节函数
void Write_24C02(unsigned char addr, unsigned char dat)
IIC_Start();
IIC_SendByte(0xa0); //设备写地址
IIC_WaitAck();
IIC_SendByte(addr); //发送内存字节地址
IIC_WaitAck();
IIC_SendByte(dat); //写入目标数据
IIC_WaitAck();
IIC_Stop();
//24C02字节读函数
unsigned char Read_24c02(unsigned char dat)
unsigned char temp;
//先进行一个伪写操作
IIC_Start();
IIC_SendByte(0xa0); //设备写地址
IIC_WaitAck();
IIC_SendByte(dat); //发送内存字节地址
IIC_WaitAck();
//再进行字节读操作
IIC_Start();
IIC_SendByte(0xa1); //设备读地址
IIC_WaitAck();
temp = IIC_RecByte(); //读取目标数据
IIC_Ack(0); //产生非应答信号
IIC_Stop();
return temp;
//数码管显示实时数据
void show_now()
show(0,table[10]);
delay(500);
show(1,table[level]);
delay(500);
show(2,table[10]);
delay(500);
show(3,0xff);
delay(500);
show(4,0xff);
delay(500);
show(5,table[rd1/100]);
delay(500);
show(6,table[rd1/10%10]);
delay(500);
show(7,table[rd1%10]);
delay(500);
//数码管显示历史数据
void show_old()
show(0,table[10]);
delay(500);
show(1,table[old_level]);
delay(500);
show(2,table[10]);
delay(500);
show(3,0xff);
delay(500);
show(4,0xff);
delay(500);
show(5,table[old_rd1/100]);
delay(500);
show(6,table[old_rd1/10%10]);
delay(500);
show(7,table[old_rd1%10]);
delay(500);
//单个数码管显示函数
void show(unsigned char pos, unsigned char value)
XBYTE[0xE000] = 0xFF; //消隐
XBYTE[0xC000] = 0x01 << pos; //选择数码管的位置
XBYTE[0xE000] = value; //输出数码管显示的内容
//延时函数
void delay(unsigned int t)
while(t--);
IIC驱动代码
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include "reg52.h"
#include "intrins.h"
#define somenop _nop_();_nop_();_nop_();_nop_();_nop_();
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
//总线启动条件
void IIC_Start(void)
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
//总线停止条件
void IIC_Stop(void)
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
//应答位控制
void IIC_Ack(bit ackbit)
if(ackbit)
SDA = 0;
else
SDA = 1;
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1;
somenop;
//等待应答
bit IIC_WaitAck(void)
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
SCL = 0;
IIC_Stop();
return 0;
else
SCL = 0;
return 1;
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
unsigned char i;
for(i=0;i<8;i++)
if(byt&0x80)
SDA = 1;
else
SDA = 0;
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
return da;
#ifndef _IIC_H
#define _IIC_H
//函数声明
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(bit ackbit);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
#endif
以上是关于蓝桥杯15——PCF8591与24C02综合应用:智能照明自动控制器的主要内容,如果未能解决你的问题,请参考以下文章