也就是w6那一位,程序如下:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define key_state_0 0 //初始
#define key_state_1 1 //按下
#define key_state_2 2 //释放
uchar code table[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,
0x79,0x71
};
sbit DS=P2^2;
sbit duan=P2^6;
sbit wei=P2^7;
#define WRITE_SECOND 0x80
#define WRITE_MINUTE 0x82
#define WRITE_HOUR 0x84
#define READ_SECOND 0x81
#define READ_MINUTE 0x83
#define READ_HOUR 0x85
#define WRITE_PROTECT 0x8E
sbit ACC_7=ACC^7;//位寻址寄存器定义
sbit SCLK=P3^2; // DS1302时钟信号 6脚
sbit DIO=P2^4; // DS1302数据信号 7脚
sbit CE=P3^3; // DS1302片选 5脚
sbit key_1=P3^4;
sbit key_2=P3^5;
sbit key_3=P3^6;
sbit key_4=P3^7;
sbit fm=P2^3;
uchar miao,fen,shi,fun,s2a,lshi,lfen,kai,flag,flag1;
uint temp;
void smgxs(uchar, uchar, uchar);
void delay(uchar z);
void Write1302 ( uchar addr,dat );
uchar Read1302 (uchar addr );
void Initial( );
void xsxz( );
void naozhong( );
void read_key( );
void delay1(uint count) //延时函数
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void dsreset(void) //复位初始化函数
{
uint i;
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //读一位数据函数
{
uint i;
bit dat;
DS=0;i++; //i++ 起延时作用
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //读一个字节函数
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
void tmpwritebyte(uchar dat) //写一个字节函数
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //写1
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //写0
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //获取温度并转换
{
dsreset();
delay1(1);
tmpwritebyte(0xcc); //写跳过读rom指令
tmpwritebyte(0x44); //写温度转换指令
}
uint tmp() //读取寄存器中存储的温度数据
{
float tt;
uchar a,b;
dsreset();
delay1(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread(); //读低8位
b=tmpread(); //读高8位
temp=b;
temp<<=8; //字节合并
temp=temp|a;
tt=temp*0.0625; //温度在寄存器中挝?2位,分辨率为0.0625
temp=tt; //乘10表示小数点后面只取一位
return temp;
}
void main( )
{
TMOD=0x01;//定时器工作方式2(8位自动重装)
TH0=0xD8;//装初值
TL0=0xF0;//装初值
EA=1;//开总中断
ET0=1;//开定时器0中断
TR0=1;//启动定时器0
fun=0;
s2a=0;
flag=0;
flag=1;
Initial();//时钟初始化
while(1)
{
//miao=Read1302(READ_SECOND);//读取秒
fen=Read1302(READ_MINUTE);//读取分
shi=Read1302(READ_HOUR);//读取时
xsxz( );
if(flag==1)
naozhong( );
tmpchange(); //获取温度并转换
}
}
void smgxs(uchar shi, uchar fen, uchar miao)//
{
uchar w1,w2,w3,w4,w5,w6;
w1=shi/10;
w2=shi%10;
w3=fen/10;
w4=fen%10;
w5=miao/10;
w6=miao%10;
duan=1;//打开段选
P0=table[w1];//段数据
duan=0;//关闭段选
P0=0xff;//消隐
wei=1;//打开位选
P0=0xfe;//位数据
wei=0;//关闭位选
delay(5);//延时
duan=1;
P0=table[w2];
duan=0;
P0=0xff;
wei=1;
P0=0xfd;
wei=0;
delay(5);
duan=1;
P0=table[w3];
duan=0;
P0=0xff;
wei=1;
P0=0xfb;
wei=0;
delay(5);
duan=1;
P0=table[w4];
duan=0;
P0=0xff;
wei=1;
P0=0xf7;
wei=0;
delay(5);
duan=1;
P0=table[w5];
duan=0;
P0=0xff;
wei=1;
P0=0xef;
wei=0;
delay(5);
duan=1;
P0=table[w6];
duan=0;
P0=0xff;
wei=1;
P0=0xdf;
wei=0;
delay(5);
}
void delay(uchar z)//延时子程序ms
{
uchar x,y;
for (x=z;x>0;x--)
for(y=110;y>0;y--);
}
void Write1302 ( uchar addr,dat ) //地址、数据发送子程序
{
uchar i,temp;
CE=0; //CE引脚为低,数据传送中止
SCLK=0; //清零时钟总线
CE=1; //CE引脚为高,逻辑控制有效//发送地址
for ( i=8; i>0; i-- ) //循环8次移位
{
SCLK=0;
temp=addr;
DIO=(bit)(temp&0x01);//每次传输低字节
addr>>= 1;//右移一位
SCLK=1;//发送数据
}
for ( i=8; i>0; i-- )
{
SCLK=0;
temp=dat;
DIO=(bit)(temp&0x01);
dat>>=1;
SCLK=1;
}
CE=0;
}
uchar Read1302 (uchar addr )//数据读取子程序
{
uchar i,temp,dat1,dat2;
CE=1;
for ( i=8; i>0; i-- ) //发送地址 //循环8次移位
{
SCLK=0;
temp=addr;
DIO=(bit)(temp&0x01);//每次传输低字节
addr>>=1;//右移一位
SCLK=1; //读取数据
}
for ( i=8;i>0;i--)
{
ACC_7=DIO;
SCLK=1;//注意时序
ACC>>=1;
SCLK=0;
}
CE=0;
dat1=ACC;
dat2=dat1/16; //数据进制转换
dat1=dat1%16; //十六进制转十进制
dat1=dat1+dat2*10;
return (dat1);
}
void Initial( )//初始化DS1302
{
Write1302(WRITE_PROTECT,0X00); //禁止写保护
Write1302(WRITE_SECOND,0x30); //秒位初始化
Write1302(WRITE_MINUTE,0x59); //分钟初始化
Write1302(WRITE_HOUR,0x23); //小时初始化
Write1302(WRITE_PROTECT,0x80); //允许写保护
}
void xsxz()//显示选择
{
if (fun==0)
smgxs(shi,fen,tmp());
if (fun==1)
smgxs(shi,fen,00);
if (fun==2)
smgxs(lshi,lfen,flag);
}
void naozhong ( )
{
if((shi==lshi)&&(fen==lfen)&&(flag1==1))
fm=0;
}
void read_key( )
{
uchar aa,bb,cc,dd;
static char key_state=0;
switch (key_state)
{
case key_state_0: // 按键初始态
if (!key_1||!key_2||!key_3||!key_4)
key_state=key_state_1;// 键被按下,状态转换到键确认态
break;
case key_state_1: // 按键确认态
if(!key_1||!key_2||!key_3||!key_4)
{
if(!key_1)//功能键.0:时钟运行1:时钟调整2:闹钟调整
{
fun++;
if(fun==3)
fun=0;
}
if(!key_2)//时分切换键.0:分钟调整1:小时调整2:闹钟开关设置
{
s2a++;
if(s2a==3)
s2a=0;
}
if(!key_3)//向上调整键
{
if((fun==1)&&(s2a==0))//时钟分加
{
fen++;
if(fen==60)
fen=0;
}
if((fun==1)&&(s2a==1))//时钟时加
{
shi++;
if(shi==24)
shi=0;
}
if((fun==2)&&(s2a==0))//闹钟分加
{
lfen++;
if(lfen==60)
lfen=0;
}
if((fun==2)&&(s2a==1))//闹钟时加
{
lshi++;
if(lshi==24)
lshi=0;
}
if((fun==2)&&(s2a==2))//闹钟开关
{
flag=!flag;
flag1=1;
}
}
if(!key_4)//向下调整键
{
if((fun==1)&&(s2a==0))//时钟分减
{
if(fen==0)
fen=60;
fen--;
}
if((fun==1)&&(s2a==1))//时钟时减
{
if(shi==0)
shi=24;
shi--;
}
if((fun==2)&&(s2a==0))//闹钟分减
{
if(lfen==0)
lfen=60;
lfen--;
}
if((fun==2)&&(s2a==1))//闹钟时减
{
if(lshi==0)
lshi=24;
lshi--;
}
if(fun==0)
{
flag1=0;
fm=1;
}
}
Write1302(WRITE_PROTECT,0X00);//关写保护
aa=fen/10;//进制转换
bb=fen%10;
aa<<=4;
fen=aa+bb;
Write1302(WRITE_MINUTE,fen);//写入分数据
cc=shi/10;
dd=shi%10;
cc<<=4;
shi=cc+dd;
Write1302(WRITE_HOUR,shi);//写入时数据
Write1302(WRITE_PROTECT,0x80);//开写保护
key_state=key_state_2;// 状态转换到键释放态 ;
}
else
key_state=key_state_0;// 按键已抬起,转换到按键初始态
break;
case key_state_2:
if(key_1&&key_2&&key_3&&key_4)
key_state=key_state_0;//按键已释放,转换到按键初始态
break;
}
}
void timer0() interrupt 1//定时器0中断程序
{
TH0=0xD8;//装初值
TL0=0xF0;//装初值
read_key();
}
显示放中断了,这个给力啊。
一般是要求中断了的代码越少越好啊!
一周热门 更多>