要求:
1、數字鐘:時、分,小時用二十四進制顯示,分鐘用六十進制顯示。
2、顯示采用動態數碼管顯示方式
3、動態時顯示六位:時 分 秒 用按鍵可切換顯示年月日
4、具有清零的功能,且能夠對小時、分鐘進行調整(校時)。
5、具有整點、半點報時功能,整點用聲音次數報時,半點特殊聲音報時。
一、Protues仿真圖:
二、程序源碼:
因為注釋非常的全,這里就不再進行講解了。
/*******************************************************************************
================================================================================
【平 臺】STC89C51_sumjess平臺
【編 寫】sumjess
【E-mail 】1371129880@qq.com
【軟件版本】V2.0
【最后更新】2019年06月10日
【相關信息參考下列地址】
【網 站】
https://blog.csdn.net/qq_38351824
http://www.51hei.com/bbs/mcu-2-1.html
---------------------------------------------------------------------------------
【dev.env.】MDK4.02及以上版本
【Target 】STC89C51
第一次修訂:2019/05/09
第二次修訂:2019/05/21
第三次修訂:2019/06/10
【problem 】
(1)庫內補充的不全面;
(2)庫內解釋部分不全面;
(3)庫內還存在一定的bug;
【direction】
下一步的目標就是把庫繼續集成!
【explain 】
為了方便使用,我也自己寫了很多的庫,和優化了算法和表示方式!
【warning】
目前程序中暫無錯誤 !
---------------------------------------------------------------------------------
沒有完美的代碼,只有不斷的奉獻,大家一起努力;
贈人玫瑰手留余香,歡迎大家反饋bug!
================================================================================
********************************************************************************/
#include #include"intrins.h" //循環移位函數頭文件 #define uint unsigned int // 宏定義 #define uchar unsigned char #define NOT_Break 25 //任意賦值避開條件 uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0XBF,0xff}; //共陽極數碼管編碼0-9和“—” uchar val[8]={2,3,10,5,9,10,5,5}; sbit key0 = P0^0; //清零 sbit key1 = P0^1; //時間---年月日轉換 sbit BEEP = P3^7; //蜂鳴器 uchar wei=0X01,duan=0; void smg()//數碼管掃描送顯示函數 { P1=wei; // 選擇要點亮的數碼管是哪一個 P2=table[val[duan]]; // 給改數碼管送顯示數據 wei=_crol_(wei,1); // 移位,為點亮下一個數碼管做準備 duan++; if(duan>7) duan=0; } void delay(uint z) //1毫秒 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void time0init() // 定時器0初始化函數 { TMOD=0x01; //設置定時器0為工作方式1(M1M0為01) TH0=(65536-2000)/256; //裝初值12M晶振定時2ms數為2000 TL0=(65536-2000)%256; EA=1; //開總中斷 ET0=1; //開定時器0中斷 TR0=1; //啟動定時器0 } uint num=0,keytime=0,time; //時間更新 1s,20ms掃描一次按鍵, 控制修改項閃爍 void time0() interrupt 1 { TH0=(65536-2000)/256; //裝初值12M晶振定時2ms數為2000 TL0=(65536-2000)%256; keytime++; //20ms掃描一次按鍵 time++; //控制修改項閃爍 num++; //時間更新 1s smg(); } uchar key() { static uchar kzt=0; //推動循環,每次執行一次case uchar sb=NOT_Break; //任意賦值避開條件 switch(kzt) //按順序依次執行 { //------------case 0:------------// case 0: //第一步 P3=0xff; //P3做讀入狀態時,應該要先寫1的,才能正確讀入數據 //按照課本原文 作輸入時:必須先將1寫入口鎖存器,使場效應管截止,該口線同時被內部上拉電阻拉成高電平,同時也能被外部輸入源拉成低電平,即外部輸入1時,該口線為高電平,輸入0時,該口線為低電平 if(P3!=0xff) //如果有按鍵按下 { kzt=1; //向下執行第二步 return NOT_Break; //返回一個無關的值,用來跳出此次循環 } break; //如果沒有按鍵按下,直接跳出 //------------case 1:------------// case 1: //第二步 P3=0xff; //P3做讀入狀態時,應該要先寫1的,才能正確讀入數據 //按照課本原文 作輸入時:必須先將1寫入口鎖存器,使場效應管截止,該口線同時被內部上拉電阻拉成高電平,同時也能被外部輸入源拉成低電平,即外部輸入1時,該口線為高電平,輸入0時,該口線為低電平 if(P3!=0xff) //有按鍵按下 { switch(P3) { case 0xfe: //第一個按鍵按下 sb=0; break; //直接跳出 case 0xfd: //第二個按鍵按下 sb=1; break; //直接跳出 case 0xfb: //第三個按鍵按下 sb=2; break; //直接跳出 case 0xf7: //第四個按鍵按下 sb=3; break; //直接跳出 } kzt=2; //如果無按鍵按下 向下執行第三步 return sb; //返回sb的值 } else //如果無按鍵按下 回到第一步 { kzt=0; return NOT_Break; //返回一個無關的值,用來跳出此次循環 } break; //------------case 2:------------// case 2: //第三步 P3=0xff; //P3做讀入狀態時,應該要先寫1的,才能正確讀入數據 //按照課本原文 作輸入時:必須先將1寫入口鎖存器,使場效應管截止,該口線同時被內部上拉電阻拉成高電平,同時也能被外部輸入源拉成低電平,即外部輸入1時,該口線為高電平,輸入0時,該口線為低電平 if(P3==0xff) //如果沒有按鍵按下 { kzt=0; //如果無按鍵按下 回到第一步 return NOT_Break; } break; //如果有按鍵按下 直接跳出 } return NOT_Break; } void main() { char shi=23,fen=59,miao=55,qh=0; //初始化時分秒 狀態標志位(0:正常,1:改變秒鐘,2:改變分鐘,3:改變時鐘) char flag=0; //標志位---年月日&&時分秒 char keycode=NOT_Break; //鍵值 P0=0xff; P1=0xff; P2=0xff; P3=0xff; delay(10); //保證上面三條指令順利完成 time0init(); //定時器0初始化函數 while(1) { if(key0==0) //清零按鍵按下 { shi=0;fen=0;miao=0; //時分秒清零 qh=0; //開始顯示 } if(key1==0) //年月日&&時分秒按鍵按下 { while(!key1); //等待放開按鍵 if(flag==0) flag=1; //年月日&&時分秒 else flag=0; qh=0; //開始顯示 } if(keytime>9) //2ms*10=20ms { keytime=0; //計數清零 keycode=key(); //檢測是否有按鍵按下 } //////////////////////////////---時間更新---////////////////////////////// if((num>=500)&&(qh==0)) //時間更新 2ms*500=1s { num=0; //計數清零 miao++; //秒數加1 if(miao>59) //如果miao等于60 { miao=0; //miao賦值為0 fen++; //分鐘加1 if(fen>59) //如果fen等于60 { fen=0; //fen賦值為0 shi++; //小時加1 if(shi>23) shi=0;//如果shi等于24 shi賦值為0 } } } /////////////////////////////////////////////////////////////////////////// //////////////////////////////---按鍵檢測---/////////////////////////////// ///////////////////////////---第一個按鍵按下---/////////////////////////////// if(keycode==0) //第一個按鍵按下 選擇 { qh++; //狀態標志位(0:正常,1:改變秒鐘,2:改變分鐘,3:改變時鐘) if(qh>3) qh=1; //如果qh等于4,qh賦值為1 keycode=NOT_Break; //任意賦值避開條件 } ///////////////////////////---第二個按鍵按下---/////////////////////////////// if(keycode==1) //第二個按鍵按下 加 { if(qh==1) { miao++; if(miao>59) miao=0;//如果miao等于60 miao賦值為0 } if(qh==2) { fen++; if(fen>59) fen=0; //如果fen等于60 fen賦值為0 } if(qh==3) { shi++; if(shi>23)shi=0; //如果shi等于24 shi賦值為0 } keycode=NOT_Break; //任意賦值避開條件 } ///////////////////////////---第三個按鍵按下---/////////////////////////////// if(keycode==2) //第三個按鍵按下 減 { if(qh==1) { miao--; if(miao<0) miao=59;//如果miao等于-1 miao賦值為59 } if(qh==2) { fen--; if(fen<0) fen=59; //如果fen等于-1 fen賦值為59 } if(qh==3) { shi--; if(shi<0) shi=23; //如果shi等于-1 shi賦值為23 } keycode=NOT_Break; //任意賦值避開條件 } ///////////////////////////---第四個按鍵按下---/////////////////////////////// if(keycode==3) //第四個按鍵按下 確定 { qh=0; keycode=NOT_Break; //任意賦值避開條件 } /////////////////////////////////////////////////////////////////////////// ///////////////////////////---顯示函數---/////////////////////////////// switch(qh) //按鍵按下后立即顯示 { //正常顯示 case 0: if(flag==1) //顯示日期 年月日 { val[0]=2; val[1]=0; val[2]=1; val[3]=9; val[4]=0; val[5]=7; val[6]=0; val[7]=4; } else { val[0]=shi/10; //顯示時間 時分秒 val[1]=shi%10; val[2]=10; val[3]=fen/10; val[4]=fen%10; if(fen==30) { BEEP=0;delay(200);BEEP=1; } else if(fen==0) { BEEP=0;delay(100);BEEP=1;} val[5]=10; val[6]=miao/10; val[7]=miao%10; } break; //秒鐘修改后顯示 其中秒鐘部分在閃爍 case 1: if(time<250) //2ms*250=0.5s { val[0]=shi/10; val[1]=shi%10; val[3]=fen/10; val[4]=fen%10; val[6]=miao/10; val[7]=miao%10; } else if(time<500) //2ms*500=1s { val[0]=shi/10; val[1]=shi%10; val[3]=fen/10; val[4]=fen%10; val[6]=11; val[7]=11; } else if(time>500) //2ms*500=1s { time=0; } break; //分鐘修改后顯示 其中分鐘部分在閃爍 case 2: if(time<250) { val[0]=shi/10; val[1]=shi%10; val[3]=fen/10; val[4]=fen%10; val[6]=miao/10; val[7]=miao%10; } else if(time<500) { val[0]=shi/10; val[1]=shi%10; val[3]=11; val[4]=11; val[6]=miao/10; val[7]=miao%10; } else if(time>500) { time=0; } break; //時鐘修改后顯示 其中時鐘部分在閃爍 case 3: if(time<250) { val[0]=shi/10; val[1]=shi%10; val[3]=fen/10; val[4]=fen%10; val[6]=miao/10; val[7]=miao%10; } else if(time<500) { val[0]=11; val[1]=11; val[3]=fen/10; val[4]=fen%10; val[6]=miao/10; val[7]=miao%10; } else if(time>500)
上一篇:課程設計題四:LED彩燈控制器設計
下一篇:課程設計題二:7人多數表決器
推薦閱讀
史海拾趣
在追求技術創新的同時,DEI公司也注重品質管理和品牌塑造。公司建立了嚴格的質量管理體系,對每一個生產環節都進行嚴格的把控。同時,DEI公司也注重品牌形象的塑造,通過參與公益活動、舉辦技術研討會等方式,提升了公司的社會形象。這些舉措不僅增強了客戶對公司的信任度,也為公司的長遠發展奠定了堅實的基礎。
背景:HN Electronics成立于20世紀90年代初,正值全球電子市場快速崛起的時期。公司由一群在半導體領域擁有豐富經驗的工程師創立,他們看到了智能手機和消費電子產品市場的巨大潛力。
發展:初期,HN Electronics專注于研發高性能的電源管理芯片,通過技術創新解決了當時市場上存在的能效低、發熱量大等問題。公司迅速獲得了業界的認可,并與幾家知名手機制造商建立了合作關系。
關鍵事件:1995年,HN Electronics成功推出其首款自主研發的電源管理芯片,該產品迅速成為市場熱銷產品,為公司贏得了第一桶金。
APLUS Products公司起源于XXXX年,當時電子行業正處于飛速發展的黃金時期。公司創始人憑借對電子技術的深厚理解和市場需求的敏銳洞察,決定專注于研發和生產高質量的電子產品。初期,公司面臨著資金短缺、技術難題和市場競爭等多重挑戰。然而,通過不斷的技術創新和產品優化,APLUS逐漸在市場中嶄露頭角。
憑借卓越的產品性能和技術實力,東軟載波獲得了多項榮譽和認證。公司被評為“國家綠色工廠”,多款產品通過國內外權威認證。同時,公司還榮獲了多項行業獎項和榮譽稱號,如“2022 PLC互聯互通·基石獎”、“2022年山東民營企業新一代信息技術行業領軍10強”等。這些榮譽的獲得充分證明了東軟載波在電子行業中的領先地位和實力。
ATS公司成立于1989年,最初是一家專注于電子產品熱管理咨詢的公司。創始人團隊憑借其深厚的電子工程背景和敏銳的市場洞察力,識別到電子產品熱管理領域的潛在機遇。經過數月的研究和開發,ATS成功研發出了一種新型散熱技術,顯著提高了電子設備的散熱效率。這一技術突破迅速贏得了市場的認可,ATS開始收到來自各大電子產品制造商的咨詢和合作請求。
隨著全球環保意識的日益增強,ATS積極響應國家號召,將環保理念融入公司的產品和服務中。公司開始研發和生產符合環保標準的散熱器產品,采用環保材料和工藝,減少生產過程中的污染排放。同時,ATS還加強了對廢舊產品的回收和處理工作,努力實現資源的循環利用。這些舉措不僅提升了ATS的環保形象,也為公司的可持續發展奠定了堅實基礎。
這五個故事展示了ATS公司在電子行業中的發展歷程和取得的成就。從創業初期的技術突破,到從咨詢到制造的轉型,再到全球化戰略的實施和研發創新能力的持續提升,ATS始終保持著敏銳的市場洞察力和創新精神。同時,公司還積極踐行環保理念,為電子行業的可持續發展做出了積極貢獻。
ModBus幀格式為:從機地址(1字節),功能碼(1字節),起始地址(2字節),數據長度(2字節),CRC碼(2字節) 然后數據傳輸方式規定為串行異步:1位起始位,8位數據位,1偶校驗位,1位停止位。 我的疑問是: 1)CRC只對數據位進行校驗,那就是 ...… 查看全部問答∨ |
我添加了兩個用戶,于是在/home下有兩個目錄: my2410和xjli。 其中在my2410目錄下建一個腳本文件env_sh, 內容如下: # !/bin/bash PRJROOT=~/ KERNEL=$PRJROOT/kernel ROOTFS=$PRJROOT/rootfs TMP=$PRJROOT/tmp export PRJROOT KERNEL ROOTF ...… 查看全部問答∨ |
系統符號表創建過程如下代碼,而symTblCreate 函數參數SYM_TBL_HASH_SIZE_LOG2被定義為8 ,難道只有8 power of 2 =256 個符號表條目? 如果不是,那么符號表最長有多少?如果module中的symbols 太多添加進去使之溢出 ...… 查看全部問答∨ |
|
我開發一個驅動程序.sys和一個應用程序.exe,應用程序可以調用加載到內核的驅動 程序,我看資料說驅動程序的派遣函數是運行在應用程序的進線程的上下文中了,那 么我可以獲得應用程序的模式(PE加載到內核中)的資料么?然后再驅動里做點東西 可 ...… 查看全部問答∨ |
|
臺式電腦怎么無線上網?隨著無線上網的流行,目前不少地方都有無線網絡信號覆蓋,對于我們熟悉的筆記本電腦,平板電腦,以及智能手機都可以輕松實現無線或 wifi無線上網,那么對于我們比較傳統的臺式電腦怎么無線上網呢?近日QQ群中有人問“臺式 ...… 查看全部問答∨ |
|
在使用MOS管設計開關電源或者馬達驅動電路的時候,大部分人都會考慮MOS的導通電阻,最大電壓等,最大電流等,也有很多人僅僅考慮這些因素。這樣的電路也許是可以工作的,但并不是優秀的,作為正式的產品設計也是不允許的。下面是我對MOSFET及MOSFET ...… 查看全部問答∨ |
上位機我用VB編程,使用無線傳輸模塊,傳輸控制信號給單片機,來實現控制。 我的疑問是,在VB6.0里面,十六進制用的前綴是&H,在avr128單片機里面,用的十六進制前綴是0X。比如我用上位機發送一個十六進制數據(如&HAA)到單片機,單片機能直 ...… 查看全部問答∨ |
設計資源 培訓 開發板 精華推薦
- Microchip直播:單片機編程不再難, 利用MPLAB®代碼配置器(MCC)實現快速開發
- 【EEWORLD第二十三屆】2011年02月社區明星人物揭曉!
- 走近 AI 重磅新品 STM32N6,解鎖在 MCU 部署高性能、節能型邊緣 AI!答題有好禮~還有開發板等你拿!
- 有獎直播:Microchip適用于CryptoAuthentication™系列的可信任平臺
- 直播已結束--STM32全球線上峰會 | 新品STM32N6重磅發布,50+開發板等你抽!
- 【已結束】 電感應用知識分享|MPS 有獎直播
- TI有獎直播:伺服驅動器中電流和電壓測量解決方案
- 學AM335X課程,贏超值BB-Black團購資格,更有DIY大獎賽預熱中!
- 有獎評測:平頭哥RISC-V低功耗板——RVB2601