题目要求(主要部分):
![](https://img-blog.csdnimg.cn/4257ea3744dc4ea8a84e699995155e33.png)
代码部分:
main.c
#include <REG52.H>
#include "IIC.h"
#include "onewire.h"
#include "DS1302.h"
sfr P4=0xc0;
sbit L1=P3^0;
sbit L2=P3^1;
sbit L3=P3^2;
sbit L4=P3^3;
sbit R1=P4^4;
sbit R2=P4^2;
sbit R3=P3^5;
sbit R4=P3^4;
void HC573(unsigned char channel,unsigned char value);
void Delay(unsigned int x);
void Nixie(unsigned char column,unsigned char value);
void System_Init();
unsigned char code Array[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};
unsigned char code Array_pot[]={0x40,0x79,0X24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char light_temp=0;//电压
float light_t=0;//中间过渡电压
unsigned int temperature=0;//温度
unsigned int V_light=0;//记录电压最终值
unsigned char code Read_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
unsigned char code Write_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char TIME[7]={0x50,0x59,0x16,0x00,0x00,0x00,0x00};
unsigned char Mode=0;//模式切换
unsigned int time_para=17;//时间参数
unsigned int temp_para=250;//温度参数
unsigned char LED_para=4;//指示灯参数
unsigned char Mode_Flag=0;//参数与显示页面切换参数
unsigned char LED_Flag=0;//指示灯
unsigned int Count=0;//定时器计数器
unsigned char LED_Flag3=0;//L3指示灯标志位
unsigned char LED_Flag_3=0;//L3指示灯开关指示
//时间初始化
void DS1302_Init()
{
unsigned char i;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<7;i++)
{
Write_Ds1302_Byte(Write_address[i],TIME[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
//读取时间
void Read_DS1302()
{
unsigned char i;
for(i=0;i<7;i++)
{
TIME[i]=Read_Ds1302_Byte(Read_address[i]);
}
}
//显示时间
void Display_time()
{
Nixie(1,Array[TIME[2]/16]);
Nixie(2,Array[TIME[2]%16]);
Nixie(3,Array[16]);
Nixie(4,Array[TIME[1]/16]);
Nixie(5,Array[TIME[1]%16]);
Nixie(6,Array[16]);
Nixie(7,Array[TIME[0]/16]);
Nixie(8,Array[TIME[0]%16]);
}
//延时
void Delay100us() //@12.000MHz
{
unsigned char i, j;
i = 2;
j = 39;
do
{
while (--j);
} while (--i);
}
//读取温度
unsigned int temperature_Read()
{
unsigned char LSB,MSB;
unsigned int temp;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay100us();
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xBE);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
temp=(MSB<<8)|LSB;
temp=temp>>4;
temp*=10;
temp=temp+(LSB&0x0f)*0.625;
return temp;
}
//显示温度界面
void Display_temperature()
{
Nixie(1,Array[12]);
Nixie(2,0xff);
Nixie(3,0xff);
Nixie(4,0xff);
Nixie(5,0xff);
Nixie(6,Array[temperature/100%10]);
Nixie(7,Array_pot[temperature/10%10]);
Nixie(8,Array[temperature%10]);
}
//光敏电阻模块
void Display_light()
{
Nixie(1,Array[14]);
Nixie(2,0xff);
Nixie(3,Array_pot[V_light/100%10]);
Nixie(4,Array[V_light/10%10]);
Nixie(5,Array[V_light%10]);
Nixie(6,0xff);
Nixie(7,0xff);
if(V_light<120)
{
Nixie(8,Array[1]);
}
else
{
Nixie(8,Array[0]);
}
}
//读取Rb1,光敏电阻
void Read_PCF8591_light()
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x41);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
light_temp=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
light_t=light_temp*(5.0/255);
V_light=light_t*100;
}
//参数设置页面
void Display_parameter()
{
Nixie(1,0x8c);
if(Mode==0)
{
Nixie(2,Array[1]);
Nixie(7,Array[time_para/10%10]);
Nixie(8,Array[time_para%10]);
}
else if(Mode==1)
{
Nixie(2,Array[2]);
Nixie(7,Array[temp_para/100%10]);
Nixie(8,Array[temp_para/10%10]);
}
else if(Mode==2)
{
Nixie(2,Array[3]);
Nixie(7,0xff);
Nixie(8,Array[LED_para%10]);
}
Nixie(3,0xff);
Nixie(4,0xff);
Nixie(5,0xff);
Nixie(6,0xff);
}
//键盘扫描
void Key_Scan()
{
L4=0;
L1=L2=L3=1;
R1=R2=R3=R4=1;
if(R1==0)
{
if(Mode==0)Mode=1;
else if(Mode==1)Mode=2;
else if(Mode==2)Mode=0;
while(R1==0);
}
else if(R2==0)
{
if(Mode_Flag==1)
{
if(Mode==0){time_para--;if(time_para==255)time_para=23;}
else if(Mode==1){if(temp_para==0)temp_para=1000;temp_para-=10;}
else if(Mode==2){LED_para--;if(LED_para==3)LED_para=8;}
while(R2==0){Display_parameter();}
}
}
L3=0;
L1=L2=L4=1;
R1=R2=R3=R4=1;
if(R1==0)
{
if(Mode_Flag==0){Mode_Flag=1;}
else if(Mode_Flag==1){Mode_Flag=0;}
Mode=0;
while(R1==0);
}
else if(R2==0)
{
if(Mode_Flag==1)
{
if(Mode==0){time_para++;if(time_para==24)time_para=0;}
else if(Mode==1)temp_para+=10;
else if(Mode==2){LED_para++;if(LED_para==9)LED_para=4;}
while(R2==0){Display_parameter();}
}
}
}
//显示界面选择函数
void Display_All()
{
if(Mode_Flag==0)
{
if(Mode==2)
{
Display_light();
}
else if(Mode==1)
{
Display_temperature();
}
else if(Mode==0)
{
Read_DS1302();
Display_time();
}
}
else if(Mode_Flag==1)
{
Display_parameter();
}
}
//指示灯控制
void LED_ctrl()
{
if(time_para<8)
{
//将TIME[2]的16进制数据转化为十进制,以便于和int类型数据比较
if((time_para<=(TIME[2]/16*10+TIME[2]%16))&&((TIME[2]/16*10+TIME[2]%16)<8))
{
LED_Flag=P0&0xfe;
HC573(4,LED_Flag);
}
else
{
LED_Flag=P0|0x01;
HC573(4,LED_Flag);
}
}
else if(time_para>8)
{
if((time_para<=(TIME[2]/16*10+TIME[2]%16)))
{
LED_Flag=P0&0xfe;
HC573(4,LED_Flag);
}
else
{
LED_Flag=P0|0x01;
HC573(4,LED_Flag);
}
}
if(temperature<temp_para)
{
LED_Flag=P0&0xfd;
HC573(4,LED_Flag);
}
else
{
LED_Flag=P0|0x02;
HC573(4,LED_Flag);
}
if(V_light<120)//被遮挡
{
LED_Flag=P0&(~(0x08<<(LED_para-4)));
HC573(4,LED_Flag);
if(V_light<120&&LED_Flag3==0)//如果此时被遮挡且标志位为0
{
LED_Flag3=1;//标志位置1
TR0=1;//开启定时器
}
}
//LED_Flag3主要针对从暗(亮)模式变化到亮(暗)模式下,置位
else
{
LED_Flag=P0|(0x08<<(LED_para-4));
HC573(4,LED_Flag);
if(V_light>120&&LED_Flag3==1)
{
LED_Flag3=0;
TR0=1;
}
}
//LED3的控制
if(LED_Flag_3==1)
{
LED_Flag=P0&0xfb;
HC573(4,LED_Flag);
}
else if(LED_Flag_3==0)
{
LED_Flag=P0|(~0xfb);
HC573(4,LED_Flag);
}
}
void Time_init()
{
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
TF0=0;
TR0=0;
EA=1;
ET0=1;
}
void main()
{
System_Init();
while(1)
{
Read_PCF8591_light();
temperature=temperature_Read();
Display_All();
Key_Scan();
LED_ctrl();
}
}
void Time0() interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
Count++;
if(Count>60)//三秒判断一次
{
if(V_light<120&&LED_Flag3==1)LED_Flag_3=1;//当三秒后还处于暗模式,置标志位
else if(V_light>120&&LED_Flag3==0)LED_Flag_3=0;//三秒后处于亮模式
Count=0;
TR0=0;//判断一次后关闭定时器
}
}
void System_Init()
{
HC573(5,0x00);
HC573(4,0xff);
DS1302_Init();
Time_init();
temperature_Read();
Delay(700);
}
void HC573(unsigned char channel,unsigned char value)
{
P2=(0x1f&P2)|0x00;
P0=value;
switch(channel)
{
case 4:P2=(0x1f&P2)|0x80;break;
case 5:P2=(0x1f&P2)|0xa0;break;
case 6:P2=(0x1f&P2)|0xc0;break;
case 7:P2=(0x1f&P2)|0xe0;break;
case 0:P2=(0x1f&P2)|0x00;break;
}
P2=(0x1f&P2)|0x00;
}
void Delay(unsigned int x)
{
unsigned char i,j;
while(x--)
{
i=11;j=190;
do
{
while(--j);
}while(--i);
}
}
void Nixie(unsigned char column,unsigned char value)
{
HC573(6,0x01<<(column-1));
HC573(7,value);
Delay(1);
HC573(6,0x01<<(column-1));
HC573(7,0xff);
}
IIC.h
#ifndef __IIC_H_
#define __IIC_H_
void I2CSendAck(unsigned char ackbit);
unsigned char I2CWaitAck(void);
unsigned char I2CReceiveByte(void);
void I2CSendByte(unsigned char byt);
void I2CStop(void);
void I2CStart(void);
#endif
IIC.C
#include <REG52.H>
#include "intrins.h"
sbit sda=P2^1;
sbit scl=P2^0;
#define DELAY_TIME 5
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
onewire.h
#ifndef __onewire_H_
#define __onewire_H_
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
#endif
onewire.c
#include <REG52.H>
sbit DQ=P1^4;
//
void Delay_OneWire(unsigned int t)
{
unsigned char i;
while(t--){
for(i=0;i<12;i++);
}
}
//
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
DS1302.h
#ifndef __ds1302_H_
#define __ds1302_H_
void Write_Ds1302(unsigned char temp) ;
void Write_Ds1302_Byte( unsigned char address,unsigned char dat ) ;
unsigned char Read_Ds1302_Byte ( unsigned char address );
#endif
DS1302.c
#include <REG52.H>
#include "intrins.h"
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST=P1^3;
//
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK = 0;
SDA = temp&0x01;
temp>>=1;
SCK=1;
}
}
//
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}