英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流
标题:
闹钟
[打印本页]
作者:
winnie
时间:
2009-3-8 16:45
标题:
闹钟
#include<pic.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
#define T_IOIO TRISA1
#define KS1 RA3
#define KS2 RA4
#define KS3 RA5
#define T_CLK RA0
#define T_IO RA1
#define T_RST RA2
#define Fm RC0
union {
struct {
unsigned b0:1;
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
}oneBit;
unsigned char allBits;
} myFlag;
union {
struct {
unsigned b0:1;
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
}tpBit;
unsigned char tpBits;
} tp;
#define acc0 tp.tpBit.b0
#define acc7 tp.tpBit.b7
#define acc tp.tpBits
#define FMbit myFlag.oneBit.b2
const unsigned char table[11]={ 0x0C0, 0x0F9, 0x0A4,0x0B0, 0x99, 0x92,0x82, 0x0F8,0x80,0x90,0xff};
const unsigned char Ds1302[] = {2, 9, 5,9};//被调整数据上下对比值
// // 时 分
//////////ROM区///////////////
uchar BCD[4];//数据送LED的数据 暂存区
//uchar Reeprom[6];
uchar appear[8];//2送LED的数据 暂存区
uchar get1302[4];//从1302读出 秒 分 时 日 月 星期 年 暂存区
uchar DisCash[3];//合字->1302
unsigned char temp,temp1;
//延时子程序
void delay(unsigned int i )
{
while(i--);
}
void display(unsigned char x)//显示程序
{
unsigned char b,c ,i;
i=x;
b=0x10;
for(c=0;c<4;c++)
{
PORTB=table[ appear
] ;
if(( myFlag.oneBit.b0==1)&& (c==1)) RB7=0;//点闪
if(( myFlag.oneBit.b1==1)&& (c==2)) RB7=0;//点闪
PORTC=(PORTC&0x0f)|b;
CLRWDT();
delay(300);//延时子程序
b=b<<1;
i=i++;
}
}
/////往1302写入1Byte数据////////////////////////////////////////////////
void RTInputByte(uchar d) ////
{ ////
uchar i; ////
acc = d; // tp.tpBits// ////
T_IOIO=0; ////
for(i=8; i>0; i--) ////
{ ////
T_IO = acc0;//CARRY;//ACC0; //*相当于汇编中的 RRC */ ////
T_CLK = 1; ////
T_CLK = 0; ////
acc = acc >> 1; ////
} ////
} ////
///////从1302读取1Byte数据//////////////////////// ////
uchar RTOutputByte(void) ////
{ ////
uchar i; ////
T_IOIO=1; ////
for(i=8; i>0; i--) ////
{ ////
acc = acc >>1; //*相当于汇编中的 RRC */ ////
acc7= T_IO;// CARRY ////
T_CLK = 1; ////
T_CLK = 0; ////
} ////
return(acc); ////
} ////
///////先写地址,后写命令/数据////////////////////////// ////
void W1302(uchar ucAddr, uchar ucDa) ////
{ ////
T_RST = 0; ////
T_CLK = 0; ////
T_RST = 1; ////
RTInputByte(ucAddr); // /* 地址,命令 */ ////
RTInputByte(ucDa); // /* 写1Byte数据*/ ////
T_CLK = 1; ////
T_RST = 0; ////
} ////
///////先写地址,后读命令/数据//////////////////////// ////
uchar R1302(uchar ucAddr) ////
{ ////
uchar ucData; ////
T_RST = 0; ////
T_CLK = 0; ////
T_RST = 1; ////
RTInputByte(ucAddr); // /* 地址,命令 */ ////
ucData = RTOutputByte(); // /* 读1Byte数据 */ ////
T_CLK = 1; ////
T_RST = 0; ////
return(ucData); ////
} ////
/////////向1302写入 秒 分 时 日 月 星期 年 *///////////// ////
void Set1302(uchar *pClock ,uchar a ) ////
{ ////
uchar i; ////
uchar ucAddr = a;//0x80;// 秒. 分 /0x0C0 RAM ////
W1302(0x8e,0x00); ///* 控制命令,WP=0,允许写操作*/ ////
for(i =3; i>0; i--) ////
{ ////
W1302(ucAddr,*pClock); ///* 秒 分 时 日 月 星期 年 */ ////
pClock++; ////
ucAddr +=2; ////
} ////
W1302(0x8e,0x80); // /* 控制命令,WP=1,写保护*/ ////
} ////
////////从1302读出 秒 分 时 日 月 星期 年 *////////////////// ////
void v_Get1302(unsigned char ucCurtime[],uchar a) ////
{ ////
unsigned char i; ////
unsigned char ucAddr = a;//0x83 分 0x0C1 RAM ////
for (i=0;i<2;i++) ////
{ ////
ucCurtime = R1302(ucAddr);///*格式为: 秒 分 时 日 月 星期 年 */
ucAddr += 2; ////
} ////
} ////
//////////拆字子程序////////////////////////////////////////////////////
void bcd_bcd( uchar x )
{ uchar i,b, a=1;
i=x;
for (b=0;b<2;b++)
{
appear=(get1302[a]&0xf0)>>4;
i++;
appear=get1302[a]&0x0f;
i++;
a--;
}
} ////
////////蜂名器//////////////////////////////////////////////////////////
void F_m()
{
uchar a =8;
while(a--)
{
Fm=!Fm;
delay(10);//延时子程序
// Fm=1;
}
}
//////////按键扫描//////////////////////////////////////////////////////
void Key()
{
uchar a,b,i, d,c,e;
if(( KS3==0)||(KS2==0))
{ a=20;
F_m();
while(a--) display(0);//延时再判断
if(56!=(PORTA&56))
{
if (KS3==0){b=0;i=4;c=0;e=0; myFlag.oneBit.b0=1;}//点长亮//是 时钟设置
else {b=0;i=8;c=4;e=4; myFlag.oneBit.b1=1;myFlag.oneBit.b0=0;}// 是 闹钟设置
while( KS3==0||KS2==0) display(e);//等待抬起
di();
d=0;
//b=0;i=4;
while (c<i&&d<20)//选择被调整数
{
uchar z,x;
for(z=50;z>0&&c<i;z--)//亮50次
{ z--;
display(e);
a=PORTA&56 ;
switch(a)
{ // display(e);
case 48 : if( appear[c]!= Ds1302
) //110 ks1=0
appear[c]++;
F_m();
if(appear[e]==2&&appear[e+1]>3)appear[e+1]=0;
for(x=20;x>0&&56!=(PORTA&56);x--)
display(e);d=0; break;
case 40 : if(appear[c]!=0) //101 ks2=0
appear[c]--;
F_m();
for(x=20;x>0&&56!=(PORTA&56);x--)
display(e); d=0; break;
case 24 : c++;b++; F_m(); while( KS3==0) display(e);d=0; break; //011 ks3=0
}
}
if (c<i)
{
for(z=50; z>0&&56==(PORTA&56);z--)//被调整数闪烁程序
{ uchar i;
i=appear[c];
appear[c]=10;
display(e);
appear[c]=i;
} d++;
}
}
while( KS3==0)display(0);
if(e==0) { i=3; c=2;}
else { i=7; c=6;}
for(b=1;b<3;b++)
{
DisCash
=((appear[c]&0x0f)*16)|(appear&0x0f);//合字
i=i-2;
c=c-2;
}
if(e==0) Set1302(&DisCash[0],0x80);//写1302 DisCash[0]=0;DisCash[1]=dtat;DisCash[2]=dtat
else Set1302(&DisCash[0],0x0C0);//写1302 RAM
myFlag.oneBit.b1=0;
}
}
}
//系统 各I/O初始化子程序
void initial ()
{ TRISB=0;
TRISC=2;
ADCON1=7;;//设置RA为IO口
TRISA=0x38;
PORTC=1;
}
void main()
{
initial (); //系统 各I/O初始化子程序
temp=50;
temp1=10;
v_Get1302(get1302,0x0C3);//从1302读出RAM
bcd_bcd(4);//拆字子程序
while(1)
{
v_Get1302(get1302,0x83);//从1302读出 秒 分 时 日 月 星期 年
bcd_bcd(0);//拆字子程序
display(0);//显示程序
Key();
temp=temp--;//点闪记时
if( temp==0){ temp=50; myFlag.oneBit.b0=!myFlag.oneBit.b0; FMbit=!FMbit; }
if(appear[0]==appear[4]&&appear[1]==appear[5]&&appear[2]==appear[6]&&appear[3]==appear[7]&&FMbit)
{
if(temp1==0)
{
Fm=!Fm; temp1=10;
}temp1--;
}
else Fm=1;
}
}
欢迎光临 英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 (http://enroobbs.com/)
Powered by Discuz! X3.2