目录
1.使用的模块
1)蜂鸣器和继电器。
2)LED灯。
3)数码管。
4)AD、DA模块。
5)独立按键模块。
6)DS302模块。
2.基本功能
1)光敏电阻输出的电压超过3V就产生报警。
2)转口输出的电压超过3.5V就产生报警。
3)数码管可以显示电压和实时时钟。
4)时间为整点时发生警报。
3.报警的功能
1)光敏电阻输出的电压报警产生的功能为100ms流水灯和蜂鸣器响继电器吸合。
2)转口电阻输出的电压报警产生的功能为LED灯隔个点亮。
3)光敏电阻输出的电压报警和转口报警同时符合条件时值产生光敏报警模式。
4)当实时时钟的时间为整点时继电器吸合,LED3点亮其他熄灭。
4.按键功能
1)S4按下转换数码管显示界面。
2)在什么界面都是S5按下报警停止。
5.初始化
1)继电器与蜂鸣器都关闭。
2)数码管显示ADC界面。
3)实时时钟初始时间为8:58:00。
4)数码管显示图片
电压显示
实时时钟显示
6.代码如下
main
#include <STC15F2K60S2.H>
#include "iic.h"
#include "ds1302.h"
void Delay() //@12.000MHz
{
unsigned char i, j;
i = 6;
j = 211;
do
{
while (--j);
} while (--i);
}
void Timer2Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0x18; //设置定时初始值
T2H = 0xFC; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
EA=1; //开启总中断
IE2 |= 0x04; //开启定时器2中断
}
void Device(unsigned char p2,unsigned char p0)//配置138锁存器
{
P0=p0;
P2=P2&0x1f|p2;
P2 &=0x1f;
}
void system()//初始化
{
Device(0xa0,0);//关闭蜂鸣器与继电器
Device(0x80,0xff);//关闭LED灯
}
unsigned int smgs[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3E,0x80,0x39,0x40};
//0~9 10U 11 . 13-
void smg(unsigned n,unsigned m)//数码管显示函数
{
int a;
a=0x01<<n;
Device(0xc0,0);
Device(0xe0,~smgs[m]);//显示内容
Device(0xc0,a);//位置n+1
}
unsigned char u1,ms,u2;//收集电压的1变量相关变量
unsigned int u1_5,u2_5;//变量的转变
void ADC_read()//ADC采集,10模式采集一次 , 因为每次都是上一次的值,所以要使用两次该函数
{
if(ms>=10)
{
ms=0;
ADC(0x41);
u1=ADC(0x41);
ADC(0x43);
u2=ADC(0x43);
//255->500
u1_5=u1*100/51;
u2_5=u2*100/51;
}
}
//Delay()作用是让数码管显示更加明亮
void show_adc()//显示电压的函数
{
smg(0,u1_5/100);Delay();
smg(0,11);Delay();
smg(1,u1_5/10%10);Delay();
smg(2,u1_5%10);Delay();
smg(4,u2_5/100);Delay();
smg(4,11);Delay();
smg(5,u2_5/10%10);Delay();
smg(6,u2_5%10);Delay();
smg(7,10);Delay();
}
int s,min,h;//收据时间变量
void ds1302()//实时时钟采集
{
s= BCDToDec(Read_Ds1302_Byte( 0x81 ));
min=BCDToDec(Read_Ds1302_Byte( 0x83 ));
h=BCDToDec(Read_Ds1302_Byte( 0x85 ));
}
void show_sj()//实时时钟显示函数
{
smg(0,h/10);Delay();
smg(1,h%10);Delay();
smg(2,13);Delay();
smg(3,min/10);Delay();
smg(4,min%10);Delay();
smg(5,13);Delay();
smg(6,s/10);Delay();
smg(7,s%10);Delay();
}
int led;//时间变量
int w;//位移变量
void Led_running()//流水灯函数
{
if(led>500)
{
led=0;
Device(0x80,~(0x01 << w));
w++;
w=w%8;
Device(0xa0,0x50);
}
}
unsigned char adc=0;//adc报警变量
int b=0;//按键功能变量
void adc_jb()//报警函数
{
//光敏电阻
if((u1_5>300)&&(adc==1)&&(b==0))
{
Led_running();
Device(0xa0,0x50);
}
//转口器
if((u2_5>350)&&(adc==2)&&(b==0))
{
Device(0x80,0xaa);
Device(0xa0,0);
}
//变量优先级条件
if((u1_5>300)&&(u2_5>300))
{adc=1;}
if((u2_5>350)&&(u1_5<300))
{adc=2;}
if((u2_5<350)&&(u1_5>300))
{adc=1;}
if((u2_5<350)&&(u1_5<300))
{adc=3;b=0;}
if((adc!=1)&&(adc!=2))
{Device(0x80,0xff);Device(0xa0,0);}
}
void ds1302_bj()//实时时钟报警器
{
//报警条件
if((min==0)&&(s==0)&&(b==0))
{
Device(0x80,~0x03);
Device(0xa0,0x10);
}
if(min==0&&(s==5))
{
b=0;
Device(0xa0,0);
Device(0x80,0xff);
}
}
int i;//界面转换变量
void key()//按键
{
if(P33==0)//s4
{Delay();if(P33==0){i++;i=i%2;while(P33==0){}}}
if(P32==0)//s5
{Delay();if(P32==0){b=1;}}
}
void main()
{
system();
Timer2Init();
vClock_Set(8,58,00);//实时时钟初始化时间
while(1)
{
}
}
void t2() interrupt 12//中断入口
{
key();
ADC_read();
ms++;
led++;
ds1302();
//根据变量显示界面
if(i==0)
{
show_adc();
adc_jb();
}
if(i==1)
{
show_sj();
ds1302_bj();
}
if(b==1)
{
Device(0xa0,0);
Device(0x80,0xff);
}
}
ds1302.c
#include <intrins.h>
#include "ds1302.h"
#include <STC15F2K60S2.H>
sbit SCK=P1^7;
sbit IO=P2^3;
sbit CE = P1^3; // DS1302复位
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
IO=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
CE=0; _nop_();
SCK=0; _nop_();
CE=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
CE=0;
}
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
CE=0; _nop_();
SCK=0; _nop_();
CE=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(IO)
temp|=0x80;
SCK=1;
}
CE=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
IO=0; _nop_();
IO=1; _nop_();
return (temp);
}
//实时时钟转变
void vClock_Set(unsigned char hour,unsigned char minute,unsigned char second)
{
Write_Ds1302_Byte(0x8e,0x00); //关闭写保护
Write_Ds1302_Byte(0x80,DecToBCD(second)); //写入小时数据到对应的地址
Write_Ds1302_Byte(0x82,DecToBCD(minute)); //写入分钟数据到对应的地址
Write_Ds1302_Byte(0x84,DecToBCD(hour)); //写入秒钟数据到对应的地址
Write_Ds1302_Byte(0x8e,0x80); //打开写保护
}
ds1302.h
#ifndef __DS1302_H
#define __DS1302_H
#define DecToBCD(dec) (dec/10*16)+(dec%10)//10进制转变为BCD码
#define BCDToDec(bcd) (bcd/16*10)+(bcd%16)//BCD码转变为10进制
unsigned char Read_Ds1302_Byte( unsigned char address );
void vClock_Set(unsigned char hour,unsigned char minute,unsigned char second);
#endif
iic .c
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
void Delay_Ms(unsigned int ms) //@12.000MHz
{
unsigned char i, j;
while(ms--)
{
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
//ADC输出函数
char ADC(unsigned char c)
{
char q;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(c);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
q=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return q;
}
iic .h
#ifndef _IIC_H
#define _IIC_H
void Write_EEPROM(unsigned char add, unsigned char dat);
unsigned char ucRead_EEPROM(unsigned char add);
char ADC(unsigned char c);
#endif
期待大家一起谈论不足之处。