該程序應該是基于PIC單片機的,采用的是887芯片,暫時沒有找到pic板塊,就這樣了、
附件KS為proteus仿真圖
DS1302為C程序
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (16.89 KB, 下載次數: 84)
下載附件
2018-3-20 18:11 上傳
單片機源程序如下:
- /*
- * File: DS1302.c
- * Author: WillForest
- *
- * Created on 2017年4月11日, 下午9:18
- */
- #include <xc.h>
- // #pragma config statements should precede project file includes.
- // Use project enums instead of #define for ON and OFF.
- // CONFIG1
- #pragma config FOSC = XT // Oscillator Selection bits (XT oscillator: Crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
- #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
- #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
- #pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
- #pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
- #pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
- #pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled)
- #pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled)
- #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
- #pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
- // CONFIG2
- #pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
- #pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
- #define DATA 1 //LCD寫數據時為1
- #define COM 0 //LCD寫命令時為0
- #define LINE1 0b10000000
- #define LINE2 0b11000000
- #define LCD_E RD2
- #define LCD_RW RD1
- #define LCD_RS RD0
- #define DQ RA0
- #define DQ_IO TRISA0
- #define RST RE0
- #define CLK RE1
- #define DAT RE2
- #define DELAY_5US() \
- void WriteDs1302(unsigned char addr, unsigned char code);
- unsigned char ReadDs1302(unsigned addr);
- void TimeCahr(void);
- void Ds1302Init(void);
- unsigned char ReadByte(void);
- void WriteByte(unsigned char data);
- char TopChar[16];
- void LCD_CSH(void);//初始化
- void LCD_BUSY(void);//檢測LCD是否忙
- void LCD_WRITE(char,char);//LCD寫1字節,命令或數據
- void LCD_WRITE_4(char,char);//LCD寫半字節
- char LCD_READ(void);//讀LCD,忙檢測用
- void DELAY(unsigned int);
- void DELAY_US(char);
- int READ_DS18B20(void);
- void WRITE_BYTE(char A);
- char READ_BYTE(void);
- void ONE_WIRE_RESET(void);
- void DQ_ONE_BIT(char A);
- void READ_SLOT(void);
- void DISP_T(int R1);
- void BCD(int R1);
- void CSH(void);
- void CSH_DS1307(void);
- void DS1307_WRITE(char addr,char data);
- void WEEK(char we);
- int READ_DS18B20(void);
- void BCD(int R1);
- void LCD_RUN(int R1);
- void NZ_RUN1(int R1);
- void NZ_RUN2(int R1);
- void NZ_RUN3(int R1);
- void NZ_RUN4(int R1);
- void JS(int R1);
- void N_B(void);
- void Y_B(void);
- void R_B(void);
- void S_B(void);
- void F_B(void);
- void M_B(void);
- unsigned char C[16];
- unsigned char D[16];
- int N=0,Y=0,R=0,S=0,F=0,M=0,XQ;
- int NN1=0,YY1=0,RR1=0,SS1=0,FF1=0,MM1=0;//修改當前日期差值
- int N2=0,Y2=1,R2=1,S2=0,F2=0,M2=0;//設置目標日期差值
- int MB,MQ,YS;//時間轉化
- char RL;//左右移
- int RUN=0;//修改位置
- char NZ=0;//鬧鐘時鐘的判斷
- char EX;
- char i;
- int T;
- int WW,QW,BW,SW,GW;
- void main(void)
- { CSH();
- DELAY(30);
- LCD_CSH();
- Ds1302Init();//時鐘設置?
- while(1)
- { TimeCahr();//時間轉換
- N=TopChar[0]*10+TopChar[1];
- Y=TopChar[2]*10+TopChar[3];
- R=TopChar[4]*10+TopChar[5];
- XQ=1;
- S=TopChar[6]*10+TopChar[7];
- F=TopChar[8]*10+TopChar[9];
- M=TopChar[10]*10+TopChar[11];
- T=READ_DS18B20();
- if(RB2==0) {DELAY(200);if(RB2==1) RUN--;}
- if(RB3==0) {DELAY(200);if(RB3==1) RUN++;}
- if(RB4==0) {DELAY(200);if(RB4==1) if(NZ==1) NZ=0; else NZ=1;}
- if(NZ==0)
- {{if(RUN==-1) RUN=6;RUN=RUN%7;
- if(RB0==0) {DELAY(200);if(RB0==1) NZ_RUN1(RUN);}
- if(RB1==0) {DELAY(200);if(RB1==1) NZ_RUN2(RUN);}}
- N=N+NN1;
- if((N%4)==0) EX=1;else EX=0;
- Y=Y+YY1;
- R=R+RR1;
- if(N%4==0)
- {if(Y==1) MQ=0;
- if(Y==2) MQ=31;
- if(Y==3) MQ=60;
- if(Y==4) MQ=91;
- if(Y==5) MQ=121;
- if(Y==6) MQ=152;
- if(Y==7) MQ=182;
- if(Y==8) MQ=213;
- if(Y==9) MQ=244;
- if(Y==10) MQ=274;
- if(Y==11) MQ=305;
- if(Y==12) MQ=335;
- }
- if(N%4!=0)
- {if(Y==1) MQ=0;
- if(Y==2) MQ=31;
- if(Y==3) MQ=59;
- if(Y==4) MQ=90;
- if(Y==5) MQ=120;
- if(Y==6) MQ=151;
- if(Y==7) MQ=181;
- if(Y==8) MQ=212;
- if(Y==9) MQ=243;
- if(Y==10) MQ=273;
- if(Y==11) MQ=304;
- if(Y==12) MQ=334;
- }
- MQ=(MQ+R+(N/4)+1+N*365);
- if(N2%4==0)
- {if(Y2==1) MB=0;
- if(Y2==2) MB=31;
- if(Y2==3) MB=60;
- if(Y2==4) MB=91;
- if(Y2==5) MB=121;
- if(Y2==6) MB=152;
- if(Y2==7) MB=182;
- if(Y2==8) MB=213;
- if(Y2==9) MB=244;
- if(Y2==10) MB=274;
- if(Y2==11) MB=305;
- if(Y2==12) MB=335;
- }
- if(N2%4!=0)
- {if(Y2==1) MB=0;
- if(Y2==2) MB=31;
- if(Y2==3) MB=59;
- if(Y2==4) MB=90;
- if(Y2==5) MB=120;
- if(Y2==6) MB=151;
- if(Y2==7) MB=181;
- if(Y2==8) MB=212;
- if(Y2==9) MB=243;
- if(Y2==10) MB=273;
- if(Y2==11) MB=304;
- if(Y2==12) MB=334;
- }
- MB=(MB+R2+(N2/4)+1+N2*365);
- MB=(MB-MQ);
- BCD(N);
- D[0]=2;D[1]=0;D[2]=SW;D[3]=GW;D[4]=-3;
- BCD(Y);
- D[5]=SW;D[6]=GW;D[7]=-3;
- BCD(R);
- D[8]=SW;D[9]=GW;
- XQ=6;
- XQ=XQ+MQ;
- XQ=XQ%7;
- if(XQ==0) XQ=7;
- WEEK(XQ);
- if(MB<0) {D[13]=21;D[14]=34;D[15]=34;}
- if(MB>=0) {BCD(MB); D[13]=BW;D[14]=SW;D[15]=GW;}}
- if(NZ==1)
- {{if(RUN==-1) RUN=3;RUN=RUN%4;
- if(RB0==0) {DELAY(200);if(RB0==1) NZ_RUN3(RUN);}
- if(RB1==0) {DELAY(200);if(RB1==1) NZ_RUN4(RUN);}
- BCD(N2);
- D[2]=SW;D[3]=GW;
- BCD(Y2);
- D[5]=SW;D[6]=GW;D[7]=-3;
- BCD(R2);
- D[8]=SW;D[9]=GW;D[10]=85;D[11]=85;D[12]=85;D[13]=85;D[14]=85;D[15]=85;
- }}
- LCD_WRITE(LINE1,COM);
- for(i=0;i<16;i++) LCD_WRITE(D[i]+'0',DATA);
- S=S+SS1;
- F=F+FF1;
- if(F==60) F=0;
- M=M+MM1;
- if(M==60) M=0;
- BCD(S);
- C[0]=SW;C[1]=GW;C[2]=10;
- BCD(F);
- C[3]=SW;C[4]=GW;C[5]=10;
- BCD(M);
- C[6]=SW;C[7]=GW;C[8]=85;
- DISP_T(T);
- C[12]=175;C[13]=19;C[14]=85;
- LCD_RUN(RUN);
- LCD_WRITE(LINE2,COM);
- for(i=0;i<16;i++) LCD_WRITE(C[i]+'0',DATA);
-
- }
- }
- //子程序DISP_T用來LCD第一行顯示所測的溫度值“T= ℃”
- void DISP_T(int R1)
- {
- int R2;
- if(R1>=0)
- {BCD(R1);
- C[9]=85;C[10]=SW;C[11]=GW;
- }
- else
- { R2=~R1+1;
- BCD(R2);
- C[9]=-3;C[10]=SW;C[11]=GW;
- }
- }
- //讀取DS18B20的溫度值
- int READ_DS18B20(void)
- {
- int R1;
- ONE_WIRE_RESET(); //1-WIRE復位
- WRITE_BYTE(0xCC); //直接訪問RAM
- WRITE_BYTE(0x44); //溫度轉換
- DELAY(100); //9位分辨率轉換時間為93.75ms
- ONE_WIRE_RESET(); //1-WIRE復位
- WRITE_BYTE(0xCC); //直接訪問RAM
- WRITE_BYTE(0xBE); //讀取RAM中的數據,只讀溫度值
- R1=READ_BYTE(); //讀取低字節
- R1=R1+(READ_BYTE()<<8);//讀取高字節
- R1=R1>>4;//右移四位,取溫度值的整數
- return(R1);//返回R1
- }
- //1-wire器件復位
- void ONE_WIRE_RESET(void)
- {
- DQ_IO=1; //先置DQ高電平
- NOP(); //
- DQ_IO=0; //
- DQ=0; //強制拉DQ至低電平
- DELAY_US(49);
- DQ_IO=1; //釋放DQ線
- while(DQ==1);//等待DS18B20應答
- DELAY_US(49);
- }
- //DS18B20寫字節
- void WRITE_BYTE(char R1)//寫一字節
- {
- char i,j;
- for(i=0;i<8;i++) //寫八位數據
- {
- if((R1&0x01)==0x01)
- j=1;
- else
- j=0;
- R1=R1>>1;
- DQ_ONE_BIT(j);
- }
- }
- //DS18B20讀字節
- char READ_BYTE(void)//讀一字節
- {
- char i,R1;
- R1=0;
- for(i=0;i<8;i++)
- {
- R1=R1>>1;
- READ_SLOT();
- if(DQ==1)
- R1+=0x80;
- DELAY_US(4);
- }
- return(R1);
- }
- //DS18B20寫1個字節
- void DQ_ONE_BIT(char R1)
- {
- if(R1==1)
- {
- DQ_IO=0;
- DQ=0;
- DELAY_5US();
- DQ_IO=1;
- DELAY_US(6);
- }
- else
- {
- DQ_IO=0;
- DQ=0;
- DELAY_US(7);
- DQ_IO=1;
- }
- }
- //時隙函數
- void READ_SLOT(void)
- {
- DQ_IO=0;
- DQ=0;
- NOP();
- NOP();
- DQ_IO=1;
- NOP();
- NOP();
- }
- void BCD(int R1)
- { WW=0;QW=0;BW=0;SW=0;GW=0;
- while(R1>=10000)
- {R1-=10000;WW++;}
- while(R1>=1000)
- {R1-=1000;QW++;}
- while(R1>=100)
- {R1-=100;BW++;}
- while(R1>=10)
- {R1-=10;SW++;}
- GW=R1;
- }
- void LCD_CSH(void)
- {
- DELAY(20);
- LCD_WRITE_4(0b0011,COM);
- DELAY(5);
- LCD_WRITE_4(0b0011,COM);
- DELAY_US(10);
- LCD_WRITE_4(0b0011,COM);
- DELAY_US(10);
- LCD_WRITE_4(0b0010,COM);
- LCD_BUSY();
- LCD_WRITE(0b00101000,COM);
- LCD_WRITE(0b00001100,COM);
- LCD_WRITE(0b00000001,COM);
- DELAY(2);
- LCD_WRITE(0b00000110,COM);
- }
- void LCD_WRITE_4(char R1,char FLAG)
- {
- LCD_RW=0;NOP();
- LCD_RS=FLAG;NOP();
- PORTD &= 0x0F;NOP();
- LCD_E=1;NOP();
- R1=R1<<4;
- PORTD |=R1;NOP();
- LCD_E=0;NOP();
- LCD_RS=0;NOP();
- PORTD &= 0x0F;
- }
- void LCD_WRITE(char R1,char FLAG)
- {
- char R2;
- LCD_BUSY();
- R2=R1&0xF0;
- R2=R2>>4;
- LCD_WRITE_4(R2,FLAG);
- R2=R1&0x0F;
- LCD_WRITE_4(R2,FLAG);
- DELAY_US(10);
- }
- char LCD_READ(void)
- {
- unsigned char R1;
- LCD_RS=0;
- LCD_RW=1;NOP();
- LCD_E=1;NOP();
- R1=0;
- R1=(PORTD<<4)&0x0F;
- LCD_E=0;NOP();
- LCD_E=1;NOP();
- R1 |= (PORTD & 0x0F);
- LCD_E=0;NOP();
- LCD_RW=0;
- return (R1);
- }
- void LCD_BUSY(void)
- {
- unsigned char R1;
- while(1)
- {
- R1=LCD_READ();
- if((R1&0x80)==0x00)
- break;
- };
- }
- void DELAY(unsigned int n)
- {
- unsigned int j;
- char k;
- for (j=0;j<n;j++)
- for (k=246;k>0;k--)
- NOP();
- }
- void DELAY_US(char n)
- {
- char j;
- for (j=0;j<n;j++)
- {
- NOP();NOP();
- }
- }
- void N_B(void)
- {if((N+NN1)>99) NN1=99;
- if((N+NN1)<01) NN1=1;
- }
- void Y_B(void)
- {if((Y+YY1)>12) YY1=YY1-12;
- if((Y+YY1)<1) YY1=YY1+12;
- if((Y+YY1)==2) {if(EX==0) {if((R+RR1)>28) RR1=28-R;}
- if(EX==1) {if((R+RR1)>29) RR1=29-R;}}
- }
- void R_B(void)
- {
- if(Y==1) {if((R+RR1)>31) RR1=31-R;if((R+RR1)<=0) RR1=31+R;}
- if(Y==2) {if(EX==0) {if((R+RR1)>28) RR1=28-R;if((R+RR1)<=0) RR1=28+R;}
- if(EX==1) {if((R+RR1)>29) RR1=29-R;if((R+RR1)<=0) RR1=29+R;}}
- if(Y==3) {if((R+RR1)>31) RR1=31-R;if((R+RR1)<=0) RR1=31+R;}
- if(Y==4) {if((R+RR1)>30) RR1=30-R;if((R+RR1)<=0) RR1=30+R;}
- if(Y==5) {if((R+RR1)>31) RR1=31-R;if((R+RR1)<=0) RR1=31+R;}
- if(Y==6) {if((R+RR1)>30) RR1=30-R;if((R+RR1)<=0) RR1=30+R;}
- if(Y==7) {if((R+RR1)>31) RR1=31-R;if((R+RR1)<=0) RR1=31+R;}
- if(Y==8) {if((R+RR1)>31) RR1=31-R;if((R+RR1)<=0) RR1=31+R;}
- if(Y==9) {if((R+RR1)>30) RR1=30-R;if((R+RR1)<=0) RR1=30+R;}
- if(Y==10) {if((R+RR1)>31) RR1=31-R;if((R+RR1)<=0) RR1=31+R;}
- if(Y==11) {if((R+RR1)>30) RR1=30-R;if((R+RR1)<=0) RR1=30+R;}
- if(Y==12) {if((R+RR1)>31) RR1=31-R;if((R+RR1)<=0) RR1=31+R;}
- }
- void S_B(void)
- {if((S+SS1)>24) SS1=SS1-24;
- if((S+SS1)<0) SS1=SS1+24;
- }
- void F_B(void)
- {
- if((F+FF1)>60) FF1=FF1-60;
- if((F+FF1)<0) FF1=FF1+60;
- }
- void M_B(void)
- {if((M+MM1)>60) MM1=MM1-60;
- if((M+MM1)<0) MM1=MM1+60;
- }
- void NZ_RUN1(int R1)
- {switch(R1)
- {
- case 1: NN1=NN1+1;N_B();break;
- case 2: YY1=YY1+1;Y_B(); break;
- case 3: RR1=RR1+1;R_B();break;
- case 4: SS1=SS1+1;S_B();break;
- case 5: FF1=FF1+1;F_B();break;
- case 6: MM1=MM1+1;M_B();break;
- case 0: break;
- }
- }
- void NZ_RUN2(int R1)
- {switch(R1)
- {
- case 1: NN1=NN1-1;N_B();break;
- case 2: YY1=YY1-1;Y_B(); break;
- case 3: RR1=RR1-1;R_B();break;
- case 4: SS1=SS1-1;S_B();break;
- case 5: FF1=FF1-1;F_B();break;
- case 6: MM1=MM1-1;M_B();break;
- case 0: break;
- }
- }
- void NZ_RUN3(int R1)
- {
- switch(R1)
- {
- case 1: N2++;if(N2>100) N2=N2-100;break;
- case 2: Y2++;if(Y2>12) Y2=Y2-12;if(Y2==2) {if((N2%4)!=0) {if(R2>28) R2=28;}if((N2%4)==0) {if(R2>29) R2=29;}} break;
- case 3: R2++;
- {if(Y2==1) {if(R2>31) R2=R2-31;}
- if(Y2==2) {if((N2%4)!=0) {if(R2>28) R2=R2-28;}
- if((N2%4)==0) {if(R2>29) R2=R2-29;}}
- if(Y2==3) {if(R2>31) R2=R2-31;}
- if(Y2==4) {if(R2>30) R2=R2-30;}
- if(Y2==5) {if(R2>31) R2=R2-31;}
- if(Y2==6) {if(R2>30) R2=R2-30;}
- if(Y2==7) {if(R2>31) R2=R2-31;}
- if(Y2==8) {if(R2>31) R2=R2-31;}
- if(Y2==9) {if(R2>30) R2=R2-30;}
- if(Y2==10) {if(R2>31) R2=R2-31;}
- if(Y2==11) {if(R2>30) R2=R2-30;}
- if(Y2==12) {if(R2>31) R2=R2-31;}}break;
- case 0: break;
- }
- }
- void NZ_RUN4(int R1)
- {switch(R1)
- {
- case 1: N2--;if(N2<0) N2=N2+100;break;
- case 2: Y2--;if(Y2<1) Y2=Y2+12;if(Y2==2) {if((N2%4)!=0) {if(R2>28) R2=28;}if((N2%4)==0) {if(R2>29) R2=29;}} break;
- case 3: R2--;
- {if(Y2==1) {if(R2<1) R2=31+R2;}
- if(Y2==2) {if((N2%4)!=0) {if(R2<1) R2=28+R2;}
- if((N2%4)==0) {if(R2<1) R2=29+R2;}}
- if(Y2==3) {if(R2<1) R2=31+R2;}
- if(Y2==4) {if(R2<1) R2=30+R2;}
- if(Y2==5) {if(R2<1) R2=31+R2;}
- if(Y2==6) {if(R2<1) R2=30+R2;}
- if(Y2==7) {if(R2<1) R2=31+R2;}
- if(Y2==8) {if(R2<1) R2=31+R2;}
- if(Y2==9) {if(R2<1) R2=30+R2;}
- if(Y2==10) {if(R2<1) R2=31+R2;}
- if(Y2==11) {if(R2<1) R2=30+R2;}
- if(Y2==12) {if(R2<1) R2=31+R2;}}break;
- case 0: break;
- }
- }
- void LCD_RUN(int R1)
- {
- switch(R1)
- {
- case 1:C[15]=30;break;
- case 2:C[15]=41;break;
- case 3:C[15]=34;break;
- case 4:C[15]=35;break;
- case 5:C[15]=22;break;
- case 6:C[15]=29;break;
- case 0:C[15]=85;break;
- }
- }
- void WEEK(char we)
- { switch(we)
- {
- case 1: D[10]=35;
- D[11]=37;
- D[12]=30;
- break;
- case 2: D[10]=29;
- D[11]=31;
- D[12]=30;
- break;
- case 3: D[10]=36;
- D[11]=37;
- D[12]=21;
- break;
- case 4: D[10]=39;
- D[11]=21;
- D[12]=20;
- break;
- case 5: D[10]=36;
- D[11]=24;
- D[12]=37;
- break;
- case 6: D[10]=22;
- D[11]=34;
- D[12]=41;
- break;
- case 7: D[10]=35;
- D[11]=17;
- D[12]=36;
- break;
- }
- }
- //======主程序初始化=======
- void CSH(void)
- { ANSEL=0x00;
- ANSELH=0x00;
- TRISA=0x00;
- TRISD=0b00000000;
- TRISE=0x00;
- TRISB=0b11111111; 0100000; //允許B口高四位電平變化中斷
- OPTION_REG=0b00000000;
- INTCON=0b11000000; T1CON=0b00110001;
- WPUB=0xFF;
- }
- unsigned char ReadDs1302(unsigned addr)
- {
- unsigned char code;
- RST = 0;//便能清零
- CLK = 0;//時鐘清零
- RST = 1;
- WriteByte(addr | 0x01);//寫入地址
- code = ReadByte();//讀取數據
- CLK = 1;//時鐘置位
- RST = 0;//便能失效
- return code;//返回數據
- }
- void WriteDs1302(unsigned char addr, unsigned char code)
- {RST = 0;//便能清零
- CLK = 0; //時鐘清零
- RST = 1;
- WriteByte(addr & 0xfe); //寫入地址
- WriteByte(code); //寫入數據
- CLK = 1; //時鐘置位
- RST = 0; //便能失效
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載(程序與proteus仿真圖):
KS.zip
(20.72 KB, 下載次數: 50)
2018-3-20 11:31 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
DS1302.zip
(4.87 KB, 下載次數: 45)
2018-3-20 11:31 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|