注:代码使用reg52.h头文件,采用小蜜蜂老师代码格式。
题目:
示例代码:
main.c(函数都写在main函数内,未采用模块化)
#include <REGX52.H>
#include "DS1302.h"
#include "intrins.h"
#include "IIC.h"
sfr P4=0xc0;
sbit TX=P1^0;
sbit RX=P1^1;
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(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[10]={0x40,0x79,0X24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char code DS1302_Read_Address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
unsigned char code DS1302_Write_Address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char Time[]={0x55,0x20,0x20,0x00,0x00,0x00,0x00};
unsigned int Distance;//超声波距离计算
unsigned char Mode_S4=0;//S4
unsigned char Mode_S5=0;//S5
unsigned char Time_P=2;//采集时间参数
unsigned char Distance_P=10;//采集距离参数
unsigned char Chao_Mode=0;//超声波采集模式
unsigned char Data_Mode=0;//数据显示模式
unsigned int Average_Data=0;//平均值
unsigned int Max_Data=0;//最大值
unsigned int Min_Data=100;//最小值
unsigned int Sum=0;//总和
unsigned int cnt=0;//记录测量数据次数
unsigned char Measur_Falg=0;//测量标志位
unsigned char Temp=0;//记录采集电压值
unsigned char Flag_Trigger=0;//触发模式下标志位
unsigned char Alarm_Flag=0;//警报标志位
unsigned char LED_Stat=0xff;//灯光设置
unsigned char LED=0xff;//用于前4个led灯光选择
//RB1光敏电阻读取
void PCF8591_Read()
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x41);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
Temp=I2CReceiveByte();
I2CSendAck(1);
I2CStop();
}
//电压输出
void Set_DAC(unsigned char Data)
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x41);
I2CWaitAck();
if(Distance<=10)
{
I2CSendByte(51);
}
else if(Distance>=78)
{
I2CSendByte(255);
}
else
{
Data=3*Data+21;
I2CSendByte(Data);
}
I2CSendAck(1);
I2CStop();
}
void DS1302_Init()
{
unsigned char i;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<7;i++)
{
Write_Ds1302_Byte(DS1302_Write_Address[i],Time[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void DS1302_Read_Time()
{
unsigned char i;
for(i=0;i<7;i++)
{
Time[i]=Read_Ds1302_Byte(DS1302_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 Delay12us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 28;
while (--i);
}
void Send_Wave()
{
unsigned char i;
for(i=0;i<8;i++)
{
TX=1;
Delay12us();
TX=0;
Delay12us();
}
}
void Time_Chao()
{
unsigned int temp;
TMOD&=0x0F;
TH1=0;
TL1=0;
Send_Wave();
TR1=1;
while((RX==1)&&(TF1==0));
TR1=0;
if(TF1==0)
{
temp=TH1;
temp=(temp<<8)|TL1;
Distance=((temp/10)*17)/100+3;
}
TH1=0;
TL1=0;
}
//超声波显示
void Display_chao()
{
Nixie(1,0xc7);
if(Chao_Mode==0)
{
Nixie(2,0xc6);
}
else if(Chao_Mode==1)
{
Nixie(2,Array[15]);
}
Nixie(3,0xff);
Nixie(4,0xff);
Nixie(5,0xff);
if((Distance/100%10)==0)Nixie(6,0xff);
else Nixie(6,Array[Distance/100%10]);
Nixie(7,Array[Distance/10%10]);
Nixie(8,Array[Distance%10]);
}
//超声波增强显示
void Display_Delay(unsigned int x)
{
while(x--)
{
Display_chao();
}
}
//数据记录显示页面
void Display_Data()
{
Nixie(1,0x89);
if(Data_Mode==0)
{
Nixie(2,0xfe);
Nixie(5,0xff);
Nixie(6,Array[Max_Data/100%10]);
Nixie(7,Array[Max_Data/10%10]);
Nixie(8,Array[Max_Data%10]);
}
else if(Data_Mode==1)
{
Nixie(2,0xBF);
Nixie(5,Array[Average_Data/1000%10]);
Nixie(6,Array[Average_Data/100%10]);
Nixie(7,Array_pot[Average_Data/10%10]);
Nixie(8,Array[Average_Data%10]);
}
else if(Data_Mode==2)
{
Nixie(2,0xf7);
Nixie(5,0xff);
Nixie(6,Array[Min_Data/100%10]);
Nixie(7,Array[Min_Data/10%10]);
Nixie(8,Array[Min_Data%10]);
}
Nixie(3,0xff);
Nixie(4,0xff);
}
//参数设置页面
void Display_Para()
{
Nixie(1,0x8c);
if(Mode_S5==0)
{
Nixie(2,Array[1]);
Nixie(7,Array[Time_P/10%10]);
Nixie(8,Array[Time_P%10]);
}
else if(Mode_S5==1)
{
Nixie(2,Array[2]);
Nixie(7,Array[Distance_P/10%10]);
Nixie(8,Array[Distance_P%10]);
}
Nixie(3,0xff);
Nixie(4,0xff);
Nixie(5,0xff);
Nixie(6,0xff);
}
//显示选择
void Display_channel()
{
if(Mode_S4==0)
{
if(Mode_S5==0)
{
Display_Time();
}
else if(Mode_S5==1)
{
Display_Delay(10);
}
else if(Mode_S5==2)
{
Display_Data();
}
}
else if(Mode_S4==1)
{
Display_Para();
}
}
//矩阵按键
void Key_Scan()
{
L4=0;
L1=L2=L3=1;
R1=R2=R3=R4=1;
if(R1==0)
{
if(Mode_S4==0){Mode_S4=1;Mode_S5=0;}
else if(Mode_S4==1){Mode_S4=0;Mode_S5=0;}
while(R1==0)
{
Display_channel();
}
}
else if(R2==0)
{
if((Mode_S4==0)&&(Mode_S5==1))
{
if(Chao_Mode==0)Chao_Mode=1;
else if(Chao_Mode==1)Chao_Mode=0;
}
else if((Mode_S4==0)&&(Mode_S5==2))
{
if(Data_Mode==0)Data_Mode=1;
else if(Data_Mode==1)Data_Mode=2;
else if(Data_Mode==2)Data_Mode=0;
}
while(R2==0)
{
Display_channel();
}
}
L3=0;
L1=L2=L4=1;
R1=R2=R3=R4=1;
if(R1==0)
{
if(Mode_S4==0)
{
if(Mode_S5==0){Mode_S5=1;}
else if(Mode_S5==1){Mode_S5=2;Mode_S4=0;}
else if(Mode_S5==2){Mode_S5=0;}
}
else if(Mode_S4==1)
{
if(Mode_S5==0)Mode_S5=1;
else if(Mode_S5==1)Mode_S5=0;
}
while(R1==0)
{
Display_channel();
}
}
else if(R2==0)
{
if((Mode_S4==1)&&(Mode_S5==0))
{
if(Time_P==2)Time_P=3;
else if(Time_P==3)Time_P=5;
else if(Time_P==5)Time_P=7;
else if(Time_P==7)Time_P=9;
else if(Time_P==9)Time_P=2;
}
else if((Mode_S4==1)&&(Mode_S5==1))
{
Distance_P+=10;
if(Distance_P>80)Distance_P=10;
}
while(R2==0)
{
Display_channel();
}
}
}
//超声波数据记录
void Data_Deal()
{
cnt++;
Max_Data=Max_Data<Distance?Distance:Max_Data;
Min_Data=Distance<Min_Data?Distance:Min_Data;
Sum+=Distance;
Average_Data=(Sum*10/cnt);
if(((Distance-Distance_P)<5)||((Distance_P-Distance)<=5))//在参数测量+-5cm
{
Alarm_Flag++;
}
else
{
Alarm_Flag=0;
}
}
//超声波测量选择
void Measure_Channel()
{
if(Chao_Mode==0)//触发模式
{
if(Temp>=130)//在亮状态置标志位
{
Flag_Trigger=1;
}
else if((Temp<100)&&(Flag_Trigger==1))//暗状态启动测量同时清除标志位
{
Time_Chao();
Data_Deal();
Flag_Trigger=0;//实现进行1次测量
}
}
else if((Chao_Mode==1)&&((Time[0]%Time_P)==0))//定时模式
{
if(Measur_Falg!=Time[0])//对标志位检测,实现到时间后执行1次测量
{
Time_Chao();
Data_Deal();
Measur_Falg=Time[0];
}
}
}
//灯光控制
void LED_Ctrl()
{
if(Mode_S4==0)//在数据界面选择显示前4个LED
{
if((Mode_S4==0)&&(Mode_S5==0))
{
LED_Stat=LED&0xfe;//使用LED&想要亮的灯,进行单独显示
HC573(4,LED_Stat);
}
else if((Mode_S4==0)&&(Mode_S5==1))
{
LED_Stat=LED&0xfD;
HC573(4,LED_Stat);
}
else if((Mode_S4==0)&&(Mode_S5==2))
{
LED_Stat=LED&0xfB;
HC573(4,LED_Stat);
}
}
else if(Mode_S4==1)//参数页面关闭前4个LED
{
LED_Stat=0xff;
HC573(4,LED_Stat);
}
//超声波触发模式还是定时模式
if(Chao_Mode==0)
{
LED_Stat=LED_Stat&0xF7;
HC573(4,LED_Stat);
}
else
{
LED_Stat=LED_Stat|0x08;
HC573(4,LED_Stat);
}
//警报灯
if(Alarm_Flag>=3)
{
LED_Stat=LED_Stat&0xef;
HC573(4,LED_Stat);
}
else
{
LED_Stat=LED_Stat|0x10;
HC573(4,LED_Stat);
}
//光敏电阻检测灯
if(Temp>=130)
{
LED_Stat=LED_Stat&0xDf;
HC573(4,LED_Stat);
}
else if(Temp<100)
{
LED_Stat=LED_Stat|0x20;
HC573(4,LED_Stat);
}
}
void main()
{
System_init();
DS1302_Init();
while(1)
{
DS1302_Read_Time();
Display_channel();//数码管总显示选择
Measure_Channel();//超声波测量模式选择
PCF8591_Read();//光敏电阻读取
Key_Scan();
Set_DAC(Distance);//设置DAC输出
LED_Ctrl();//灯光设置
}
}
void System_init()
{
HC573(4,0xff);
HC573(5,0x00);
}
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(int x) //@12.000MHz
{
unsigned char i, j;
while(x--)
{
i = 12;
j = 169;
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);
}
ds1302.c
#include <REGX52.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);
}
ds1302.h
#ifndef __DS1302_H_
#define __DS1302_H_
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte ( unsigned char address );
#endif
iic.c
#include <REGX52.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);
}
iic.h
#ifndef __IIC_H_
#define __IIC_H_
void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
void I2CSendAck(unsigned char ackbit);
unsigned char I2CWaitAck(void);
#endif