实验平台:CT107D
实验芯片:stc15f2k60s2
实验现象:完成题目要求
代码如下
#include
#include
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
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);
}
void set_sfm(unsigned char shi,unsigned char fen,unsigned char miao)
{
Write_Ds1302_Byte(0x8e,0x00);//关闭保护位
Write_Ds1302_Byte(0x80,(miao/10)*16+miao%10);//设置秒
Write_Ds1302_Byte(0x82,(fen/10)*16+fen%10);//设置分
Write_Ds1302_Byte(0x84,(shi/10)*16+shi%10);//设置小时
Write_Ds1302_Byte(0x8e,0x80);//打开保护位
}
#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 );
void set_sfm(unsigned char shi,unsigned char fen,unsigned char miao);
#endif
#include "stc15f2k60s2.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
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;
}
void write_eeprom(unsigned char add,unsigned char date)
{
IIC_Start();//启动总线
IIC_SendByte(0xa0);//发送设备地址,第八位为0所以为写
IIC_WaitAck();//等待应答
IIC_SendByte(add);//发送数据地址
IIC_WaitAck();//等待应答
IIC_SendByte(date);//发送数据
IIC_WaitAck();//等待应答
IIC_Stop();//停止总线
}
unsigned char read_eeprom(unsigned char add)
{
unsigned char temp;//定义变量temp用来获得eeprom中的数据
EA = 0;//关闭中断,中断可能会影响总线时序
IIC_Start();//开启总线
IIC_SendByte(0xa0);
//发送设备地址,第八位为0所以为写,因为读取的时候为读取现在的地址加一,所以要发送现在写的地址进去
IIC_WaitAck();//等待应答
IIC_SendByte(add);//发送数据地址
IIC_WaitAck();//等待应答
IIC_Start();//开启总线
IIC_SendByte(0xa1);//发送设备地址,第八位为1所以为读,读取的地址为刚刚我们写入的地址
IIC_WaitAck();//等待应答
temp = IIC_RecByte();//读取数据
IIC_WaitAck();//等待应答
IIC_Stop();//停止总线
EA = 1;//打开中断
return temp;//返回temp
}
void init_adc(unsigned char add)
{
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Stop();
}
unsigned char read_adc()
{
unsigned char dat;
EA = 0;
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
dat = IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
EA = 1;
return dat;
}
#ifndef _IIC_H
#define _IIC_H
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
void write_eeprom(unsigned char add,unsigned char date);
unsigned char read_eeprom(unsigned char add);
void init_adc(unsigned char add);
unsigned char read_adc();
#endif
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit buzz = P0^6;
sbit relay = P0^4;
bit mode = 1;//1为自动,0为手动
bit read_ad = 0;
bit buzz_open_flag = 1;
bit open_flag = 0;
bit set_flag = 0;
bit waring_flag = 0;
uchar duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00,0x40};
uchar disbuff[8];
uchar trg,cont;
uchar shi_temp,fen_temp;
uchar shi,fen;
uchar shidu;
uchar sdyz=50;
void keyscan()
{
uchar keydate = P3^0xff;
trg = keydate&(keydate^cont);
cont = keydate;
}
void keyfun()
{
if(trg == 0x01)
{
mode = ~mode ;
}
//手动模式
if((trg == 0x02)&&(mode == 0))
{
buzz_open_flag = ~buzz_open_flag;
}
if((trg == 0x04)&&(mode == 0))
{
open_flag = 1;
}
if((trg == 0x08)&&(mode == 0))
{
open_flag = 0;
}
//自动模式
if((trg == 0x02)&&(mode == 1))
{
set_flag = ~set_flag;
if(set_flag == 0)
{
write_eeprom(0x01,sdyz);
}
if(set_flag == 1)
{
sdyz = read_eeprom(0x01);
}
}
if((trg == 0x04)&&(mode == 1))
{
if(sdyz==99)
sdyz=99;
else
sdyz++;
}
if((trg == 0x08)&&(mode == 1))
{
if(sdyz==0)
sdyz=0;
else
sdyz--;
}
}
void shownum()
{
if((set_flag == 1)&&(mode == 1))
{
disbuff[0] = 17;
disbuff[1] = 17;
disbuff[2] = 16;
disbuff[3] = 16;
disbuff[4] = 16;
disbuff[5] = 16;
disbuff[6] = sdyz/10;
disbuff[7] = sdyz%10;
}
else
{
disbuff[0] = shi/10;
disbuff[1] = shi%10;
disbuff[2] = 17;
disbuff[3] = fen/10;
disbuff[4] = fen%10;
disbuff[5] = 16;
disbuff[6] = shidu/10;
disbuff[7] = shidu%10;
}
}
void display()
{
static uchar index;
P2 = P2&0x1f|0xe0;
P0 = ~0xff;
P2 = P2&0x1f;
P2 = P2&0x1f|0xc0;
P0 = 1<<index;
P2 = P2&0x1f;
P2 = P2&0x1f|0xe0;
P0 = ~duan[disbuff[index]];
P2 = P2&0x1f;
index++;
index &= 0x07;
}
void LED()
{
if(mode == 0)
{
P2 = P2&0x1f|0x80;
P0 = ~0x02;
P2 = P2&0x1f;
}
if(mode == 1)
{
P2 = P2&0x1f|0x80;
P0 = ~0x01;
P2 = P2&0x1f;
}
}
void set_fucker()
{
if((buzz_open_flag == 0)&&(open_flag == 0))
{
P2 = P2&0x1f|0xa0;
buzz = 0;
relay = 0;
P2 = P2&0x1f;
}
if((buzz_open_flag == 0)&&(open_flag == 1))
{
P2 = P2&0x1f|0xa0;
buzz = 0;
relay = 1;
P2 = P2&0x1f;
}
if((buzz_open_flag == 1)&&(waring_flag == 1)&&(mode == 0)&&(open_flag == 0))
{
P2 = P2&0x1f|0xa0;
buzz = 1;
relay = 0;
P2 = P2&0x1f;
}
if((buzz_open_flag == 1)&&(waring_flag == 1)&&(mode == 0)&&(open_flag == 1))
{
P2 = P2&0x1f|0xa0;
buzz = 1;
relay = 1;
P2 = P2&0x1f;
}
if((buzz_open_flag == 1)&&(waring_flag == 0)&&(open_flag == 0))
{
P2 = P2&0x1f|0xa0;
buzz = 0;
relay = 0;
P2 = P2&0x1f;
}
if((buzz_open_flag == 1)&&(waring_flag == 0)&&(open_flag == 1))
{
P2 = P2&0x1f|0xa0;
buzz = 0;
relay = 1;
P2 = P2&0x1f;
}
}
void drive()
{
if(shidu<sdyz) waring_flag = 1;
else waring_flag = 0;
if((mode == 1)&&(shidu<sdyz)) open_flag = 1;
if((mode == 1)&&(shidu>=sdyz)) open_flag = 0;
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
EA = 1;
}
void time1() interrupt 1
{
static uint count;
display();
keyscan();
keyfun();
if(++count == 500)
{
read_ad = 1;
count = 0;
set_fucker();
drive();
}
}
void main()
{
Timer0Init();
set_sfm(8,30,0);
init_adc(0x03);
while(1)
{
shownum();
LED();
shi_temp = Read_Ds1302_Byte(0x85);
fen_temp = Read_Ds1302_Byte(0x83);
shi = shi_temp/16*10+shi_temp%16;
fen = fen_temp/16*10+fen_temp%16;
if(read_ad == 1)
{
shidu = read_adc();
shidu = shidu/255.0f*99;
read_ad = 0;
}
}
}