驅動:
//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();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/260662.html
標籤:其他
上一篇:獨立按鍵控制LED狀態
