新手上传一个自用程序
/***************************************************************************
标题: 定时器中断 24小时时钟程序
效果: 数码管显示24小时制时钟
工作于:LY5A-L2A开发板
作者: 林洋电子吧
说明: 板使用12M晶振
******************************************************************************/
- //头文件:
- #include<reg51.h>
- #include<intrins.h>
- #include<math.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define S_RST DS_RST=1
- #define C_RST DS_RST=0
- #define S_CLK DS_CLK=1
- #define C_CLK DS_CLK=0
- //引脚定义:
- sbit SMG_q = P3^4; //定义数码管阳级控制脚(千位)
- sbit SMG_b = P3^5; //定义数码管阳级控制脚(百位)
- sbit SMG_s = P3^6; //定义数码管阳级控制脚(十位)
- sbit SMG_g = P3^7; //定义数码管阳级控制脚(个位)
- sbit IR=P3^3; //红外接收数据引脚,
- sbit DS_RST = P0^0; //DS复位端
- sbit DS_IO = P0^1; //IO端
- sbit DS_CLK = P0^2; //SCLK端
- sbit SPK = P0^7; //续电器
- sbit LED = P0^6;
- sbit LED1 = P0^5;
- //变量定义:
- code unsigned char table[]=
- {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xBF};
- //表:共阳数码管 0-9
- unsigned char l_posit=0; //显示位置
- unsigned char ly_tt=0; //作为计数时间量
- unsigned char SET=0; //设置标识
- unsigned char dskg=0;
- unsigned char ddss=0;//掉电标识
- unsigned char ss=0; //闪烁标识
- unsigned char ss1=0;
- unsigned char ss2=0;
- unsigned char ss3=0;
- unsigned char ts1=0;
- //////////////////////
- signed char time;
- unsigned char shi;
- unsigned char fen;
- unsigned char miao;
- unsigned char yue;
- unsigned char ri;
- unsigned char nian;
- unsigned char zhou;
- unsigned char qi;
- unsigned char ba;
- unsigned char sh;
- unsigned char ge;
- //函数声明:
- void display(unsigned char q,unsigned char b,unsigned char s,unsigned char g);//定义显示函数,参数为显示时分
- void delay(uint a);
- void init(); //初如化函数
- void gettime();
- uchar BCD_s(uchar BCDs);
- uchar s_BCD(uchar sBCD);
- void RW_DS1302(uchar reg, uchar byte);
- uchar Read_DS1302(uchar reg);//从DS1302寄存器读数据
- void DS1302_InputByte(uchar byte); //往DS1302写入1Byte数据
- uchar DS1302_OutputByte(void); //从DS1302读取1Byte数据
- void ts();
- /**************************红外接收处理***********************************
- **************************************************************************
- *************************************************************************/
- unsigned char irtime;//红外用全局变量
- bit irpro_ok=0,irok=0;
- unsigned char IRcord[4];
- unsigned char irdata[33];
- unsigned char xs=0;
- unsigned char xstt=2;
- unsigned char xs_tt=0;
- signed char ds_time;
- unsigned char k_fen;
- unsigned char k_shi;
- unsigned char g_fen;
- unsigned char g_shi;
- signed char date;
- /*------------------------------------------------
- 函数声明
- ------------------------------------------------*/
- void Ir_work(void);
- void Ircordpro(void);
- void EX0init(void);
- void TIM0init(void);//定时器0初始化
- /**************************红外接收处理***********************************
- **************************************************************************
- *************************************************************************/
- //初始化函数
- void init()
- {
- P1=0XFF;
- SMG_q=0;
- SMG_b=0;
- SMG_s=0;
- SMG_g=0;
- SPK=1;
- delay(500);
- // TMOD=0X02; //设置定时器1为模式一,即16位计算模式
- // TH0=0X00;
- // TL0=0X00;
- // EA=1; //开启总中断
- // ET0=1; //开启定时器0中断
- // TR0=1; //启动定时器
- // EX1=1; //开启外部中断1,红外接收数据引脚
- // IT1=1; //设置成下降沿触发方式
- RW_DS1302(0x8e,0x80);delay(10);
- delay(500);
- }
- //显示函数,参数为显示内容
- void display(unsigned char q,unsigned char b,unsigned char s,unsigned char g)
- {
- P1=0XFF; //
- switch(l_posit){
- case 0: //选择千位数码管,关闭其它位
- SMG_q=1;
- SMG_b=0;
- SMG_s=0;
- SMG_g=0;
- P1=table[q/10]; //输出显示内容
- break;
- case 1: //选择百位数码管,关闭其它位
- SMG_q=0;
- SMG_b=1;
- SMG_s=0;
- SMG_g=0;
- P1=table[b%10];
- break;
- case 2: //选择十位数码管,关闭其它位
- SMG_q=0;
- SMG_b=0;
- SMG_s=1;
- SMG_g=0;
- P1=table[s/10];
- break;
- case 3: //选择个位数码管,关闭其它位
- SMG_q=0;
- SMG_b=0;
- SMG_s=0;
- SMG_g=1;
- P1=table[g%10];
- break;
- }
- l_posit++; //每调用一次将轮流显示一位
- if(l_posit>3)
- l_posit=0;
- }
- //延时子函数,短暂延时
- void delay(uint a)
- {
- uint k;
- while(a--)
- {
- for(k=0;k<120;k++){;}
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- /********************************************************
- * *
- * DS1302时钟芯片程序段 *
- * *
- ********************************************************/
- void DS1302_InputByte(uchar byte) //往DS1302写入1Byte数据
- {
- uchar i;
- uchar temp;
- temp = byte;
- for(i=8; i>0; i--)
- {
- DS_IO = temp&0x01;
- S_CLK;
- C_CLK;
- temp = temp >> 1;
- }
- }
- uchar DS1302_OutputByte(void) //从DS1302读取1Byte数据
- {
- uchar i;
- uchar temp=0;
- for(i=0; i<8;i++)
- {
- C_CLK;
- if(DS_IO!=0) temp|=(1<<i);
- S_CLK;
- }
- return(temp);
- }
- void RW_DS1302(uchar reg, uchar byte)//向DS1302寄存器写数据
- {
- C_RST;
- C_CLK;
- S_RST;
- DS1302_InputByte(reg);
- DS1302_InputByte(byte);
- S_CLK;
- C_RST;
- }
- uchar Read_DS1302(uchar reg)//从DS1302寄存器读数据
- {
- uchar byte;
- C_RST;
- C_CLK;
- S_RST;
- DS1302_InputByte(reg);
- byte = DS1302_OutputByte();
- S_CLK;
- C_RST;
- return(byte);
- }
- //////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////转码
- uchar BCD_s(uchar BCDs)//十六进制转化为10进制
- {
- BCDs=(BCDs>>4)*10+(BCDs&0x0f);//将读出来的十六进制转化为10进制
- delay(1);
- return(BCDs);
- }
- uchar s_BCD(uchar sBCD)//10进制转化为十六进制
- {
- sBCD=((sBCD/10)<<4)+(sBCD%10);//将10进制转化为十六进制
- delay(1);
- return(sBCD);
- }
- /////////////////////////////////////////////////
- void gettime()
- {
- time=Read_DS1302(0x85);//读小时
- shi=BCD_s(time);
- time=Read_DS1302(0x83);//读分
- fen=BCD_s(time);
- time=Read_DS1302(0x81);//读秒
- time&=0x7f;//这句代码的意思是:因为秒的最高位第七位分为两种可能,一:它是0,如果是0的话,时钟会自动的计时,如果是1的话,时钟会停止走动,相当于中断
- miao=BCD_s(time);//将分读出来的十六进制转化为10进制
- time=Read_DS1302(0x89);//读月
- yue=BCD_s(time);
- time=Read_DS1302(0x87);//读日
- ri=BCD_s(time);
- time=Read_DS1302(0x8D);//读年
- nian=BCD_s(time);
- time=Read_DS1302(0x8b);//读zhou
- zhou=BCD_s(time);
- ds_time=Read_DS1302(0xc1);
- k_fen=BCD_s(ds_time);
- ds_time=Read_DS1302(0xc9);
- k_shi=BCD_s(ds_time);
- ds_time=Read_DS1302(0xc5);
- g_fen=BCD_s(ds_time);
- ds_time=Read_DS1302(0xc7);
- g_shi=BCD_s(ds_time);
- }
- /**************************红外接收处理***********************************
- **************************************************************************
- *************************************************************************/
- /*------------------------------------------------
- 定时器0中断处理
- ------------------------------------------------*/
- void tim0_isr (void) interrupt 1 using 1
- {
- irtime++; //用于计数2个下降沿之间的时间
- xs_tt++;
- if(xs_tt==xstt){xs_tt=0;} //亮度变量
- if(xs_tt==1)
- { if(ss==1)
- { if(ss2>=10)
- { SMG_q=0;
- SMG_b=0;
- SMG_s=0;
- SMG_g=0;
- P0=0xFF;
- }
- else
- display(qi,ba,sh,ge);
- }
- else
- display(qi,ba,sh,ge);
- }
- else
- P1=0xFF;
- ss1++;
- if(ss1==250)
- { ss1=0;
- ss2++;
- if(ss2==16)
- { ss2=0;
- }
- }
- }
- /*void tim1_isr (void) interrupt 3
- {
- xs_tt++;
- if(xs_tt==xstt){xs_tt=0;}
- if(xs_tt==1)
- {display();}
- else
- P0=0xFF;
- }*/
- /*------------------------------------------------
- 外部中断0中断处理
- ------------------------------------------------*/
- void EX0_ISR (void) interrupt 2 //外部中断0服务函数
- {
- static unsigned char i; //接收红外信号处理
- static bit startflag; //是否开始处理标志位
- if(startflag)
- {
- if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
- i=0;
- irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
- irtime=0;
- i++;
- if(i==33)
- {
- irok=1;
- i=0;
- }
- }
- else
- {
- irtime=0;
- startflag=1;
- }
- }
- /*------------------------------------------------
- 定时器0初始化
- ------------------------------------------------*/
- void TIM0init(void)//定时器0初始化
- {
- TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
- TH0=0x00; //重载值
- TL0=0x00; //初始化值
- ET0=1; //开中断
- TR0=1;
- // TH1=0x00; //重载值
- // TL1=0x00; //初始化值
- // TR1=1;
- // ET1=1; //开中断
- }
- /*------------------------------------------------
- 外部中断0初始化
- ------------------------------------------------*/
- void EX0init(void)
- {
- IT1 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
- EX1 = 1; //使能外部中断
- EA = 1; //开总中断
- }
- /*------------------------------------------------
- 键值处理
- ------------------------------------------------*/
- void Ir_work(void)//红外键值散转程序
- {
- // uchar date;
- if(SET==0){
- switch(IRcord[2])//判断第三个数码值
- {
- case 0x16:if(IRcord[3]==0xe9){
- ddss=1;}
- break;//1 显示相应的按键值
- case 0x0c:if(IRcord[3]==0xf3){
- xs=0;}
- break;//1 显示相应的按键值
- case 0x18:if(IRcord[3]==0xe7){
- xs=1;}
- break;//1 显示相应的按键值
- case 0x5e:if(IRcord[3]==0xa1){
- xs=2;}
- break;//1 显示相应的按键值
- case 0x0d:if(IRcord[3]==0xf2){
- xstt=2;}
- break;//1 显示相应的按键值
- case 0x19:if(IRcord[3]==0xe6){
- xstt=15;}
- break;//1 显示相应的按键值
- // case 0x0d:if(IRcord[3]==0xf2){
- // xstt=30;}
- // break;//1 显示相应的按键值
- case 0x09:if(IRcord[3]==0xf6){
- SPK=~SPK;}
- break;//1 显示相应的按键值
- case 0x15:if(IRcord[3]==0xea){
- dskg=1;}
- break;//1 显示相应的按键值
- case 0x07:if(IRcord[3]==0xf8){
- dskg=0;}
- break;//1 显示相应的按键值
- default:break;
- // IRcord[2]=0;
- }}
- /////////////////////////////////////////////////////////////////////////////////////////////////////
- if(SET==0){
- if(IRcord[2]==0x42){
- if(IRcord[3]==0xbd){
- RW_DS1302(0x8e,0x00);delay(10);//允许写操作
- date=Read_DS1302(0x81);//先将秒读出来
- date=0x80|date;//这句就是将秒置为最高位
- RW_DS1302(0x80,date);delay(10);//再将秒写进去
- RW_DS1302(0x8e,0x80);delay(10);//写完了关闭
- SET=1;ss=1;}
- IRcord[2]=0;
- irpro_ok=0;}
- if(IRcord[2]==0x08){
- if(IRcord[3]==0xf7){
- SET=4;}
- IRcord[2]=0;
- irpro_ok=0;}}
- if(SET==1){
- if(IRcord[2]==0x42){
- if(IRcord[3]==0xbd){
- SET=2;ss=1;
- IRcord[2]=0;
- irpro_ok=0;}}
-
- if(IRcord[2]==0x4a){
- if(IRcord[3]==0xb5){
- RW_DS1302(0x8e,0x00);delay(10);
- time=Read_DS1302(0x83);
- time=BCD_s(time);//这是修改分的主要代码,好好研究就成了
- time++;
- if(time>59)
- {
- time=0;
- }
- time=s_BCD(time);
- RW_DS1302(0x82,time);
- RW_DS1302(0x8e,0x80);
- IRcord[2]=0;
- irpro_ok=0;}}
- if(IRcord[2]==0x52){
- if(IRcord[3]==0xad){
- RW_DS1302(0x8e,0x00);delay(10);
- time=Read_DS1302(0x85);
- time=BCD_s(time);
- time++;
- if(time>23)
- {
- time=0;
- }
- time=s_BCD(time);
- RW_DS1302(0x84,time);
- RW_DS1302(0x8e,0x80);
- IRcord[2]=0;
- irpro_ok=0;}}}
- if(SET==2){
- if(IRcord[2]==0x42){
- if(IRcord[3]==0xbd){
- SET=3;ss=1;
- IRcord[2]=0;
- irpro_ok=0;}}
- if(IRcord[2]==0x4a){
- if(IRcord[3]==0xb5){
- RW_DS1302(0x8e,0x00);delay(10);
- time=Read_DS1302(0x87);
- time=BCD_s(time);//这是修改分的主要代码,好好研究就成了
- time++;
- if(time>31)
- {
- time=1;
- }
- time=s_BCD(time);
- RW_DS1302(0x86,time);
- RW_DS1302(0x8e,0x80);
- IRcord[2]=0;
- irpro_ok=0;}}
- if(IRcord[2]==0x52){
- if(IRcord[3]==0xad){
- RW_DS1302(0x8e,0x00);delay(10);
- time=Read_DS1302(0x89);
- time=BCD_s(time);
- time++;
- if(time>12)
- {
- time=1;
- }
- time=s_BCD(time);
- RW_DS1302(0x88,time);
- RW_DS1302(0x8e,0x80);
- IRcord[2]=0;
- irpro_ok=0;}}
- }
- if(SET==3){
- if(IRcord[2]==0x42){
- if(IRcord[3]==0xbd){
- RW_DS1302(0x8e,0x00);
- date=Read_DS1302(0x81);
- date&=0x7f;//将秒的最高位置零表示重新开始工作
- RW_DS1302(0x80,date);
- RW_DS1302(0x8e,0x80);
- SET=0;
- ss=0;}
- IRcord[2]=0;
- irpro_ok=0;}
- if(IRcord[2]==0x52){
- if(IRcord[3]==0xad){
- RW_DS1302(0x8e,0x00);delay(10);
- time=Read_DS1302(0x8D);
- time=BCD_s(time);
- time++;
- if(time>99)
- {
- time=0;
- }
- time=s_BCD(time);
- RW_DS1302(0x8C,time);
- RW_DS1302(0x8e,0x80);
- IRcord[2]=0;
- irpro_ok=0;}}
- if(IRcord[2]==0x4a){
- if(IRcord[3]==0xb5){
- RW_DS1302(0x8e,0x00);delay(10);
- time=Read_DS1302(0x8B);
- time=BCD_s(time);
- time++;
- if(time>7)
- {
- time=1;
- }
- time=s_BCD(time);
- RW_DS1302(0x8A,time);
- RW_DS1302(0x8e,0x80);
- IRcord[2]=0;
- irpro_ok=0;}}
- }
- /* if(SET==4){
- if(IRcord[2]==0x42){
- if(IRcord[3]==0xbd){
- RW_DS1302(0x8e,0x00);
- date=Read_DS1302(0x81);
- date&=0x7f;//将秒的最高位置零表示重新开始工作
- RW_DS1302(0x80,date);
- RW_DS1302(0x8e,0x80);
- SET=0;
- ss=0;}
- IRcord[2]=0;
- irpro_ok=0;}} */
- if(SET==4){
- if(IRcord[2]==0x08){
- if(IRcord[3]==0xf7){
- SET=5;ss=1;
- IRcord[2]=0;
- irpro_ok=0;}}
-
- if(IRcord[2]==0x5a){
- if(IRcord[3]==0xa5){
- RW_DS1302(0x8e,0x00);delay(10);
- ds_time=Read_DS1302(0xc1);
- ds_time=BCD_s(ds_time);
- ds_time++;
- if(ds_time>59)
- {
- ds_time=0;
- }
- ds_time=s_BCD(ds_time);
- RW_DS1302(0xc0,ds_time);
- RW_DS1302(0x8e,0x80);
- IRcord[2]=0;
- irpro_ok=0;}}
- if(IRcord[2]==0x1c){
- if(IRcord[3]==0xe3){
- RW_DS1302(0x8e,0x00);delay(10);
- ds_time=Read_DS1302(0xc9);
- ds_time=BCD_s(ds_time);
- ds_time++;
- if(ds_time>23)
- {
- ds_time=0;
- }
- ds_time=s_BCD(ds_time);
- RW_DS1302(0xc8,ds_time);
- RW_DS1302(0x8e,0x80);
- IRcord[2]=0;
- irpro_ok=0;}}}
- if(SET==5){
- if(IRcord[2]==0x08){
- if(IRcord[3]==0xf7){
- SET=0;ss=0;}
- IRcord[2]=0;
- irpro_ok=0;}
- if(IRcord[2]==0x5a){
- if(IRcord[3]==0xa5){
- RW_DS1302(0x8e,0x00);delay(10);
- ds_time=Read_DS1302(0xc5);
- ds_time=BCD_s(ds_time);
- ds_time++;
- if(ds_time>59)
- {
- ds_time=0;
- }
- ds_time=s_BCD(ds_time);
- RW_DS1302(0xc4,ds_time);
- RW_DS1302(0x8e,0x80);}
- IRcord[2]=0;
- irpro_ok=0;}
- if(IRcord[2]==0x1c){
- if(IRcord[3]==0xe3){
- RW_DS1302(0x8e,0x00);delay(10);
- ds_time=Read_DS1302(0xc7);
- ds_time=BCD_s(ds_time);
- ds_time++;
- if(ds_time>23)
- {
- ds_time=0;
- }
- ds_time=s_BCD(ds_time);
- RW_DS1302(0xc6,ds_time);
- RW_DS1302(0x8e,0x80); }
- IRcord[2]=0;
- irpro_ok=0;}}
- irpro_ok=0;//处理完成标志
- }
- /*------------------------------------------------
- 红外码值处理
- ------------------------------------------------*/
- void Ircordpro(void)//红外码值处理函数
- {
- unsigned char i, j, k;
- unsigned char cord,value;
- k=1;
- for(i=0;i<4;i++) //处理4个字节
- {
- for(j=1;j<=8;j++) //处理1个字节8位
- {
- cord=irdata[k];
- if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
- value|=0x80;
- if(j<8)
- {
- value>>=1;
- }
- k++;
- }
- IRcord[i]=value;
- value=0;
- }
- irpro_ok=1;//处理完毕标志位置1
- }
- /**************************红外接收处理***********************************
- **************************************************************************
- *************************************************************************/
- //主函数,C语言的入口函数:
- void main()
- {
- init(); //初始化中断控制寄存器
- EX0init(); //初始化外部中断
- TIM0init();//初始化定时器
- while(1)
- {
- if(ss2==2)
- gettime();
- /////////////////////////////////////
- if(irok) //如果接收好了进行红外处理
- {
- Ircordpro();
- irok=0;
- }
- if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
- {
- Ir_work();
- }
- //////////////////////////////////////////
- if(dskg==1)
- { if(shi==k_shi)
- { if(fen==k_fen)
- { SPK=0; }
- }
- if(shi==g_shi)
- { if(fen==g_fen)
- { SPK=1; }
- }
- }
- /* if(SET==0)
- { qi=shi;
- ba=shi;
- sh=fen;
- ge=fen;
- if(ss2>=8)
- { LED=0;}
- else
- LED=1;
- }*/
- if(SET==1)
- { qi=shi;
- ba=shi;
- sh=fen;
- ge=fen;
- LED=0;}
- if(SET==2)
- { qi=yue;
- ba=yue;
- sh=ri;
- ge=ri;
- LED=1;}
- if(SET==3)
- { qi=nian;
- ba=nian;
- sh=0;
- ge=zhou;
- LED=1;}
- /* if(SET==4)
- { qi=shi;
- ba=shi;
- sh=fen;
- ge=fen;
- LED=1;}*/
- if(SET==4)
- { ss=1;
- qi=k_shi;
- ba=k_shi;
- sh=k_fen;
- ge=k_fen;
- if(ss2>=8)
- { LED=0;}
- else
- LED=1;
- }
- if(SET==5)
- { ss=1;
- qi=g_shi;
- ba=g_shi;
- sh=g_fen;
- ge=g_fen;
- if(ss2>=8)
- { LED=0;}
- else
- LED=1;
- }
- if(SET==0){
- if(xs==0)
- { qi=shi;
- ba=shi;
- sh=fen;
- ge=fen;
- LED=1;
- if(ss2>=8)
- { LED=0;}
- else
- LED=1;}
- if(xs==1)
- { qi=yue;
- ba=yue;
- sh=ri;
- ge=ri;
- LED=1;}
- if(xs==2)
- { qi=zhou;
- ba=zhou;
- sh=miao;
- ge=miao;
- LED=1;} }
- if(dskg==1)
- { LED1=0;}
- if(dskg==0)
- { LED1=1;}
- if(ddss==0)
- { if(ss2>=8)
- { LED1=0;}
- else
- LED1=1;
- }
- if(shi==7)
- { xstt=2;}
- if(shi==19)
- { xstt=15;}
- ////////////////////////////////////
- if(zhou==6)
- { ts();}
- ////////////////////////////
- }
- }
- //////////////////////////////////////////
- ////////////////////////////////////////////时间校准
- void ts()
- {
- if(shi==0)
- { if(fen==0)
- { if(miao==30)//0x30是30秒
- { ts1=1;
- }
- }
- }
- //////////////////////////////////////////////////
- if(ts1==1)
- { if(shi==1)
- { if(fen==1)
- { if(miao==15)
- { ts1=0;
- RW_DS1302(0x8e,0x00);delay(10);
- RW_DS1302(0x80,0x31);delay(10);//0x80写秒0x30就是31秒
- RW_DS1302(0x8e,0x80);delay(10);
- }
- }
- }
- }
- }
复制代码
|