题目
我的解答
DS1302
DS1302.h
#ifndef __DS1302_H__
#define __DS1302_H__
extern unsigned char DS1302_Time[3];
void DS1302_Init();
void SetTime();
void ReadTime();
#endif
DS1302.C
#include <STC15F2K60S2.H>
#define DS1302_Sec 0x80
#define DS1302_Min 0x82
#define DS1302_Hou 0x84
#define DS1302_WP 0x8E
sbit DS1302_SCLK=P1^7;
sbit DS1302_IO=P2^3;
sbit DS1302_CE=P1^3;
unsigned char DS1302_Time[3]={11,50,59};
void DS1302_Init()
{
DS1302_CE=0;
DS1302_SCLK=0;
}
void DS1302_Write(unsigned char Command,Data)
{
unsigned char k;
DS1302_CE=1;
for(k=0;k<8;k++)
{
DS1302_IO=Command&(0x01<<k);
DS1302_SCLK=0;
DS1302_SCLK=1;
}
for(k=0;k<8;k++)
{
DS1302_IO=Data&(0x01<<k);
DS1302_SCLK=0;
DS1302_SCLK=1;
}
DS1302_CE=0;
}
unsigned char DS1302_Read(unsigned char Command)
{
unsigned char k,Data=0x00;
Command|=0x01;
DS1302_CE=1;
for(k=0;k<8;k++)
{
DS1302_IO=Command&(0x01<<k);
DS1302_SCLK=0;
DS1302_SCLK=1;
}
for(k=0;k<8;k++)
{
DS1302_SCLK=1;
DS1302_SCLK=0;
if(DS1302_IO){Data|=(0x01<<k);};
}
DS1302_IO=0;
DS1302_CE=0;
return Data;
}
void SetTime()
{
unsigned char Temp;
DS1302_Write(DS1302_WP,0x00);
Temp=DS1302_Time[0];
DS1302_Write(DS1302_Hou,Temp/10*16+Temp%10);
Temp=DS1302_Time[1];
DS1302_Write(DS1302_Min,Temp/10*16+Temp%10);
Temp=DS1302_Time[2];
DS1302_Write(DS1302_Sec,Temp/10*16+Temp%10);
DS1302_Write(DS1302_WP,0x80);
}
void ReadTime()
{
unsigned char Temp;
Temp=DS1302_Read(DS1302_Hou);
DS1302_Time[0]=Temp/16*10+Temp%16;
Temp=DS1302_Read(DS1302_Min);
DS1302_Time[1]=Temp/16*10+Temp%16;
Temp=DS1302_Read(DS1302_Sec);
DS1302_Time[2]=Temp/16*10+Temp%16;
}
iic
iic.h
#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 AT24C02_Write(unsigned char Address,Data);
unsigned char AT24C02_Read(unsigned char Address);
void Delay1ms(unsigned int x);
#endif
iic.c
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include "reg52.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 AT24C02_Write(unsigned char Address,Data)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(Address);
IIC_WaitAck();
IIC_SendByte(Data);
IIC_WaitAck();
IIC_Stop();
}
unsigned char AT24C02_Read(unsigned char Address)
{
unsigned char Data;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(Address);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
Data=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return Data;
}
void Delay1ms(unsigned int x) //@12.000MHz
{
unsigned char i, j;
while(x--)
{
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
Timer
Timer.h
#ifndef __Timer_H__
#define __Timer_H__
void Timer0Init(void);
void Timer1Init(void);
#endif
Timer.c
#include <STC15F2K60S2.H>
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR = 0xc0; //定时器时钟1T模式
TMOD = 0x00; //设置定时器模式
TL0 = 0x20; //设置定时初值
TH0 = 0xD1; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1;
ET0=1;
}
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR = 0xc0; //定时器时钟1T模式
TMOD = 0x00; //设置定时器模式
TL1 = 0x00; //设置定时初值
TH1 = 0x00; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 0; //定时器1开始计时
}
主程序
main.c
#include <STC15F2K60S2.H>
#include "Timer.h"
#include "DS1302.h"
#include "iic.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit A1=P1^0;
sbit B1=P1^1;
u8 code ledguan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
u8 wei_xuan,disp[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
u8 KN,KTN,KeyN;
u8 Key();
u8 GetState();
void Key_Loop();
u16 length=999,time,wave_count,length_din=300;
void Start();
void delay(u8 i);
void Pros();
void Wave_Rec();
bit Mode=0,xiugai_t;
u8 DS_an_count=0;
bit Wave_an_count=0;
u8 hour,min,sec;
u16 led_count=0;
bit led;
bit fmq,fmqq;
u16 fmq_count;
void main()
{
P2=0x80;P0=0xfe;P2=0x00;
P2=0xc0;P0=0xff;P2=0x00;
P2=0xe0;P0=0x00;P2=0x00;
P2=0xa0;P0=0x40;P2=0x00;
Delay1ms(1000);
P2=0X80;P0=0xff;P2=0x00;
P2=0xc0;P0=0xff;P2=0x00;
P2=0xe0;P0=0xff;P2=0x00;
P2=0xa0;P0=0x00;P2=0x00;
Timer0Init();
Timer1Init();
DS1302_Init();
SetTime();
// ET0=0;
// AT24C02_Write(1,12);
// Delay1ms(10);
// KN=AT24C02_Read(1);
// ET0=1;
//
// disp[0]=ledguan[KN/10%10];
// disp[1]=ledguan[KN%10];
while(1)
{
Wave_Rec();
KN=Key();
if(KN)
{
switch(KN)
{
case 7:
Mode=!Mode;
break;
case 6:
if(!Mode)
{
if(DS_an_count==0)
{
hour=DS1302_Time[0];
min=DS1302_Time[1];
sec=DS1302_Time[2];
}
xiugai_t=1;
DS_an_count++;
DS_an_count%=3;
if(DS_an_count==0)
{
xiugai_t=0;
DS1302_Time[0]=hour;
DS1302_Time[1]=min;
DS1302_Time[2]=sec;
SetTime();
}
}
else
{
if(Wave_an_count)
{
AT24C02_Write(1,(u8)length_din);
Delay1ms(10);
}
Wave_an_count=!Wave_an_count;
}
break;
case 5:
if(!Mode&&DS_an_count)
{
if(DS_an_count==1)
{
hour++;
hour%=24;
}
else if(DS_an_count==2)
{
min++;
min%=60;
}
}
else if(Mode&&Wave_an_count)
{
length_din++;
}
break;
case 4:
if(!Mode&&DS_an_count)
{
if(DS_an_count==1)
{
if(hour==0)hour=23;
else hour--;
}
else if(DS_an_count==2)
{
if(min==0)min=59;
else min--;
}
}
else if(Mode&&Wave_an_count)
{
length_din--;
}
default:
break;
}
}
if(!Mode)
{
ET0=0;
ReadTime();
ET0=1;
if(!xiugai_t)
{
disp[0]=ledguan[DS1302_Time[0]/10%10];
disp[1]=ledguan[DS1302_Time[0]%10];
disp[2]=0xbf;
disp[3]=ledguan[DS1302_Time[1]/10%10];
disp[4]=ledguan[DS1302_Time[1]%10];
disp[5]=0xbf;
disp[6]=ledguan[DS1302_Time[2]/10%10];
disp[7]=ledguan[DS1302_Time[2]%10];
}
else
{
if(DS_an_count==1&&DS1302_Time[2]%2)
{
disp[0]=0xff;
disp[1]=0xff;
}
else
{
disp[0]=ledguan[hour/10%10];
disp[1]=ledguan[hour%10];
}
disp[2]=0xbf;
if(DS_an_count==2&&DS1302_Time[2]%2)
{
disp[3]=0xff;
disp[4]=0xff;
}
else
{
disp[3]=ledguan[min/10%10];
disp[4]=ledguan[min%10];
}
disp[5]=0xbf;
disp[6]=ledguan[sec/10%10];
disp[7]=ledguan[sec%10];
}
}
else
{
if(!Wave_an_count)
{
disp[0]=ledguan[length/100%10];
disp[1]=ledguan[length/10%10]&0x7f;
disp[2]=ledguan[length%10];
disp[3]=0xff;
disp[4]=0xff;
disp[5]=0xff;
disp[6]=0xff;
disp[7]=0xff;
}
else
{
disp[0]=0xff;
disp[1]=0xff;
disp[2]=0xff;
disp[3]=0xbf;
disp[4]=0xbf;
disp[5]=ledguan[length_din/100%10];
disp[6]=ledguan[length_din/10%10]&0x7f;
disp[7]=ledguan[length_din%10];
}
}
if(length<length_din)
{
fmq=1;
}
else
{
fmq=0;
}
if(fmq)fmqq=1;
if(fmq_count<1000&&fmqq)
{
P2=0xa0;P0=0x40;P2=0X00;
}
else if(fmq_count>=1000)
{
if(!fmq)
{
fmq_count=0;
fmqq=0;
P2=0xa0;P0=0x00;P2=0X00;
}
}
if(length<(u16)(1.2*length_din))led=1;
else {led=0;led_count=0;}
if(led_count<500)
{
P2=0x80;P0=0xff;P2=0x00;
}
else if(led_count<1000)
{
P2=0x80;P0=0xfe;P2=0x00;
}
else
{
led_count=0;
}
}
}
u8 Key()
{
u8 Temp;
Temp=KeyN;
KeyN=0;
return Temp;
}
u8 GetState()
{
u8 State=0;
if(P30==0)State=7;
if(P31==0)State=6;
if(P32==0)State=5;
if(P33==0)State=4;
return State;
}
void Key_Loop()
{
static u8 Now,Last;
Last=Now;
Now=GetState();
if(!Now&&Last)
{
KeyN=Last;
}
}
void Start()
{
u8 k;
A1=0;
for(k=0;k<10;k++)
{
A1^=1;
delay(1);
}
}
void delay(u8 i)
{
u8 k;
while(i--)
for(k=0;k<12;k++);
}
void Pros()
{
if(TF1)
{
TF1=0;
length=999;
}
else
{
time=(TH1<<8)|TL1;
length=(u16)time*0.17;
length/=12;
}
TH1=0;
TL1=0;
}
void Wave_Rec()
{
if(wave_count>350)
{
wave_count=0;
Start();
TR1=1;
while(B1&&!TF1);
TR1=0;
Pros();
}
}
void Timer0_R() interrupt 1
{
static u8 smg_count,key_count;
smg_count++;key_count++;wave_count++;
if(smg_count==2)
{
smg_count=0;
P2=0xc0;P0=1<<wei_xuan;P2=0x00;
P2=0xe0;P0=0xff;P2=0x00;
P2=0xe0;P0=disp[wei_xuan++];P2=0x00;
wei_xuan%=8;
}
if(key_count>=20)
{
key_count=0;
Key_Loop();
}
if(led)
{
led_count++;
}
if(fmqq)
{
fmq_count++;
}
}
总结
与自己以前的代码相比
定时器初始化函数更新
AUXR = 0xc0; //定时器时钟1T模式
TMOD = 0x00; //设置定时器模式
由于我同时用了定时器1和定时器0,所以这样写会好一点
做题目中的一些思考
本届题目比第三届题目还简单,但是我手里的这个pdf版本的题目看起来不像是正版题目,不管那么多了,做就完事了。
我把警报设置为达到条件之后蜂鸣器响一秒钟,实现的方式是定时器计时。
if(length<length_din)//如果满足条件
{
fmq=1; //蜂鸣器响一秒钟
}
else
{
fmq=0;//否则不响
}
if(fmq)fmqq=1;//响一秒钟,即使在一秒钟内不符合条件也会响
if(fmq_count<1000&&fmqq)//如果<1s且该响
{
P2=0xa0;P0=0x40;P2=0X00;//响
}
else if(fmq_count>=1000)//>1s
{
if(!fmq)//再次判断是否需要响
{
fmq_count=0;//不要响,计时归零
fmqq=0;
P2=0xa0;P0=0x00;P2=0X00;//不响
}
}
与此同时,在定时器中断中。
if(fmqq)
{
fmq_count++;
}