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