1、題目要求數組
2、程序源碼緩存
1 #include "stc15.h" 2 #include "ds1302.h" 3 #include "onewire.h" 4 5 #define uchar unsigned char 6 #define uint unsigned int 7 #define KEYCOM P3 8 #define KEY_S4 0x08 9 #define KEY_S5 0x04 10 #define KEY_S6 0x02 11 #define KEY_S7 0x01 12 13 14 uchar code smg_dis[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40,0x39}; 15 uchar code Time_Init [3] ={23,59,50};//時鐘初始化 時 分 秒 16 17 uchar code Time_Max [3] = {23,59,59};//時間閾值 18 uchar Time_rd_Buf[3];//時間讀取緩存 19 uchar Clock_buf[3]={0,0,0};//鬧鐘時間 20 uchar Time_set_Buf[3];//時間設置緩存 21 uchar Smg_Buf[8];//數碼管顯示緩存 22 23 uchar Trg;//按鍵當前值 24 uchar Cont;//按鍵前次值 25 26 bit KeyFlag = 0; 27 bit ClockFlag = 0;//鬧鐘 28 bit TimeFlag = 0;//時間獲取 29 30 bit ClockSet = 0;//設置鬧鐘 31 bit TimeSet = 0;//設置時間 32 33 bit BlinkFlag=0; 34 bit TempShow =0;//溫度顯示 35 36 37 void KeyRead (void); 38 void Timer0Init(void); 39 void SMG_Show (uchar *arr); 40 void SMG_Show1 (uchar *arr); 41 uchar Resize (uchar sum , uchar max);//按鍵調整時間 42 void Ds1302_Init (unsigned char *arr); 43 void Ds1302_Get (unsigned char *arr); 44 unsigned char Read_Temp (void); 45 46 int main (void) 47 { 48 uchar Temp_Val=0;//溫度值 49 char T_Len=-1;// 設置的位數切換 50 P0=0x00;P2=0xa0;P2=0x00; 51 P0=0xff;P2=0x80;P2=0x00; 52 Ds1302_Init(Time_Init);//設置初始化時間 53 Temp_Val=Read_Temp();//讀取一次消除 第一次的85 54 Timer0Init(); 55 while(1) 56 { 57 if(KeyFlag) 58 { 59 KeyFlag=0; 60 KeyRead(); 61 if((Trg & KEY_S7) && !ClockSet && !ClockFlag)//非鬧鐘設置或鬧鐘 62 { 63 if(!TimeSet)//只有第一次按下時才寫入 64 { 65 Time_set_Buf[0]=Time_rd_Buf[0]/16*10+Time_rd_Buf[0]%16;//16進制轉換10進制 寫入函數的入參是十進制 66 Time_set_Buf[1]=Time_rd_Buf[1]/16*10+Time_rd_Buf[1]%16;//將讀取的時間寫到設置的緩存中,調整的也是緩存中的值 67 Time_set_Buf[2]=Time_rd_Buf[2]/16*10+Time_rd_Buf[2]%16;//整個設置過程當中再也不讀取時間 68 } 69 TimeSet=1; 70 ++T_Len; 71 if( T_Len > 2) //初值爲 -1 按下當即自加一次 =0 取值 0 1 2 對應 Time_set_Buf 和 Time_Max 和 Clock_buf 數組的下標 72 { 73 T_Len=-1; 74 TimeSet=0;//退出設置模式 75 Ds1302_Init(Time_set_Buf);//時分秒所有設置後 寫入時間 76 } 77 } 78 if(Trg & KEY_S6 && !TimeSet && !ClockFlag)//鬧鐘設置 79 { 80 ClockSet=1; 81 ++T_Len; 82 if( T_Len > 2) //與時間設置同理 83 { 84 T_Len=-1; 85 ClockSet=0; 86 } 87 } 88 89 if(Trg & KEY_S4 && !TimeSet && !ClockSet && !ClockFlag || Cont & KEY_S4 )//按下顯示溫度 90 { 91 TempShow=1; 92 Temp_Val=Read_Temp(); 93 Smg_Buf[0]=10; 94 Smg_Buf[1]=10; 95 Smg_Buf[2]=10; 96 Smg_Buf[3]=10; 97 Smg_Buf[4]=10; 98 Smg_Buf[5]=Temp_Val/10; 99 Smg_Buf[6]=Temp_Val%10; 100 Smg_Buf[7]=12; 101 } 102 else 103 TempShow=0; 104 105 if(TimeSet)//時間設置 106 { 107 SMG_Show1(Time_set_Buf); 108 if(BlinkFlag && T_Len>=0)//閃爍 每隔1s標誌位會變化一次 標誌位爲1的時候,將不顯示該位 109 { 110 Smg_Buf[T_Len*3+1]=10; 111 Smg_Buf[T_Len*3 ]=10; 112 } 113 Time_set_Buf[T_Len]=Resize(Time_set_Buf[T_Len],Time_Max[T_Len]);//調整 114 } 115 116 if(ClockSet)//鬧鐘設置 與時間設置同理 117 { 118 SMG_Show1(Clock_buf); 119 if(BlinkFlag && T_Len>=0) 120 { 121 Smg_Buf[T_Len*3+1]=10; 122 Smg_Buf[T_Len*3 ]=10; 123 } 124 Clock_buf[T_Len]=Resize(Clock_buf[T_Len],Time_Max[T_Len]); 125 } 126 127 if(ClockFlag && (Trg & KEY_S4 || Trg & KEY_S5 || Trg & KEY_S6 || Trg & KEY_S7))//關鬧鐘 128 { 129 ClockFlag=0; 130 P0=~0x00;P2=0x80;P2=0x00; 131 } 132 133 } 134 if(TimeFlag && !TimeSet && !ClockSet )//100ms 獲取時間並在非設置狀態下顯示 135 { 136 TimeFlag=0; 137 Ds1302_Get(Time_rd_Buf); 138 if(!TempShow) 139 SMG_Show(Time_rd_Buf);//顯示溫度的時候不更新顯示緩存 140 if(Time_rd_Buf[0]==Clock_buf[0] && Time_rd_Buf[1]==Clock_buf[1] && Time_rd_Buf[2]==Clock_buf[2] )//鬧鐘 141 { 142 ClockFlag=1; 143 } 144 } 145 } 146 } 147 148 149 void Timer0Init(void) //1ms@11.0592MHz 150 { 151 AUXR |= 0x80; 152 TMOD &= 0xF0; 153 TL0 = 0xCD; 154 TH0 = 0xD4; 155 TF0 = 0; 156 TR0 = 1; 157 ET0 = 1; 158 EA = 1; 159 } 160 161 void TIME0 (void) interrupt 1 162 { 163 static uchar SmgCount = 0; 164 static uchar KeyCount = 0; 165 static uchar TimeCount = 0; 166 static uint BlinkCount = 0; 167 static uchar SmgLen = 0; 168 static uchar ClockCount = 0; 169 static uchar ClockNum=0; 170 if( ++KeyCount > 10) 171 { 172 KeyCount = 0; 173 KeyFlag = 1; 174 } 175 176 if(TimeSet || ClockSet)//設置的時候閃爍 177 { 178 if( ++BlinkCount >1000) 179 { 180 BlinkCount=0; 181 BlinkFlag=~BlinkFlag;//不可手動置零 182 } 183 } 184 else//不在設置下所有清零 185 { 186 BlinkCount=0; 187 BlinkFlag=0; 188 } 189 190 if( ++SmgCount > 1)//數碼管動態 191 { 192 SmgCount = 0; 193 P0=~smg_dis[Smg_Buf[SmgLen]];P2=0xe0;P2=0X00; 194 P0=1<<SmgLen;P2=0xc0;P2=0X00; 195 if(++SmgLen > 7) SmgLen=0; 196 } 197 198 if( ++TimeCount > 100)//時間獲取間隔 199 { 200 TimeCount=0; 201 TimeFlag=1; 202 } 203 204 if(ClockFlag)//鬧鐘 205 { 206 ClockCount++; 207 if(ClockCount >=200)//0.2s 208 { 209 ClockCount=0; 210 ClockNum++; 211 if(ClockNum>=25) //次數 212 { 213 ClockNum=0; 214 ClockFlag=0; 215 ClockCount=0; 216 } 217 if( ClockNum%2 )//亮或滅 218 { 219 P0=~0x01;P2=0x80;P2=0x00; 220 } 221 else 222 { 223 P0=~0x00;P2=0x80;P2=0x00; 224 } 225 } 226 } 227 else//不在鬧鐘狀態下所有清零 228 { 229 ClockNum=0; 230 ClockCount=0; 231 } 232 } 233 234 void KeyRead (void) 235 { 236 unsigned char ReadData = KEYCOM^0xff; 237 Trg = ReadData & (ReadData ^ Cont); 238 Cont = ReadData; 239 } 240 241 void SMG_Show (uchar *arr) 242 { 243 Smg_Buf[0]=arr[0]/16; 244 Smg_Buf[1]=arr[0]%16; 245 Smg_Buf[2]=11; 246 Smg_Buf[3]=arr[1]/16; 247 Smg_Buf[4]=arr[1]%16; 248 Smg_Buf[5]=11; 249 Smg_Buf[6]=arr[2]/16; 250 Smg_Buf[7]=arr[2]%16; 251 } 252 253 void SMG_Show1 (uchar *arr)//10進制 設置的時候顯示 254 { 255 Smg_Buf[0]=arr[0]/10; 256 Smg_Buf[1]=arr[0]%10; 257 Smg_Buf[2]=11; 258 Smg_Buf[3]=arr[1]/10; 259 Smg_Buf[4]=arr[1]%10; 260 Smg_Buf[5]=11; 261 Smg_Buf[6]=arr[2]/10; 262 Smg_Buf[7]=arr[2]%10; 263 } 264 265 266 uchar Resize (uchar sum , uchar max)//按鍵調整 267 { 268 char temp; 269 temp = sum; 270 if(Trg & KEY_S5)// + 271 { 272 if( ++temp > max ) temp=max; 273 } 274 if(Trg & KEY_S4)// - 275 { 276 if( --temp < 0) temp=0; 277 } 278 return temp; 279 } 280 281 void Ds1302_Init (unsigned char *arr) 282 { 283 Write_Ds1302(0x8e,0); 284 Write_Ds1302(0x80,(arr[2]/10)*16+arr[2]%10);//小時 285 Write_Ds1302(0x82,(arr[1]/10)*16+arr[1]%10);//分 286 Write_Ds1302(0x84,(arr[0]/10)*16+arr[0]%10);//秒 287 Write_Ds1302(0x8e,0x80); 288 } 289 290 void Ds1302_Get (unsigned char *arr)//時間獲取 291 { 292 arr[2]=Read_Ds1302(0x81); 293 arr[1]=Read_Ds1302(0x83); 294 arr[0]=Read_Ds1302(0x85); 295 } 296 297 unsigned char Read_Temp (void)//溫度 298 { 299 unsigned char Low,High,Temp; 300 init_ds18b20(); 301 Delay_OneWire(1); 302 Write_DS18B20(0xcc); 303 Write_DS18B20(0x44); 304 init_ds18b20(); 305 Delay_OneWire(1); 306 Write_DS18B20(0xcc); 307 Write_DS18B20(0xbe); 308 Low=Read_DS18B20(); 309 High=Read_DS18B20(); 310 Low=Low>>4; 311 High=High<<4; 312 Temp=High|Low; 313 return Temp; 314 }