DS12C887时钟芯片 程序理解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<reg52.h> 2 #include"define.h" //difine的头文件在后面 3 void delay(uint z) 4 { 5 uint x,y; 6 for(x=z;x>0;x--) 7 for(y=110;y>0;y--); 8 } 9 10 void didi() //进入这个函数后,就是让蜂鸣器以 滴 滴滴 滴 滴滴的方式不停地响 11 { 12 beep=0; 13 delay(50); 14 beep=1; 15 delay(100); 16 beep=0; 17 delay(50); 18 beep=1; 19 } 20 void write_com(uchar com) 21 { 22 rs=0; 23 lcden=0; 24 P0=com; 25 delay(5); 26 lcden=1; 27 delay(5); 28 lcden=0; 29 } 30 31 void write_date(uchar date) 32 { 33 rs=1; 34 lcden=0; 35 P0=date; 36 delay(5); 37 lcden=1; 38 delay(5); 39 lcden=0; 40 } 41 42 void init() 43 { 44 uchar num; 45 EA=1; 46 EX0=1; 47 IT0=1; 48 49 dula=0; 50 wela=0; 51 lcden=0; 52 // set_time(); 53 set_alarm(14,13,10); 54 write_ds(0x0B,0x26); 55 read_ds(0x0c); 56 // fen=59; 57 // miao=53; 58 // shi=23; 59 write_com(0x38); 60 write_com(0x0c); 61 write_com(0x06); 62 write_com(0x01); 63 write_com(0x80); 64 for(num=0;num<15;num++) 65 { 66 write_date(table[num]); 67 delay(5); 68 } 69 write_com(0x80+0x40); 70 for(num=0;num<12;num++) 71 { 72 write_date(table1[num]); 73 delay(5); 74 } 75 76 } 77 78 void write_sfm(uchar add,uchar date) 79 { 80 uchar shi,ge; 81 shi=date/10; 82 ge=date%10; 83 write_com(0x80+0x40+add); 84 write_date(0x30+shi); 85 write_date(0x30+ge); 86 } 87 88 void keyscan() 89 { 90 rd=0; 91 if(flag1==1)// 当标志位为1时,按s2,或者按s3都可以令标志位 flag1 清零 92 { 93 if(s2==0) 94 { 95 delay(5); 96 if(s2==0) 97 { 98 while(!s2); 99 flag1=0; 100 } 101 102 } 103 if(s3==0) 104 { 105 delay(5); 106 if(s3==0) 107 { 108 while(!s3); 109 flag1=0; 110 } 111 112 } 113 } 114 115 if(s1==0) 116 { 117 delay(5); 118 if(s1==0) 119 { s1num++; 120 flag=1; 121 flag1=0; 122 while(!s1); 123 if(s1num==1) 124 { 125 TR0=0; 126 write_com(0x80+0x40+10); 127 write_com(0x0f); 128 } 129 } 130 if(s1num==2) 131 { 132 write_com(0x80+0x40+7); 133 } 134 if(s1num==3) 135 { 136 write_com(0x80+0x40+4); 137 } 138 if(s1num==4) 139 { 140 s1num=0; 141 write_com(0x0c); 142 flag=0; 143 write_ds(0,miao); 144 write_ds(2,fen); 145 write_ds(4,shi); 146 } 147 148 149 } 150 if(s1num!=0) 151 { 152 if(s2==0) 153 { 154 delay(1); 155 if(s2==0) 156 { 157 while(!s2); 158 if(s1num==1) 159 { 160 miao++; 161 if(miao==60) 162 miao=0; 163 write_sfm(10,miao); 164 write_com(0x80+0x40+10); 165 166 167 } 168 if(s1num==2) 169 { 170 fen++; 171 if(fen==60) 172 fen=0; 173 write_sfm(7,fen); 174 write_com(0x80+0x40+7); 175 } 176 if(s1num==3) 177 { 178 shi++; 179 if(shi==24) 180 shi=0; 181 write_sfm(4,shi); 182 write_com(0x80+0x40+4); 183 } 184 } 185 } 186 if(s3==0) 187 { 188 delay(1); 189 if(s3==0) 190 { 191 while(!s3); 192 if(s1num==1) 193 { 194 /* if(miao==0) 195 { 196 miao=59; 197 write_sfm(10,miao); 198 write_com(0x80+0x40+10); 199 }*/ 200 miao--; 201 if(miao==-1) 202 miao=59; 203 write_sfm(10,miao); 204 write_com(0x80+0x40+10); 205 } 206 if(s1num==2) 207 { 208 fen--; 209 if(fen==-1) 210 fen=59; 211 write_sfm(7,fen); 212 write_com(0x80+0x40+7); 213 } 214 if(s1num==3) 215 { 216 shi--; 217 if(shi==-1) 218 shi=23; 219 write_sfm(4,shi); 220 write_com(0x80+0x40+4); 221 } 222 } 223 } 224 } 225 } 226 /*给时钟芯片中写程序的时候,要传入两个参数,一个地址、一个数据, 227 因为先要确定那一个寄存器才可以将其数据正确的存入其中*/ 228 void write_ds(uchar add,uchar date) 229 { 230 dscs=0; //片选为0才可以工作 231 dsas=1; // 232 dsds=1; 233 dsrw=1; 234 P0=add; // 将数据送到P0口 235 dsas=0;//as为下降沿时锁存,将add送到它的内部 236 dsrw=0; //将rw拉低之后或者拉低之前,再送数据都可以 237 P0=date;//将数据送到P0口 238 dsrw=1;//在rw的上升沿将数据写入到寄存器中 239 dsas=1; 240 dscs=1; 241 } 242 /*而在读时钟数据时,只需要传入它的地址, 243 就可以直接读取,因为要都会数据,故而有返回值*/ 244 uchar read_ds(uchar add) 245 { 246 uchar ds_date; //因为要有变量最后接受数据 247 dsas=1; 248 dsds=1; 249 dsrw=1; 250 dscs=0; 251 P0=add; 252 dsas=0; 253 dsds=0; 254 P0=0xff;//再给给数据之前,先全为高 255 ds_date=P0; 256 dsds=1; 257 dsas=1; 258 dscs=1; 259 return ds_date; 260 } 261 262 void set_time() 263 { 264 write_ds(4,10); 265 write_ds(2,32); 266 267 } 268 269 void set_alarm(uchar ashi,uchar afen,uchar amiao) 270 { 271 write_ds(1,amiao); 272 write_ds(3,afen); 273 write_ds(5,ashi); 274 } 275 void main() 276 { 277 init(); 278 while(1) 279 { 280 keyscan(); //先进行扫描,如果flag1没有置1时,蜂鸣器就不会响,只有P3^2有了跳变沿变化而进入到外部0中令flag置1才会进入到蜂鸣器想的函数中 281 if(flag1==1) 282 didi(); 283 if(flag==0) 284 { 285 miao=read_ds(0); 286 fen=read_ds(2); 287 shi=read_ds(4); 288 write_sfm(10,miao); 289 write_sfm(7,fen); 290 write_sfm(4,shi); 291 } 292 } 293 } 294 295 void exter() interrupt 0 296 { uchar c; 297 flag1=1; //进入外部中断0后,令flag1标志位置1 298 c=read_ds(0x0c); //将寄存器C读取一下,不需要干其他的事情,只是为了将闹钟中断位清零 299 } 300 301 302 303 #define uchar unsigned char 304 #define uint unsigned int 305 sbit dula=P2^6; 306 sbit wela=P2^7; 307 sbit rs=P3^5; 308 sbit lcden=P3^4; 309 sbit s1=P3^0; 310 sbit s2=P3^1; 311 sbit s3=P3^2; 312 sbit rd=P3^7; 313 sbit beep=P2^3; 314 sbit dscs=P1^4; 315 sbit dsas=P1^5; 316 sbit dsrw=P1^6; 317 sbit dsds=P1^7; 318 sbit dsirq=P3^3; 319 uchar count,s1num,flag,flag1; 320 char miao,shi,fen; 321 uchar code table[]=" 2007-7-30 MON"; 322 uchar code table1[]=" : : "; 323 void write_ds(uchar,uchar); 324 void set_alarm(uchar,uchar,uchar); 325 uchar read_ds(uchar);void set_time();