《基于單片機的數字時鐘的硬件結構及軟件系統設計》13000字(論文)_第1頁
《基于單片機的數字時鐘的硬件結構及軟件系統設計》13000字(論文)_第2頁
《基于單片機的數字時鐘的硬件結構及軟件系統設計》13000字(論文)_第3頁
《基于單片機的數字時鐘的硬件結構及軟件系統設計》13000字(論文)_第4頁
《基于單片機的數字時鐘的硬件結構及軟件系統設計》13000字(論文)_第5頁
已閱讀5頁,還剩56頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

PAGEII基于單片機的數字時鐘的硬件結構及軟件系統設計摘要電子日歷是一種非常常見的日常計時工具,在當今社會中越來越重要。電子日歷的硬件主要采用AT89C51作為主控核心,DS1302時鐘芯片提供時鐘和LCD1602液晶顯示器。AT89C51單片機由STC公司生產,功耗低,電壓可達4~6V;DS1302時鐘芯片是美國達拉斯公司生產的低功耗實時時鐘芯片,可實現年、月、日、周、時、分、秒計時,并具有閏年補償等多項功能。此外,DS1302應用壽命長,誤差小。它適用于數字電子日歷取直觀的數字顯示,數字顯示是取LCD1602液晶顯示器來顯示,可以同時顯示年、月、日、周、時、分、秒等信息。此外,電子日歷還具有時間校準功能。軟件方面,主要包括日通程序、時間調整程序、顯示程序等,所有程序編寫完成后,在keil軟件中進行調試。在沒有問題之后,它們被燒錄到MCU進行測試。本設計主要由時鐘芯片DS1302和溫度傳感器DS18B20采集數據到單片機進行處理,然后通過LCD1602顯示,本文主要討論了液晶顯示器LCD1602與時鐘芯片DS1302、溫度傳感器DS18B20與單片機的硬件互聯和通信,給出了幾種硬件連接方案在日歷計算的軟件方面,對該方法進行了詳細的比較?!娟P鍵詞】AT89C51LCD1602DS18B20DS1302按鍵目錄11486前言 121075第一章工作原理 2237061.1設計目標 2314251.1.1基本功能 28838第二章硬件設計與原理 3145852.1總設計框圖 3202382.2硬件設計分析 3144542.2.1電源的設計 344682.2.2單片機最小系統 4159402.2.3顯示系統 10271722.2.4LCD1602的指令說明及時序 126442.2.5LCD1602的RAM地址映射及標準字庫表 1432202.2.6DS1302原理及說明 16161972.2.7DS18B20工作原理及說明 1954422.2.8按鍵電路 2026381第三章軟件設計與分析 22236973.1軟件設計的組成 22186313.2源程序 2613711第四章軟件仿真 56214844.1PROTEUS簡介 5681714.2仿真圖 5818214.3原理圖 59283274.4元件清單 6025374參考文獻 64前言近年來,隨著通道技術的飛速發展,單片機領域不斷走向社會的每一個角落,也推動著傳統的主控檢測技術日新月異。在單片機實時操作和主動控制系統中,單片機是目前應用的核心部件。僅僅掌握單片機的知識是不夠的。它還應根據其具體的硬件結構和軟件組合,針對應用對象的具體特點加以完善。單片機原理與應用課程設計是電子類專業的一門基礎課程。它是繼匯編語言程序設計和接口技能課程之后的一門實踐性課程。

第一章工作原理1.1設計目標1.1.1基本功能此萬年歷主要具有:年、月、日、星期、時、分、秒、溫度顯示。主要功能:1、萬年歷2、時間3、星期4、溫度顯示(以上四項內容同時顯示)5、四鍵調時(設置鍵、上調鍵、下調鍵、關音按鍵)第二章硬件設計與原理以AT89C51單片機為核心,起著控制作用。系統包括LCD1602液晶顯示電路、復位電路、時鐘電路、按鍵電路、溫度傳感器電路、時鐘芯片電路。設計思路分為七個模塊:復位電路、晶振電路模塊、AT89C51、LCD1602液晶顯示電路、按鍵電路、溫度傳感器電路、時鐘芯片電路這七個模塊。2.1總設計框圖2.2硬件設計分析2.2.1電源的設計系統電源使用直流5伏。由電腦USB接口提供電源。USB是通用串行總線(UniversalSerialBus)接口的簡稱。它是目前使用比較廣泛的電腦接口之一,主要版本有1.0、1.1和最新的2.0三種版本。根據USB總線的工業標準,它可以提供額定功率為5V/500mA的電源供USB設備使用。2.2.2單片機最小系統51單片機是所有與intel8031指令系統兼容的單片機的總稱。這一系列單片機的鼻祖是英特爾的8031單片機。后來,隨著同一技術的發展,它成為應用廣泛的8位單片機之一。MCU是一種大規模集成電路,它將CPU、ram、ROM、定時器/計數器、多功能I/O口等計算機所需的基本功能部件集成在一塊芯片中,又稱MCU。51系列單片機包括以下幾個部分:一個8位CPU;片上振蕩器和時鐘電路4KBROM程序存儲器128BRAM數據存儲器控制電路尋址64KB外部數據存儲器和64KB外部程序存儲器空間32個可編程I/O端口兩個16位定時器/計數器一個可編程全雙工串行端口五個中止源和兩個優先級嵌套中止結構As圖2-2-1是AT89C51單片機的基本結構,其基本性能介紹如下:圖2-2-1AT89C51單片機AT89C51包含40個引腳、32個外部雙向輸入/輸出(I/O)端口、2個外部和中間端口、3個16位可編程定時計數器和2個全雙工串行通信端口。AT89C51可以按常規方法編程,但不能在線編程。它將普通微處理器與flash存儲器相結合,特別是可擦除flash存儲器,可以有效地降低開發成本。AT89C51的主要特性如下表所示:兼容MCS—51指令系統32個可編程I/O線4k字節可編程閃爍存儲器可編程UARL通道三個16位可編程定時/計數器中斷時鐘頻率0-24MHz2個外部中斷源,共8個中斷源256×8bit內部RAM2個讀寫中斷口線可直接驅動LED軟件設置睡眠和喚醒功能低功耗空閑和掉電模式表2-2-1AT89C51主要功能描述AT89C51是一種8位通用微處理器,采用40針雙列直插式封裝。采用工業級C51核,內部功能和引腳布局與通用型8xc52相似。主要用于掌握收斂調整功能。主要功能包括會聚主芯片內部存儲器、數據RAM和外部接口的初始化、會聚調整的掌握、會聚測試圖的掌握、紅外遙控信號的吸收和解碼以及與主板CPU的通信。主要引腳有:xtal1(19引腳)和xtal2(18引腳)是振蕩器的輸入和輸出端口,外置12Mhz晶體振蕩器。Rst/VPD(9針)為復位輸入端口,復位電路由外電阻和電容組成。VCC(40針)和VSS(20針)是電源端口,分別連接到+5V電源的正極和負極端子。在本設計中,端口P0(32-39針)被定義為N1功能主端口,與N1的相應功能針相連。引腳13被定義為IR輸入端口,引腳10和引腳11被定義為I2C總線主端口,與N1的SDAs(18引腳)和SCLS(19引腳)端口相連。27引腳和28引腳被定義為握手信號功能端口,與主板CPU的相應功能端口相連,用于檢測電流系統并掌握匯聚調整功能的端口P0:端口P0是一組8位開漏雙向I/O端口,即地址/數據總線復用端口。當用作輸出端口時,每個TTL邏輯門可以通過吸收電流來驅動。將“1”寫入端口P0時,它可用作高阻抗輸入。當訪問外部數據存儲器或程序存儲器時,這組端口線分時地址轉換(低8位)和數據總線復用在訪問期間激活內部上拉電阻。在flash編程中,端口P0吸收指令字節,而在程序驗證中,它輸出指令字節。在驗證中,它請求外部上拉電阻器P1端口:P1是一個帶有內部上拉電阻器的8位雙向I/O端口。P1的輸出緩沖級可以驅動(吸收或輸出電流)4個TTL邏輯門。將“1”寫入端口,通過內部上拉電阻將端口拉至高電平,即可作為輸入端口。當用作輸入端口時,由于內部上拉電阻,引腳在被外部信號下拉時將輸出電流(IIL)。與AT89C51不同,P1.0和P1.1還可用作定時器/計數器2的外部計數輸入(P1.0/T2)和輸入(P1.1/t2ex)。在閃存編程和程序驗證期間,P1吸收低8位地址P2端口:P2是一個帶內部上拉電阻器的8位雙向I/O端口。P2的輸出緩沖級可以驅動(吸收或輸出電流)4個TTL邏輯門。將“1”寫入端口P2,并通過內部上拉電阻將端口拉至高電平。此時,它可以用作輸入端口。當它被用作輸入端口時,由于內部上拉電阻,當它被外部信號拉低時,引腳將輸出電流(IIL)。當訪問具有16位地址的外部程序存儲器或外部數據存儲器時(例如,執行MOVX@dptr指令),P2端口發送高8位地址數據。當訪問具有8位地址的外部數據存儲器(例如執行MOVX@RI指令)時,P2端口輸出P2鎖存器的內容。在flash編程或驗證過程中,P2還吸收高位地址和一些主信號&P3端口:P3端口是一組帶有內部上拉電阻的8位雙向I/O端口。P3端口的輸出緩沖級可以驅動(吸收或輸出電流)四個TTL邏輯門。當將“1”寫入P3端口時,它們由內部上拉電阻器上拉,可用作輸入端口。此時,外部下拉的P3端口將使用上拉電阻器輸出電流(IIL)。除了作為一個通用的I/O端口外,P3端口的主要用途是它的第二個功能。P3端口還吸收一些主信號,用于閃存編程和程序驗證Rst:復位輸入。當振蕩器工作時,rst引腳輸出超過兩個機器周期,并且高電平將重置MCUAle/prog:當訪問外部程序存儲器或數據存儲器時,Ale(地址鎖存許可)輸出脈沖用于鎖存地址的低8位。通常,ale仍以時鐘振蕩頻率的1/6輸出一個固定的脈沖信號,因此可以用來輸出時鐘或定時目標。應當注意,每當訪問外部數據存儲器時,Al脈沖將被跳過。該引腳還用于在閃存編程期間輸入程序脈沖(PROG)。如有必要,可通過在SFR區域設置8eh裝置的D0位置來停止ale操作。在此位之后,只有一條MOVX和MOVC指令可以激活ale。此外,銷會稍微拉高。當MCU執行外部程序時,ale停止位應設置為無效PSEN:PSEN的輸出是外部程序存儲器的讀出通信號。當AT89C51從外部程序存儲器中獲取指令(或數據)時,PSEN每機器周期有效兩次,即輸出兩個脈沖。在此期間,當訪問外部數據存儲器時,PSEN信號將被跳過兩次。EA/VPP:外部訪問權限。為了使CPU只訪問外部程序存儲器(地址為0000hffffh),EA終端必須堅持低電平(接地)。應注意,如果加密位Lb1被編程,則在復位期間EAend狀態將被內部鎖定。如果EA端是高電平(連接到VCC端),CPU執行內部程序存儲器中的指令。閃存編程時,引腳加上+12V編程許可電源VPP,當然這一定是12V編程電壓VPP的應用器件。Xtal1:振蕩器反相放大器和內部時鐘發生器的輸入。Xtal2:振蕩器反相放大器輸出。單片機最小原理圖如圖2-2-2所示。圖2-2-2單片機最小系統單片機最小系統說明:時鐘信號產生:MCS-51芯片中有一個高增益逆變放大器,輸入為xtal1,輸出為xtal2。在芯片外部,xtal1和xtal2與晶體振蕩器和微調電容器連接,形成穩定的自激振蕩器,它是單片機的時鐘振蕩電路,時鐘電路的振蕩脈沖經觸發器分頻后成為單片機的時鐘脈沖信號,一般電容C2和C3約為30pf,晶體的振蕩頻率為1.2-12mhz。如果晶體振蕩頻率高,系統的時鐘頻率也高,單片機的運行速度也快,單片機復位使系統中的CPU等功能部件處于一定的初始狀態,并從該狀態開始工作。MCU復位條件:必須使9針加上連續兩個機器周期(即24個振蕩周期)的高電平。2.2.3顯示系統LCD1602分為帶背光和不帶背光兩種,基控制器大部分為HD44780,帶背光的比不帶背光的厚,是否帶背光在應用中并無差別,兩者尺寸差別如下圖2-2-3所示:圖圖2-2-3LCD1602尺寸圖LCD1602重要技術參數:1,顯示容量:16×2字符2,芯片工作電壓:4.5-5.5v3,工作電流:2.0ma(5.0V4,模塊最佳工作電壓:5.0V5,字符大?。?.95×4.35(W×H)Mm引腳功能說明LCD1602采用14引腳(無背光)或16引腳(帶背光)接口。各引腳接口說明如圖2-2-4所示:編號符號引腳說明編號符號引腳說明1VSS電源地9D2數據2VDD電源正極10D3數據3VL液晶顯示偏壓11D4數據4RS數據/命令選擇12D5數據5R/W讀/寫選擇13D6數據6E使能信號14D7數據7D0數據15BLA背光源正極8D1數據16BLK背光源負極圖圖2-2-4引腳接口說明圖2-2-4:引腳接口說明表引腳1:VSS是地面電源。引腳2:VDD連接到5V正極電源。第三個引腳:VL是LCD比較調整終端。接正電源時比較度最弱,接地時比較度最高。當它太高的時候,鬼魂就會出現。使用時,可通過10k電位器調節比較度。引腳4:RS是存儲設備、高級數據存儲設備和低級指令存儲設備的選擇。引腳5:R/W是讀/寫信號線,用于高電平的讀操作和低電平的寫操作。當RS和R/W都處于低電平時,它們可以寫指令或顯示地址;當RS處于低電平時,R/W處于高電平時,可以讀出忙信號;當RS處于高電平時,R/W處于低電平時,它們可以寫入數據。引腳6:e端子是啟用端子。當e終端從高電平跳到低電平時,LCD模塊執行命令。引腳7-14:d0-d7是8位雙向數據線。引腳15:背光陰極。引腳16:背光陰極。2.2.4LCD1602的指令說明及時序1602液晶模塊內部的控制器共有11條控制指令,如圖2-2-5所示:序號指令RSR/WD7D6D5D4D3D2D1D01清顯示00000000012光標返回000000001*3置輸入模式00000001I/DS4顯示開/關控制0000001DCB5光標或字符移位000001S/CR/L**6置功能00001DLNF**7置字符發生存貯器地址0001字符發生存貯器地址8置數據存貯器地址001顯示數據存貯器地址9讀忙標志或地址01BF計數器地址10寫數到CGRAM或DDRAM)10要寫的數據內容11從CGRAM或DDRAM讀數11讀出的數據內容圖圖2-2-5控制命令表通過指令編程完成1602液晶顯示模塊的讀寫操作、屏幕操作和光標操作。(說明:1為高電平,0為低電平)指令1:清除顯示,指令代碼01h,光標復位到地址00h位置命令2:復位光標并將光標返回到地址00h命令3:光標和顯示模式設置I/D:光標移動方向,高電平向右移動,低電平向左移動s:是否所有文本在屏幕上向左或向右移動。高電平有效,低電平無效命令4:顯示開關主控。D:掌握整體顯示的開與關,高電平顯示的開與關,低電平顯示的關顯示C:掌握光標的開與關,高電平顯示有光標,低電平顯示無光標B:掌握光標是否發光,高電平顯示,無光標低位顯示Command5:光標或顯示移位s/C:高位移動顯示文字,低位移動光標Command6:功能設置命令DL:高位4位總線,低位8位總線n:低位單行顯示,高位雙線顯示F:低位5x7點陣字符,5x10高位點陣字符Instruction7:字符發生器RAM地址設置Instruction8:DDRAM地址設置Instruction9:讀取忙信號和光標地址BF:忙標志位,高位表示忙,此時模塊無法吸收命令或數據,如果是低位,則表示不忙Instruction10:寫入數據說明11:讀取數據。2.2.5LCD1602的RAM地址映射及標準字庫表圖2-2-6圖2-2-6LCD1602內部顯示地址例如,如果第二行第一個字符的地址是40H,您是否可以直接寫入40H以將光標定位在第二行第一個字符上?這是不可能的,因為在寫入顯示地址時,請求的最高位D7總是高電平1,因此實際寫入的數據應該是01000000B(40H)+10000000B(80h)=11000000B(C0H)。在初始化液晶顯示模塊時,首先要設置顯示模式,液晶顯示模塊中顯示的字符的時標主動向右移動,不需要人工干預。每次輸入前確定LCD模塊是否忙。1602液晶顯示模塊中的字符生成存儲器(cgrom)存儲了160種不同的點陣字符圖形。這些字符包括阿拉伯數字、英文字母的大小寫、常用符號和日語假名。每個字符都有一個固定的代碼。例如,大寫英文字母“a”的代碼為01000001b(41h)。模塊顯示地址41當顯示H中的點陣字符圖時,我們可以看到字母“a”。圖2-2-7液晶顯示電路2.2.6DS1302原理及說明(1)時鐘芯片DS1302的工作原理:每次讀寫程序前,必須對DS1302進行初始化。首先,將SCLK端設置為“0”,然后將rst端設置為“1”,最后給出SCLK脈沖。讀/寫順序如下圖2.2所示。圖2.1顯示了DS1302的主字。主字的第7位必須設置為1。如果為0,則無法向DS1302讀取或寫入數據。對于位6,如果ram=1表示程序讀/寫,CK=0表示時間讀/寫。位1到5表示操作單元的地址。位0是讀/寫操作位。當執行讀取操作時,位為1;當位為0時,執行寫操作。主字節總是從最低位輸入/輸出。表2.2顯示了DS1302的日歷和時間存儲設備的內容:“ch”是時鐘暫停標記位。位為1時,時鐘振蕩器停止,DS1302處于低功耗狀態;位為0時,時鐘開始運行?!癢P”是寫掩碼位。在對時鐘和ram進行任何寫操作之前,WP必須為0。當“WP”為1時,寫入掩碼位防止寫入任何寄存器。(2)DS1302的主字DS1302的主字如圖2.1所示。主字節的高有效位(位7)必須是邏輯1。如果為0,則無法將數據寫入DS1302。如果位6為0,則可以訪問日歷時鐘數據。如果位1為1,則可以訪問RAM數據。位5到1指示操作單元的地址。如果位0為0,則可以執行寫操作。如果位1是1,則可以執行讀取操作。主字節總是從最低位終端輸出打開。圖2-2-8DS1302的控制字(3)當指令字輸入后的下一個SCLK時鐘的上升沿被抓住時,數據被寫入DS1302,并且數據輸入從低位開始,即位0。類似地,在緊接8位主指令字之后的下一個SCLK脈沖的下邊緣處讀取DS1302的數據,并且從低位0到高位7讀取數據。如圖2-2-9所示:圖2-2-9DS1302讀與寫的時序圖(3)DS1302寄存器DS1302有12個寄存器,其中7個寄存器與日歷和時鐘有關。存儲的數據位是BCD碼。日歷、時間寄存器及其主字見表2.2。表2.2DS1302的日歷、時間寄存器此外,DS1302還具有年存儲、主存儲、充電存儲、時鐘突發存儲和ram相關存儲。時鐘突發存儲設備可以一次順序地讀寫除充電存儲設備之外的存儲設備的所有內容。DS1302ram相關存儲器可分為兩種:一種是單個ram單元,共31個字節,每個單元配置為8位字節,其命令主字為C0H~FDH,奇數為讀操作,偶數為寫操作;另一種是突發方式下的ram存儲器,它可以一次讀寫全部31字節的RAM,命令主字是FEH(寫)和FFH(讀)。圖2-2-10DS1302電路2.2.7DS18B20工作原理及說明DS18B20的讀寫時序和測溫原理與DS1820相同,只是溫度值的位數因分辨率不同而不同,溫度轉換的延遲時間從2s縮短到750ms,DS18B20測溫原理如所示圖2-1-10。圖中溫度系數較低的晶體振蕩器的振蕩頻率受溫度影響不大。它用于產生一個固定頻率的脈沖信號,并將其發送到計數器1。高溫系數晶體振蕩器的振蕩速率隨溫度的變化而顯著變化,產生的信號作為計數器2的脈沖輸入。計數器1和溫度存儲預設為-55℃對應的基值。計數器1對低溫系數晶體振蕩器產生的脈沖信號進行減法計數。當計數器1的預置值減為0時,溫度存儲裝置的值將增加1,計數器1的預置值將重新加載。計數器1再次開始對低溫系數晶體振蕩器產生的脈沖信號進行計數。此循環將停止溫度存儲裝置值的累積,直到計數器2計數為0,此時,溫度存儲裝置中的值為測量溫度。圖2-1-10中的斜率累加器用于補償和修正溫度測量過程中的非線性,其輸出用于修正計數器1的預設值。

圖2-2-11DS18B20測溫原理框圖圖2-2-12DS18B20電路2.2.8按鍵電路按鍵是由一組按鍵或觸摸開關組成的陣列,是一種常用的輸入設備。鍵盤可分為編碼鍵盤和非編碼鍵盤1。編碼鍵盤通過硬件電路產生按鍵的按鍵代碼。該鍵盤程序簡單,但硬件電路復雜,價格昂貴,單片機系統一般不采用。在非編碼鍵盤中,一些鍵通常排列成行矩陣。硬件邏輯與密鑰編碼之間沒有嚴格的對應關系,但由所用程序決定。非編碼鍵盤的硬件接口簡單,但占用CPU時間較長,因此通常采用可編程鍵盤管理芯片來克服這一缺陷。本設計采用兩種按鍵,一種是按鍵式非編碼鍵盤,另一種是觸摸式非編碼開關,由于接線中有四個插腳,因此需要用萬用表測量連接,然后將兩個插腳連接起來。原理圖如下為了計算數據,必須先輸入數據,還必須確認按鍵輸入的值。這需要掃描鍵盤,以便確認到底按了哪個鍵。圖2-2-13按鍵電路第三章軟件設計與分析3.1軟件設計的組成系統由延時子功能、LCD1602LCD寫入命令子功能、LCD1602LCD寫入數據子功能、DS18B20初始化子功能、DS18B20讀取1位數據子功能、讀取字節數據子功能、向DS18B20寫入字節數據子功能、DS18B20啟動取溫轉換子功能組成,獲取溫度子函數、初始化子函數、DS1302地址子函數、數據發送子函數發送子函數、DS1302數據讀取子函數、DS1302初始化子函數、顯示年、月、日、周子函數、按鍵掃描子函數、主函數和數據定義。圖3-1-1DS1302讀取日期和時間流程圖圖3-1-2DS18B20溫度傳感器流程圖圖3-1-3時間調整程序流程圖圖3-1-4整體流程圖圖3-1-5DS1302讀寫程序流程圖3.2源程序#include<reg51.h>#include"DS18B20.h"uchara,b,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp,miao1,shi1=12,fen1=1,miao1=0,clock=0;//flag用于讀取頭文件中的溫度值,和顯示溫度值#defineyh0x80//LCD第一行的初始位置,因為LCD1602字符地址首位D7恒定為1(100000000=80)#defineer0x80+0x40//LCD第二行初始位置(因為第二行第一個字符位置地址是0x40)//液晶屏的與C51之間的引腳連接定義(顯示數據線接C51的P0口)sbitrs=P2^0;sbiten=P2^2;sbitrw=P2^1;//如果硬件上rw接地,就不用寫這句和后面的rw=0了sbitled=P2^6;//LCD背光開關//DS1302時鐘芯片與C51之間的引腳連接定義sbitIO=P1^1;sbitSCLK=P1^0;sbitRST=P1^2;sbitCLO=P1^4;sbitACC0=ACC^0;sbitACC7=ACC^7;/************************************************************ACC累加器=AACC.0=E0HACC.0就是ACC的第0位。Acc可以位尋址。累加器ACC是一個8位的存儲單元,是用來放數據的。但是,這個存儲單元有其特殊的地位,是單片機中一個非常關鍵的單元,很多運算都要通過ACC來進行。以后在學習指令時,常用A來表示累加器。但有一些地方例外,比如在PUSH指令中,就必須用ACC這樣的名字。一般的說法,A代表了累加器中的內容、而ACC代表的是累加器的地址。***************************************************************///校時按鍵與C51的引腳連接定義sbitkey1=P1^5;//設置鍵sbitkey2=P1^6;//加鍵sbitkey3=P1^7;//減鍵sbitbuzzer=P1^3;//蜂鳴器,通過三極管9012驅動,端口低電平響/**************************************************************/ucharcodetab1[]={"20--"};//年顯示的固定字符ucharcodetab2[]={"::"};//時間顯示的固定字符ucharcodetab3[]={"HELLOWELCOME"};//開機動畫//延時函數,后面經常調用voiddelay(uintxms)//延時函數,有參函數{ uintx,y; for(x=xms;x>0;x--) for(y=110;y>0;y--);}/********液晶寫入指令函數與寫入數據函數,以后可調用**************//*在這個程序中,液晶寫入有關函數會在DS1302的函數中調用,所以液晶程序要放在前面*/voidwrite_1602com(ucharcom)//****液晶寫入指令函數****{ rs=0;//數據/指令選擇置為指令 rw=0;//讀寫選擇置為寫 P0=com;//送入數據 delay(1); en=1;//拉高使能端,為制造有效的下降沿做準備 delay(1); en=0;//en由高變低,產生下降沿,液晶執行命令}voidwrite_1602dat(uchardat)//***液晶寫入數據函數****{ rs=1;//數據/指令選擇置為數據 rw=0;//讀寫選擇置為寫 P0=dat;//送入數據 delay(1); en=1;//en置高電平,為制造下降沿做準備 delay(1); en=0;//en由高變低,產生下降沿,液晶執行命令}voidlcd_init()//***液晶初始化函數****{ ucharj;write_1602com(0x0f|0x08); for(a=0;a<17;a++) write_1602dat(tab3[a]); j=17; while(j--) { write_1602com(0x1c);//循環左移 delay(700); } write_1602com(0x01); delay(10); write_1602com(0x38);//設置液晶工作模式,意思:16*2行顯示,5*7點陣,8位數據 write_1602com(0x0c);//開顯示不顯示光標 write_1602com(0x06);//整屏不移動,光標自動右移 write_1602com(0x01);//清顯示 /***開機動畫顯示hellowelcomedianzizhong****/ write_1602com(yh+1);//日歷顯示固定符號從第一行第1個位置之后開始顯示 for(a=0;a<14;a++) { write_1602dat(tab1[a]);//向液晶屏寫日歷顯示的固定符號部分 //delay(3); } write_1602com(er+2);//時間顯示固定符號寫入位置,從第2個位置后開始顯示 for(a=0;a<8;a++) { write_1602dat(tab2[a]);//寫顯示時間固定符號,兩個冒號 //delay(3); } write_1602com(er+0); write_1602dat(0x24); write_1602com(er+1); write_1602dat(0x20);}/***************DS1302有關子函數********************/voidwrite_byte(uchardat)//寫一個字節{ ACC=dat; RST=1; for(a=8;a>0;a--) { IO=ACC0; SCLK=0; SCLK=1; ACC=ACC>>1; }}ucharread_byte()//讀一個字節{ RST=1; for(a=8;a>0;a--) { ACC7=IO; SCLK=1; SCLK=0; ACC=ACC>>1; } return(ACC);}//voidwrite_1302(ucharadd,uchardat)//向1302芯片寫函數,指定寫入地址,數據{ RST=0; SCLK=0; RST=1; write_byte(add); write_byte(dat); SCLK=1; RST=0;}ucharread_1302(ucharadd)//從1302讀數據函數,指定讀取數據來源地址{ uchartemp; RST=0; SCLK=0; RST=1; write_byte(add); temp=read_byte(); SCLK=1; RST=0; return(temp);}ucharBCD_Decimal(ucharbcd)//BCD碼轉十進制函數,輸入BCD,返回十進制{ ucharDecimal; Decimal=bcd>>4; return(Decimal=Decimal*10+(bcd&=0x0F));}//voidds1302_init()//1302芯片初始化子函數(2010-01-07,12:00:00,week4){ RST=0; SCLK=0; write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x80,0x00);//向DS1302內寫秒寄存器80H寫入初始秒數據00 write_1302(0x82,0x00);//向DS1302內寫分寄存器82H寫入初始分數據00 write_1302(0x84,0x12);//向DS1302內寫小時寄存器84H寫入初始小時數據12 write_1302(0x8a,0x01);//向DS1302內寫周寄存器8aH寫入初始周數據4 write_1302(0x86,0x08);//向DS1302內寫日期寄存器86H寫入初始日期數據07 write_1302(0x88,0x07);//向DS1302內寫月份寄存器88H寫入初始月份數據01 write_1302(0x8c,0x10);//向DS1302內寫年份寄存器8cH寫入初始年份數據10 write_1302(0x8e,0x80);//打開寫保護}////溫度顯示子函數voidwrite_temp(ucharadd,uchardat)//向LCD寫溫度數據,并指定顯示位置{ uchargw,sw,bw; if(dat>=0&&dat<=128) { gw=dat%10;//取得個位數字 sw=dat%100/10;//取得十位數字 bw=dat/100 ;//取得百位數字 } else { dat=256-dat; gw=dat%10;//取得個位數字 sw=dat%100/10;//取得十位數字 bw=-3; //0x30-3表示為負號 } write_1602com(er+add);//er是頭文件規定的值0x80+0x40 write_1602dat(0x30+bw);//數字+30得到該數字的LCD1602顯示碼 write_1602dat(0x30+sw);//數字+30得到該數字的LCD1602顯示碼 write_1602dat(0x30+gw);//數字+30得到該數字的LCD1602顯示碼write_1602dat(0xdf);//顯示溫度的小圓圈符號,0xdf是液晶屏字符庫的該符號地址碼 write_1602dat(0x43); //顯示"C"符號,0x43是液晶屏字符庫里大寫C的地址碼 }////時分秒顯示子函數voidwrite_sfm(ucharadd,uchardat)//向LCD寫時分秒,有顯示位置加、現示數據,兩個參數{ uchargw,sw; gw=dat%10;//取得個位數字 sw=dat/10;//取得十位數字 write_1602com(er+add);//er是頭文件規定的值0x80+0x40 write_1602dat(0x30+sw);//數字+30得到該數字的LCD1602顯示碼 write_1602dat(0x30+gw);//數字+30得到該數字的LCD1602顯示碼 }////年月日顯示子函數voidwrite_nyr(ucharadd,uchardat)//向LCD寫年月日,有顯示位置加數、顯示數據,兩個參數{ uchargw,sw; gw=dat%10;//取得個位數字 sw=dat/10;//取得十位數字 write_1602com(yh+add);//設定顯示位置為第一個位置+add write_1602dat(0x30+sw);//數字+30得到該數字的LCD1602顯示碼 write_1602dat(0x30+gw);//數字+30得到該數字的LCD1602顯示碼 }//voidwrite_week(ucharweek)//寫星期函數{ write_1602com(yh+0x0c);//星期字符的顯示位置 switch(week) { case1: write_1602dat('M');//星期數為1時,顯示 write_1602dat('O'); write_1602dat('N'); break; case2: write_1602dat('T');//星期數據為2時顯示 write_1602dat('U'); write_1602dat('E'); break; case3: write_1602dat('W');//星期數據為3時顯示 write_1602dat('E'); write_1602dat('D'); break; case4: write_1602dat('T');//星期數據為4是顯示 write_1602dat('H'); write_1602dat('U'); break; case5: write_1602dat('F');//星期數據為5時顯示 write_1602dat('R'); write_1602dat('I'); break; case6: write_1602dat('S');//星期數據為6時顯示 write_1602dat('T'); write_1602dat('A'); break; case7: write_1602dat('S');//星期數據為7時顯示 write_1602dat('U'); write_1602dat('N'); break; }}//****************鍵盤掃描有關函數**********************voidkeyscan(){ if(key1==0)//key1為功能鍵(設置鍵) { delay(9);//延時,用于消抖動 if(key1==0)//延時后再次確認按鍵按下 { buzzer=0;//蜂鳴器短響一次 delay(20); buzzer=1; while(!key1); key1n++; if(key1n==12) key1n=1;//設置按鍵共有秒、分、時、星期、日、月、年、返回,8個功能循環 switch(key1n) { case1:TR0=0;//關閉定時器 //TR1=0; write_1602com(er+0x09);//設置按鍵按動一次,秒位置顯示光標 write_1602com(0x0f);//設置光標為閃爍 temp=(miao)/10*16+(miao)%10;//秒數據寫入DS1302 write_1302(0x8e,0x00); write_1302(0x80,0x80|temp);//miao write_1302(0x8e,0x80); break; case2:write_1602com(er+6);//按2次fen位置顯示光標 //write_1602com(0x0f); break; case3:write_1602com(er+3);//按動3次,shi //write_1602com(0x0f); break; case4:write_1602com(yh+0x0e);//按動4次,week //write_1602com(0x0f); break; case5:write_1602com(yh+0x0a);//按動5次,ri //write_1602com(0x0f); break; case6:write_1602com(yh+0x07);//按動6次,yue //write_1602com(0x0f); break; case7:write_1602com(yh+0x04);//按動7次,nian //write_1602com(0x0f); break; case8:write_1602com(er+1); write_1602dat(0x4d); write_1602com(er+1); break; case9:write_1602com(er+1); write_1602dat(0x46); write_1602com(er+1); break; case10:write_1602com(er+1); write_1602dat(0x53); write_1602com(er+1); break; case11: write_1602com(er+1); write_1602dat(0x20); write_1602com(0x0c);//按動到第8次,設置光標不閃爍 TR0=1;//打開定時器 temp=(miao)/10*16+(miao)%10; write_1302(0x8e,0x00); write_1302(0x80,0x00|temp);//miao數據寫入DS1302 write_1302(0x8e,0x80); break; } } } //加鍵key2 if(key1n!=0)//當key1按下以下。再按以下鍵才有效(按鍵次數不等于零) { if(key2==0)//上調鍵 { delay(10); if(key2==0) { buzzer=0;//蜂鳴器短響一次 delay(20); buzzer=1; while(!key2); switch(key1n) { case1: miao++;//設置鍵按動1次,調秒 if(miao==60) miao=0;//秒超過59,再加1,就歸零 write_sfm(0x08,miao);//令LCD在正確位置顯示"加"設定好的秒數 temp=(miao)/10*16+(miao)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x80,temp);//向DS1302內寫秒寄存器80H寫入調整后的秒數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(er+0x09);//因為設置液晶的模式是寫入數據后,光標自動右移,所以要指定返回 //write_1602com(0x0b); break; case2: fen++; if(fen==60) fen=0; write_sfm(0x05,fen);//令LCD在正確位置顯示"加"設定好的分數據 temp=(fen)/10*16+(fen)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x82,temp);//向DS1302內寫分寄存器82H寫入調整后的分數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(er+6);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置 break; case3: shi++; if(shi==24) shi=0; write_sfm(2,shi);//令LCD在正確的位置顯示"加"設定好的小時數據 temp=(shi)/10*16+(shi)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x84,temp);//向DS1302內寫小時寄存器84H寫入調整后的小時數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(er+3);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; case4: week++; if(week==8) week=1; write_1602com(yh+0x0C);//指定'加'后的周數據顯示位置 write_week(week);//指定周數據顯示內容 temp=(week)/10*16+(week)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x8a,temp);//向DS1302內寫周寄存器8aH寫入調整后的周數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(yh+0x0e);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; case5: ri++; switch(yue) { case1: case3: case5: case7: case8: case10: case12: if(ri>31) ri=1; break; case2: if(nian%4==0||nian%400==0) { if(ri>29) ri=1; } else { if(ri>28) ri=1; } break; case4: case6: case9: case11: ri++; if(ri>30) ri=1; break; } write_nyr(9,ri);//令LCD在正確的位置顯示"加"設定好的日期數據 temp=(ri)/10*16+(ri)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x86,temp);//向DS1302內寫日期寄存器86H寫入調整后的日期數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(yh+10);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; case6: yue++; if(yue==13) yue=1; write_nyr(6,yue);//令LCD在正確的位置顯示"加"設定好的月份數據 temp=(yue)/10*16+(yue)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x88,temp);//向DS1302內寫月份寄存器88H寫入調整后的月份數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(yh+7);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; case7: nian++; if(nian==100) nian=0; write_nyr(3,nian);//令LCD在正確的位置顯示"加"設定好的年份數據 temp=(nian)/10*16+(nian)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x8c,temp);//向DS1302內寫年份寄存器8cH寫入調整后的年份數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(yh+4);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; case8: write_1602com(er+9);//設置鬧鐘的秒定時 miao1++; if(miao1==60) miao1=0; write_sfm(0x08,miao1);//令LCD在正確位置顯示"加"設定好秒的數據 write_1602com(er+9);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置 break; case9: write_1602com(er+6);//設置鬧鐘的分鐘定時 fen1++; if(fen1==60) fen1=0; write_sfm(0x05,fen1);//令LCD在正確位置顯示"加"設定好的分數據 write_1602com(er+6);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置 break; case10:write_1602com(er+3);//設置鬧鐘的小時定時 shi1++; if(shi1==24) shi1=0; write_sfm(0x02,shi1);//令LCD在正確的位置顯示"加"設定好的小時數據 write_1602com(er+3);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; } } } //減鍵key3,各句功能參照'加鍵'注釋 if(key3==0) { delay(10);//調延時,消抖動 if(key3==0) { buzzer=0;//蜂鳴器短響一次 delay(20); buzzer=1; while(!key3); switch(key1n) { case1: miao--; if(miao==-1) miao=59;//秒數據減到-1時自動變成59 write_sfm(0x08,miao);//在LCD的正確位置顯示改變后新的秒數 temp=(miao)/10*16+(miao)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x80,temp);//向DS1302內寫秒寄存器80H寫入調整后的秒數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(er+0x09);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置 //write_1602com(0x0b); break; case2: fen--; if(fen==-1) fen=59; write_sfm(5,fen); temp=(fen)/10*16+(fen)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x82,temp);//向DS1302內寫分寄存器82H寫入調整后的分數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(er+6);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置 break; case3: shi--; if(shi==-1) shi=23; write_sfm(2,shi); temp=(shi)/10*16+(shi)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x84,temp);//向DS1302內寫小時寄存器84H寫入調整后的小時數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(er+3);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; case4: week--; if(week==0) week=7; write_1602com(yh+0x0C);//指定'加'后的周數據顯示位置 write_week(week);//指定周數據顯示內容 temp=(week)/10*16+(week)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x8a,temp);//向DS1302內寫周寄存器8aH寫入調整后的周數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(yh+0x0e);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; case5: ri--; switch(yue) { case1: case3: case5: case7: case8: case10: case12: if(ri==0) ri=31; break; case2:if(nian%4==0||nian%400==0) { if(ri==0) ri=29; } else { if(ri==0) ri=28; } break; case4: case6: case9: case11: if(ri==0) ri=30; break; } write_nyr(9,ri); temp=(ri)/10*16+(ri)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x86,temp);//向DS1302內寫日期寄存器86H寫入調整后的日期數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(yh+10);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; case6: yue--; if(yue==0) yue=12; write_nyr(6,yue); temp=(yue)/10*16+(yue)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x88,temp);//向DS1302內寫月份寄存器88H寫入調整后的月份數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(yh+7);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; case7: nian--; if(nian==-1) nian=99; write_nyr(3,nian); temp=(nian)/10*16+(nian)%10;//十進制轉換成DS1302要求的DCB碼 write_1302(0x8e,0x00);//允許寫,禁止寫保護 write_1302(0x8c,temp);//向DS1302內寫年份寄存器8cH寫入調整后的年份數據BCD碼 write_1302(0x8e,0x80);//打開寫保護 write_1602com(yh+4);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; case8: write_1602com(er+9);//設置鬧鐘的秒定時 miao1--; if(miao1==-1) miao1=59; write_sfm(0x08,miao1);//令LCD在正確位置顯示"加"設定好秒的數據 write_1602com(er+9);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置 break; case9: write_1602com(er+6);//設置鬧鐘的分鐘定時 fen1--; if(fen1==-1) fen1=59; write_sfm(0x05,fen1);//令LCD在正確位置顯示"加"設定好的分數據 write_1602com(er+6);//因為設置液晶的模式是寫入數據后,指針自動加一,在這里是寫回原來的位置 break; case10:write_1602com(er+3);//設置鬧鐘的小時定時 shi1--; if(shi1==-1) shi1=23; write_sfm(0x02,shi1);//令LCD在正確的位置顯示"加"設定好的小時數據 write_1602com(er+3);//因為設置液晶的模式是寫入數據后,指針自動加一,所以需要光標回位 break; } } } }}//定時器0初始化程序voidinit()//定時器、計數器設置函數{ TMOD=0x11;//指定定時/計數器的工作方式為1 TH0=0;//定時器T0的高四位=0 TL0=0;//定時器T0的低四位=0 EA=1;//系統允許有開放的中斷 ET0=1;//允許T0中斷 TR0=1;//開啟中斷,啟動定時器}//*******************主函數**************************//***************************************************voidmain(){ lcd_init();//調用液晶屏初始化子函數 ds1302_init();//調用DS1302時鐘的初始化子函數 init();//調用定時計數器的設置子函數 led=0;//打開LCD的背光電源buzzer=0;//蜂鳴器長響一次delay(80);buzzer=1; while(1)//無限循環下面的語句: { keyscan();//調用鍵盤掃描子函數}}/*************通過定時中斷實現定是獨處并顯示數據******************/voidt0()interrupt1//取得并顯示日歷和時間{ //Init_DS18B20();//溫度傳感器DS18b2初始化子函數,在頭文件中 flag=ReadTemperature();//將18b2頭文件運行返回的函數結果送到變量FLAG中,用于顯示 //讀取秒時分周日月年七個數據(DS1302的讀寄存器與寫寄存器不一樣): miao=BCD_Decimal(read_1302(0x81)); fen=BCD_Decimal(read_1302(0x83)); shi=BCD_Decimal(read_1302(0x85)); ri=BCD_Decimal(read_1302(0x87)); yue=BCD_Decimal(read_1302(0x89)); nian=BCD_Decimal(read_1302(0x8d)); week=BCD_Decimal(read_1302(0x8b)); //顯示溫度、秒、時、分數據: write_temp(12,flag);//顯示溫度,從第二行第12個字符后開始顯示 write_sfm(8,miao);//秒,從第二行第8個字后開始顯示(調用時分秒顯示子函數) write_sfm(5,fen);//分,從第二行第5個字符后開始顯示 write_sfm(2,shi);//小時,從第二行第2個字符后開始顯示 //顯示日、月、年數據: write_nyr(9,ri);//日期,從第二行第9個字符后開始顯示 write_nyr(6,yue);//月份,從第二行第6個字符后開始顯示 write_nyr(3,nian);//年,從第二行第3個字符后開始顯示 write_week(week); /***********整點報時程序************/ if(fen==0&&miao==0) if(shi<22&&shi>6) { buzzer=0;//蜂鳴器短響一次 delay(20); buzzer=1; } /**************鬧鐘程序:將暫停鍵按下停止蜂鳴********************/ if(shi1==shi&&fen1==fen&&miao==0) { clock=1; } if(clock==1) { buzzer=0;//蜂鳴器短響一次 delay(20); buzzer=1; } if(CLO==0) /*按下p1.4停止蜂鳴*/ clock=0; }typedefunsignedcharuchar;typedefunsignedintuint;sbitDQ=P3^3;//定義DQ引腳為P3.3/*******************************延時函數*********************************功能:在11.059MHz的晶振條件下調用本函數需要24μs,然后每次計數需16μs**************************************************************************/voidDS18_delay(intuseconds){ ints; for(s=0;s<useconds;s++);}/*******************************復位函數********************************功能:完成單總線的復位操作。*復位時間為480μs,因此延時時間為(480-24)/16=28.5,取29μs。*經過70μs之后檢測存在脈沖,因此延時時間為(70-24)/16=2.875,取3μs。**********************************************************************

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論