久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4766|回復: 1
收起左側

藍橋杯單片機第八屆省賽 程序題解析(完美調試,清晰解析)

[復制鏈接]
ID:586435 發表于 2020-3-22 21:04 | 顯示全部樓層 |閱讀模式
本帖最后由 黑夜的星光 于 2020-3-22 21:14 編輯

             Hellow !大家好,今天找個時間把第八屆的題也發出來 一起探討學習一下。自己呢也算做一個的經歷筆記吧 (哈哈哈哈)
                                                      試想一下 10年后的自己看到這淺陋的代碼,不知道會有什么感慨呢..................(hahaha....隔~)


                                        ps:帖子今天用了 一個粉紅的顏色,哈哈哈,看著比較養眼舒服吧,若努力學習的                                                                                                         同學不嫌棄這些代碼的話,希望這粉紅能一定程度上減緩你們的疲勞



自己在調試的時候呢, 最頭大的地方就是DS1302不能讀取時間(DS1302驅動代碼都沒問題)
   原因有二:
                   其一 :自己在上電初始化的函數中,將P22 = 0了,(我做了測試,將其P22 = 1時,可以正常工作) 詳細請看代碼
                   其二 :開發板是自己焊接的,可能P2引腳有短路的問題存在。
       起初把自己調試的都懷疑人生了   啊哈哈哈。真的很難受。哎..........     最后調試出來的時候又喜悅到了極點

說一下自己對賽題的看法吧,賽題沒有太新穎,生疏的考點,整體難度還是不低的。主要是按鍵的功能標志位的邏輯關系以及對數碼管的多工作界面的切換,數碼管玩的是真的很....ennenen
     中斷不要多做事情,快進快出。一般LED的(指示燈之類的)標志位處理放在中斷處理比其他函數內要好很多。先把簡單的容易實現的功能調試出      來,最后再去寫復雜的邏輯代碼。
     寫完一個邏輯功能就去編譯一下,看一下有沒有語法錯誤,不然等到最后錯誤太多,調試會復雜很多。然后單獨的模塊完成后記著上電驗證一下,使其逐漸能銜接起來。
   好的算法有時會起到意想不到的好處,多看看一些大佬的算法,以及一些好的思維方式。慢慢積累,對自己的好處也會慢慢變的明顯。

以上都是自己的卑鄙拙見,期間也受到了一些大佬的思維啟蒙,非常感謝。
  自己多單片機的感悟就是3點 多寫 多看 多想。  只有在自己親自寫的時候,才能體會到他們的真正含義,而且要多寫,形成自己的邏輯思維;多看別人的優秀的地方,如算法,思維,積累這些,自己學著去消化使用,慢慢變成自己的; 多想想自己編寫不出來的地方,想想功能模塊之間的聯系,怎樣做才能使完善,實現想要的結果。


                                                   
     學而不思則罔,思而不學則殆



好了,咱們上題




8DF@%P3H`JUC35OL5R9H@[R.png



OE(KS[_9P4C0YDI910M@S4N.png





代碼如下

main.c文件

/*****************************************************************************************************************************************
藍橋杯第八屆省賽習題


【細節提示】:在ds1302.c文件中定義了 有符號的數據變量 char Inittime[],以及必須在ds1302.h文件中進行 extern 全局的調用聲明
【主要難點】:數碼管的工作界面的切換,按鍵對工作標志位的使能以及互不干擾
【代碼說明】:不同的代碼編寫都有其高效的地方和一些功能需復雜實現的地方,要合理看待      
                 本題中:   多處使用了  P2 = (P2 & 0xFF) | 0x04; (對DS1302的工作使能)。
                                                                            我調試的很長時間,ds1302一直不能工作。加上這句代碼后(P22 = 1),一切都好了。
      【不知道是不是我開發板的問題,你要是使用的話,可以去掉這句代碼測試一下】
                       
******************************************************************************************************************************************/
#include "ds18b20.h"
#include "ds1302.h"
#include "smg.h"

#define uchar unsigned
#define uint  unsigned
       
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;

uchar flag_S7 = 0;               //S7功能選擇位
uchar flag_S6 = 0;               //S6功能選擇位
uchar flag_S5 = 0;               //S5功能選擇位
uchar flag_S4 = 0;               //S4功能選擇位

bit flag_Clock = 0;              //鬧鐘響起標志位
bit flag_led = 0;                //L1閃爍標志位,用于鬧鐘重置恢復閃爍狀態 【0-led閃爍開始標志;1-led閃爍停止標志】
bit flag_1s = 0;                 //時鐘設置狀態下1s閃爍標志位 【0是亮,1是滅】

uchar temp;                      //讀取溫度變量
char Clock_date[] = {0,0,0};     //鬧鐘數據

void KeyScan();                  //按鍵檢測
void SMGdisplay();                                                   //數碼管顯示                                               
void ConfigTime0();              //配置定時器0
void Detection_Clock();          //檢測鬧鐘
void Close_Clock();              //關閉鬧鐘
void ZSD_L1();                   //鬧鐘指示燈
void dateStyle();                //鬧鐘,時鐘數據轉換函數





void main()
{   
          Init_waise();
          ConfigTime0();
    InitDS1302();
          while(1)
                {         
      if(flag_S7 == 0)        R_time();                                  
                         KeyScan();
                         SMGdisplay();
                         Detection_Clock();
                }
}




/*********************************************************************************************
【函數】 數碼管顯示界面切換函數
【功能】 負責按鍵使能切換數碼管顯示狀態
【小難點】 在時鐘設置期間,使操作位1s間隔閃爍。在中斷或者S7按鍵中做好標志位即可(本代碼在中斷)
*********************************************************************************************/
void SMGdisplay()
{
   if(flag_S7 >= 0 && flag_S6 == 0 && flag_1s == 0)       Time(Inittime[2],Inittime[1],Inittime[0]);
         else if(flag_S7 == 1 && flag_1s == 1)                  SetTime(0xFF, 0xFF, Inittime[1]/10,Inittime[1]%10, Inittime[0]/10, Inittime[0]%10);
         else if(flag_S7 == 2 && flag_1s == 1)                  SetTime(Inittime[2]/10,Inittime[2]%10, 0xFF, 0xFF, Inittime[0]/10, Inittime[0]%10);
         else if(flag_S7 == 3 && flag_1s == 1)                  SetTime(Inittime[2]/10,Inittime[2]%10, Inittime[1]/10, Inittime[1]%10, 0xFF, 0xFF);
         else if(flag_S7 == 0 && flag_S6 > 0)                   Time(Clock_date[2],Clock_date[1],Clock_date[0]);
}

/*********************************************************************************************************************************
【函數】 按鍵檢測函數
【功能】 按下按鍵觸發相應工作標志位
【優化】 在按鍵彈起等待while(S? == 0)期間優化了對應數碼管功能,使數碼管不會再按鍵按下彈起期間閃爍或抖動
【算法】 使用的對按鍵功能選擇位的處理  加4為0(詳見S6)
【額外說明】對按鍵的工作使能位的操作以及對數碼管多狀態的選擇切換是本賽題中的最大的難點,一定要理清好功能之間的邏輯關系
*********************************************************************************************************************************/
void KeyScan()
{
   if(S7 == 0)
         {
            delay(200);          
                  if(S7 == 0 && flag_S6 == 0 && flag_Clock == 0)
                        {
                                 flag_S7 ++;
                                 if(flag_S7 >3)  
                                 {
                                          flag_S7 = 0;
                                    flag_1s = 0;
                                 }                                         
                        }while(S7 == 0)
                        {
                                 if(flag_S6 == 0)       Time(Inittime[2],Inittime[1],Inittime[0]);
                                 else if(flag_S6 > 0)   Time(Clock_date[2],Clock_date[1],Clock_date[0]);
                        }
                        Close_Clock();
         }
         
         if(S6 == 0)
         {
            delay(200);
                  if(S6 == 0 && flag_S7 == 0 && flag_Clock == 0)
                        {
                                 flag_S6 ++;
                                 flag_S6 &= 0x03;    //加4為0
                        }while(S6 == 0)
                        {
                           if(flag_S6 == 0)       Time(Inittime[2],Inittime[1],Inittime[0]);
                                 else if(flag_S6 > 0)   Time(Clock_date[2],Clock_date[1],Clock_date[0]);
                        }
                        Close_Clock();
         }
         
         if(S5 == 0)
         {
            delay(200);
                  if(S5 == 0 && flag_Clock == 0)
                        {  
                                 if(flag_S7)
                                 {
                                    switch(flag_S7)
                                                {
                                                         case 1: Inittime[2] ++;   break;
                                                         case 2: Inittime[1] ++;   break;
                                                         case 3: Inittime[0] ++;   break;
                                                         default: break;
                                                }
                                 }
                                 else if(flag_S6)
                                 {
                                    switch(flag_S6)
                                                {
                                                         case 1: Clock_date[2] ++;  break;
                                                         case 2: Clock_date[1] ++;  break;
                                                         case 3: Clock_date[0] ++;  break;
                                                         default: break;
                                                }
                                 }
                                 dateStyle();
                                 InitDS1302();
                        }while(S5 == 0)
                        {
                           if(flag_S6 == 0)        Time(Inittime[2],Inittime[1],Inittime[0]);
                                 else if(flag_S6 > 0)   Time(Clock_date[2],Clock_date[1],Clock_date[0]);
                        }
                  Close_Clock();
         }
         
         if(S4 == 0)
         {
                                delay(200);
                                if(S4 == 0)
                                {
                                                 if(flag_S7)
                                                 {
                                                                        switch(flag_S7)
                                                                        {
                                                                                  case 1: Inittime[2] --;   break;
                                                                                  case 2: Inittime[1] --;   break;
                                                                                  case 3: Inittime[0] --;   break;
                                                                                  default: break;
                                                                        }
                                                 }
                                                 else if(flag_S6)
                                                 {
                                                                  switch(flag_S6)
                                                                  {
                                                                                        case 1: Clock_date[2] --;  break;
                                                                                        case 2: Clock_date[1] --;  break;
                                                                                        case 3: Clock_date[0] --;  break;
                                                                                        default: break;
                                                                  }
                                                 }
                                                 dateStyle();
                                                 InitDS1302();                                 
                                }while(S4 == 0)
                                {
                                                 if(flag_S7 == 0 && flag_S6 == 0 && flag_Clock == 0)
                                                 {
                                                                    temp = rd_temperature();   //溫度讀取
                                                                    Wendu_SMG(temp);
                                                                    R_time();                  //防止在長按S4情況下導致鬧鐘失效
                                                                    Detection_Clock();
                                                 }
                                                 else if(flag_S6 == 0)        Time(Inittime[2],Inittime[1],Inittime[0]);
                                                 else if(flag_S6 > 0)         Time(Clock_date[2],Clock_date[1],Clock_date[0]);
                                }
                                Close_Clock();
                }
}

/**********************************************************************************************************
【函數】      鬧鐘,時鐘數據轉換函數
【功能】      當 時 設置時間大于23h時,使其等于0;小于0時,使其等于23;分,秒同理
【額外說明】  不加的話,時間更改會出現24小時,62分鐘或秒的情況            ———相當于對時間按鍵設置的優化
**********************************************************************************************************/
void dateStyle()
{     
      if(Inittime[2] > 23)                      Inittime[2] = 0;
      else if(Inittime[2] < 0)                        Inittime[2] = 23;
                        else if(Inittime[1] >= 60)    Inittime[1] = 0;
      else if(Inittime[1] < 0)                        Inittime[1] = 59;
                        else if(Inittime[0] >= 60)    Inittime[0] = 0;
      else if(Inittime[0] < 0)                  Inittime[0] = 59;
       
            if(Clock_date[2] > 23)              Clock_date[2] = 0;
      else if(Clock_date[2] < 0)                Clock_date[2] = 23;
                        else if(Clock_date[1] >= 60)  Clock_date[1] = 0;
      else if(Clock_date[1] < 0)                Clock_date[1] = 59;
                        else if(Clock_date[0] >= 60)  Clock_date[0] = 0;
      else if(Clock_date[0] < 0)                Clock_date[0] = 59;  
}

/******************************************************************************
【函數】 鬧鐘檢測函數
【功能】 在main函數時刻檢測鬧鐘,鬧鐘到觸發鬧鐘使能標志位,使鬧鐘打開
******************************************************************************/
void Detection_Clock()
{
     if(Inittime[2]==Clock_date[2] && Inittime[1]==Clock_date[1] && Inittime[0]==Clock_date[0])
                 {
                                         flag_Clock = 1;
                                         flag_led = 1;
                                         Selest573(5);
                                         P0 = 0x40;
                                         Selest573(0);
                                         P0 = 0xFF;
                 }
}

/********************************************************************
【函數】 鬧鐘關閉函數
【功能】 鬧鐘響起時 按下任意按鍵觸發鬧鐘使能標志位,使鬧鐘關閉
********************************************************************/
void Close_Clock()
{
   if(flag_Clock == 1)
         {
                                flag_Clock = 0;
                                Selest573(5);
                                P0 = 0x00;
                                Selest573(0);
                                P0 = 0xFF;
         }
}

/*********************************************************
【函數】L1指示燈函數
【功能】每隔0.2s L1 閃爍一次
*********************************************************/
void ZSD_L1()
{   
          static uchar t = 0;
          static uint t_5s = 0;
    if( flag_led == 1)  
                {
                                 t++;
                                 t_5s++;
                                 if(t_5s > 2500)
                                 {
                                                  t_5s = 0;
                                                  t = 200;
                                                  flag_led = 0;                                 
                                 }
                                 
                                 if(t/100 == 1)       //每0.2s到
                                 {  
                                                        Selest573(0);
                                                        P0 = 0xFF;
                                                        Selest573(4);
                                                        P0 = 0xFE;
                                                        Selest573(0);
                                                        P0 = 0xFF;
                                                        P2 = (P2 & 0xFF) | 0x04;                                 
                                 }
                                 else if(t/100 == 2)
                                 {
                                                        t = 0;
                                                        Selest573(0);
                                                        P0 = 0xFF;
                                                        Selest573(4);
                                                        P0 = 0xFF;
                                                        Selest573(0);
                                                        P2 = (P2 & 0xFF) | 0x04;
                                 }                                 
                }
}

/*********************************************************************
【函數】:定時器0初始化函數,中斷函數
【功能】:2ms中斷一次,控制L1指示燈閃爍,控制處于設置的時間閃爍
【晶振】:11.0592MHz
*********************************************************************/
void ConfigTime0()
{
    AUXR |= 0x80;                //定時器時鐘1T模式
                TMOD &= 0xF0;                //設置定時器模式
                TL0 = 0x9A;                  //設置定時初值
                TH0 = 0xA9;                  //設置定時初值
                TF0 = 0;                    //清除TF0標志
       
          EA = 1;
          ET0 = 1;
                TR0 = 1;                   //定時器0開始計時
       
}

void InterruptTime0() interrupt 1
{
         static uchar t_1s = 0;
         if(flag_S7)
         {
                                t_1s ++;
                                if(t_1s / 500 == 1)        flag_1s = 1;     //1s到,熄滅數碼滅
                                else if(t_1s / 500 == 2)                    //2s到,數碼管顯示正常
                                {  
                                          t_1s = 0;
                                    flag_1s = 0;
                                }                                       
         }
         
         if(flag_S7 == 0 && flag_S6 == 0)
         {
              flag_1s = 0;
         }

         
    ZSD_L1();           //指示燈閃爍5s關閉
}





剩余篇幅鏈接如下;



第八屆.zip (70.77 KB, 下載次數: 60)

評分

參與人數 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:463607 發表于 2022-4-4 21:40 | 顯示全部樓層
樓主說話好有趣,代碼已經下載下來準備好好學習下了
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲免费在线观看 | 一级国产精品一级国产精品片 | 成人精品鲁一区一区二区 | 成年人在线视频 | 久久精品小视频 | 看毛片网站 | 精品久久久久国产免费第一页 | 国产精品久久一区二区三区 | 亚洲人成在线播放 | 亚洲精品18 | 国产aaaaav久久久一区二区 | 国产情侣在线看 | 免费观看www7722午夜电影 | 欧美aⅴ在线观看 | 精品一区二区免费视频 | 狠狠爱网址 | 国产成人精品午夜 | 日韩欧美一区二区三区免费看 | 日韩成人av在线播放 | 欧美四虎 | 亚洲色图第一页 | 亚洲一区二区av | 婷婷一级片 | 国产欧美精品一区二区三区 | 亚洲成人免费视频在线 | 一级毛片在线视频 | 精品久| 蜜桃视频在线观看免费视频网站www | 91麻豆产精品久久久久久 | 美国av片在线观看 | 91一区二区在线观看 | www.亚洲一区二区三区 | 久久久久无码国产精品一区 | 亚洲香蕉 | 亚洲精品美女视频 | 国产精品色婷婷久久58 | 国产精品99久久久久久动医院 | 北条麻妃av一区二区三区 | 久久久久国产精品免费免费搜索 | 在线观看中文视频 | 国产色网 |