藍橋杯單片機練習_第八屆電子時鐘

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 }
相關文章
相關標籤/搜索