日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]共用體除非必要,否則我們不推薦使用,枚舉的用法比較簡(jiǎn)單,在本書 19 章的項(xiàng)目實(shí)踐中有很好的示例,這節(jié)課我們先來(lái)練習(xí)一下結(jié)構(gòu)體的使用。下邊這個(gè)程序的功能是一個(gè)帶日期的電子鐘,相當(dāng)于一個(gè)簡(jiǎn)易萬(wàn)年歷了,并且加

共用體除非必要,否則我們不推薦使用,枚舉的用法比較簡(jiǎn)單,在本書 19 章的項(xiàng)目實(shí)踐中有很好的示例,這節(jié)課我們先來(lái)練習(xí)一下結(jié)構(gòu)體的使用。下邊這個(gè)程序的功能是一個(gè)帶日期的電子鐘,相當(dāng)于一個(gè)簡(jiǎn)易萬(wàn)年歷了,并且加入了按鍵調(diào)時(shí)功能。學(xué)有余力的同學(xué)看到這里,不妨先不看我們提供的代碼,自己寫寫試試。如果能夠獨(dú)立寫一個(gè)按鍵可調(diào)的萬(wàn)年歷程序,單片機(jī)可以說(shuō)基本入門了。如果自己還不能夠獨(dú)立完成這個(gè)程序,那么還是老規(guī)矩,先抄并且理解,而后自己獨(dú)立默寫出來(lái),并且要邊默寫邊理解。


本例直接忽略了星期這項(xiàng)內(nèi)容,通過(guò)上、下、左、右、回車、ESC 這 6 個(gè)按鍵可以調(diào)整時(shí)間。這也是一個(gè)具有綜合練習(xí)性質(zhì)的實(shí)例,雖然在功能實(shí)現(xiàn)上沒(méi)有多少難度,但要進(jìn)行的操作卻比較多而且煩瑣,同學(xué)們可以從中體會(huì)到把繁雜的功能實(shí)現(xiàn)分解為一步步函數(shù)操作的必要性以及方便靈活性。簡(jiǎn)單說(shuō)一下這個(gè)程序的幾個(gè)要點(diǎn),方便大家閱讀理解程序。

把 DS1302 的底層操作封裝為一個(gè) DS1302.c 文件,對(duì)上層應(yīng)用提供基本的實(shí)時(shí)時(shí)間的操作接口,這個(gè)文件也是我們的又一個(gè)功能模塊了,我們的積累也越來(lái)越多了。

定義一個(gè)結(jié)構(gòu)體類型 sTime 用來(lái)封裝日期時(shí)間的各個(gè)元素,又用該結(jié)構(gòu)體定義了一個(gè)時(shí)間緩沖區(qū)變量 bufTime 來(lái)暫存從 DS1302 讀出的時(shí)間和設(shè)置時(shí)間時(shí)的設(shè)定值。需要注意的是在其它文件中要使用這個(gè)結(jié)構(gòu)體變量時(shí),必須首先再聲明一次 sTime 類型;

定義一個(gè)變量 setIndex 來(lái)控制當(dāng)前是否處于設(shè)置時(shí)間的狀態(tài),以及設(shè)置時(shí)間的哪一位,該值為 0 就表示正常運(yùn)行,1~12 分別代表可以修改日期時(shí)間的 12 個(gè)位;

由于這節(jié)課的程序功能要進(jìn)行時(shí)間調(diào)整,用到了 1602 液晶的光標(biāo)功能,添加了設(shè)置光標(biāo)的函數(shù),我們要改變哪一位的數(shù)字,就在 1602 對(duì)應(yīng)位置上進(jìn)行光標(biāo)閃爍,所以 Lcd1602.c在之前文件的基礎(chǔ)上添加了兩個(gè)控制光標(biāo)的函數(shù);

時(shí)間的顯示、增減、設(shè)置移位等上層功能函數(shù)都放在 main.c 中來(lái)實(shí)現(xiàn),當(dāng)按鍵需要這些函數(shù)時(shí)則在按鍵文件中做外部聲明,這樣做是為了避免一組功能函數(shù)分散在不同的文件內(nèi)而使程序顯得凌亂。

/***************************DS1302.c 文件程序源代碼*****************************/

#include

sbit DS1302_CE = P1^7;

sbit DS1302_CK = P3^5;

sbit DS1302_IO = P3^4;

struct sTime { //日期時(shí)間結(jié)構(gòu)體定義

unsigned int year; //年

unsigned char mon; //月

unsigned char day; //日

unsigned char hour; //時(shí)

unsigned char min; //分

unsigned char sec; //秒

unsigned char week; //星期

};

/* 發(fā)送一個(gè)字節(jié)到 DS1302 通信總線上 */

void DS1302ByteWrite(unsigned char dat){

unsigned char mask;

for (mask=0x01; mask!=0; mask<<=1){ //低位在前,逐位移出

if ((mask&dat) != 0){ //首先輸出該位數(shù)據(jù)

DS1302_IO = 1;

}else{

DS1302_IO = 0;

}

DS1302_CK = 1; //然后拉高時(shí)鐘

DS1302_CK = 0; //再拉低時(shí)鐘,完成一個(gè)位的操作

}

DS1302_IO = 1; //最后確保釋放 IO 引腳

}

/* 由 DS1302 通信總線上讀取一個(gè)字節(jié) */

unsigned char DS1302ByteRead(){

unsigned char mask;

unsigned char dat = 0;

for (mask=0x01; mask!=0; mask<<=1){ //低位在前,逐位讀取

if (DS1302_IO != 0){ //首先讀取此時(shí)的 IO 引腳,并設(shè)置 dat 中的對(duì)應(yīng)位

dat |= mask;

}

DS1302_CK = 1; //然后拉高時(shí)鐘

DS1302_CK = 0; //再拉低時(shí)鐘,完成一個(gè)位的操作

}

return dat; //最后返回讀到的字節(jié)數(shù)據(jù)

}

/* 用單次寫操作向某一寄存器寫入一個(gè)字節(jié),reg-寄存器地址,dat-待寫入字節(jié) */

void DS1302SingleWrite(unsigned char reg, unsigned char dat){

DS1302_CE = 1; //使能片選信號(hào)

DS1302ByteWrite((reg<<1)|0x80); //發(fā)送寫寄存器指令

DS1302ByteWrite(dat); //寫入字節(jié)數(shù)據(jù)

DS1302_CE = 0; //除能片選信號(hào)

}

/* 用單次讀操作從某一寄存器讀取一個(gè)字節(jié),reg-寄存器地址,返回值-讀到的字節(jié) */

unsigned char DS1302SingleRead(unsigned char reg){

unsigned char dat;

DS1302_CE = 1; //使能片選信號(hào)

DS1302ByteWrite((reg<<1)|0x81); //發(fā)送讀寄存器指令

dat = DS1302ByteRead(); //讀取字節(jié)數(shù)據(jù)

DS1302_CE = 0; //除能片選信號(hào)

return dat;

}

/* 用突發(fā)模式連續(xù)寫入 8 個(gè)寄存器數(shù)據(jù),dat-待寫入數(shù)據(jù)指針 */

void DS1302BurstWrite(unsigned char *dat){

unsigned char i;

DS1302_CE = 1;

DS1302ByteWrite(0xBE); //發(fā)送突發(fā)寫寄存器指令

for (i=0; i<8; i++){ //連續(xù)寫入 8 字節(jié)數(shù)據(jù)

DS1302ByteWrite(dat[i]);

}

DS1302_CE = 0;

}

/* 用突發(fā)模式連續(xù)讀取 8 個(gè)寄存器的數(shù)據(jù),dat-讀取數(shù)據(jù)的接收指針 */

void DS1302BurstRead(unsigned char *dat){

unsigned char i;

DS1302_CE = 1;

DS1302ByteWrite(0xBF); //發(fā)送突發(fā)讀寄存器指令

for (i=0; i<8; i++){ //連續(xù)讀取 8 個(gè)字節(jié)

dat[i] = DS1302ByteRead();

}

DS1302_CE = 0;

}

/* 獲取實(shí)時(shí)時(shí)間,即讀取 DS1302 當(dāng)前時(shí)間并轉(zhuǎn)換為時(shí)間結(jié)構(gòu)體格式 */

void GetRealTime(struct sTime *time){

unsigned char buf[8];

DS1302BurstRead(buf);

time->year = buf[6] + 0x2000;

time->mon = buf[4];

time->day = buf[3];

time->hour = buf[2];

time->min = buf[1];

time->sec = buf[0];

time->week = buf[5];

}

/* 設(shè)定實(shí)時(shí)時(shí)間,時(shí)間結(jié)構(gòu)體格式的設(shè)定時(shí)間轉(zhuǎn)換為數(shù)組并寫入 DS1302 */

void SetRealTime(struct sTime *time){

unsigned char buf[8];

buf[7] = 0;

buf[6] = time->year;

buf[5] = time->week;

buf[4] = time->mon;

buf[3] = time->day;

buf[2] = time->hour;

buf[1] = time->min;

buf[0] = time->sec;

DS1302BurstWrite(buf);

}

/* DS1302 初始化,如發(fā)生掉電則重新設(shè)置初始時(shí)間 */

void InitDS1302(){

unsigned char dat;

struct sTime code InitTime[] = { //2013 年 10 月 8 日 12:30:00 星期二

0x2013,0x10,0x08, 0x12,0x30,0x00, 0x02

};

DS1302_CE = 0; //初始化 DS1302 通信引腳

DS1302_CK = 0;

dat = DS1302SingleRead(0); //讀取秒寄存器

if ((dat & 0x80) != 0){ //由秒寄存器最高位 CH 的值判斷 DS1302 是否已停止

DS1302SingleWrite(7, 0x00); //撤銷寫保護(hù)以允許寫入數(shù)據(jù)

SetRealTime(&InitTime); //設(shè)置 DS1302 為默認(rèn)的初始時(shí)間

}

}

DS1302.c 最終向外提供出與具體時(shí)鐘芯片寄存器位置無(wú)關(guān)的、由時(shí)間結(jié)構(gòu)類型 sTime 作為接口的實(shí)時(shí)時(shí)間的讀取和設(shè)置函數(shù),如此處理體現(xiàn)了我們前面提到過(guò)的層次化編程的思想。應(yīng)用層可以不關(guān)心底層實(shí)現(xiàn)細(xì)節(jié),底層實(shí)現(xiàn)的改變也不會(huì)對(duì)應(yīng)用層造成影響,比如說(shuō)日后你可能需要換一款時(shí)鐘芯片,而它與 DS1302 的操作和時(shí)間寄存器順序是不同的,那么你需要做的也僅是針對(duì)這款新的時(shí)鐘芯片設(shè)計(jì)出底層操作函數(shù),最終提供出同樣的以 sTime 為接口的操作函數(shù)即可,應(yīng)用層無(wú)需做任何的改動(dòng)。

/***************************Lcd1602.c 文件程序源代碼*****************************/

#include

#define LCD1602_DB P0

sbit LCD1602_RS = P1^0;

sbit LCD1602_RW = P1^1;

sbit LCD1602_E = P1^5;

/* 等待液晶準(zhǔn)備好 */

void LcdWaitReady(){

unsigned char sta;

LCD1602_DB = 0xFF;

LCD1602_RS = 0;

LCD1602_RW = 1;

do {

LCD1602_E = 1;

sta = LCD1602_DB; //讀取狀態(tài)字

LCD1602_E = 0;

} while (sta & 0x80); //bit7 等于 1 表示液晶正忙,重復(fù)檢測(cè)直到其等于 0 為止

}

/* 向 LCD1602 液晶寫入一字節(jié)命令,cmd-待寫入命令值 */

void LcdWriteCmd(unsigned char cmd){

LcdWaitReady();

LCD1602_RS = 0;

LCD1602_RW = 0;

LCD1602_DB = cmd;

LCD1602_E = 1;

LCD1602_E = 0;

}

/* 向 LCD1602 液晶寫入一字節(jié)數(shù)據(jù),dat-待寫入數(shù)據(jù)值 */

void LcdWriteDat(unsigned char dat){

LcdWaitReady();

LCD1602_RS = 1;

LCD1602_RW = 0;

LCD1602_DB = dat;

LCD1602_E = 1;

LCD1602_E = 0;

}

/* 設(shè)置顯示 RAM 起始地址,亦即光標(biāo)位置,(x,y)-對(duì)應(yīng)屏幕上的字符坐標(biāo) */

void LcdSetCursor(unsigned char x, unsigned char y){

unsigned char addr;

if (y == 0){ //由輸入的屏幕坐標(biāo)計(jì)算顯示 RAM 的地址

addr = 0x00 + x; //第一行字符地址從 0x00 起始

}else{

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

8位單片機(jī)在嵌入式設(shè)計(jì)領(lǐng)域已經(jīng)成為半個(gè)多世紀(jì)以來(lái)的主流選擇。盡管嵌入式系統(tǒng)市場(chǎng)日益復(fù)雜,8位單片機(jī)依然不斷發(fā)展,積極應(yīng)對(duì)新的挑戰(zhàn)和系統(tǒng)需求。如今,Microchip推出的8位PIC?和AVR?單片機(jī)系列,配備了先進(jìn)的獨(dú)立...

關(guān)鍵字: 單片機(jī) 嵌入式 CPU

在嵌入式系統(tǒng)開(kāi)發(fā)中,程序燒錄是連接軟件設(shè)計(jì)與硬件實(shí)現(xiàn)的關(guān)鍵環(huán)節(jié)。當(dāng)前主流的單片機(jī)燒錄技術(shù)已形成ICP(在電路編程)、ISP(在系統(tǒng)編程)、IAP(在應(yīng)用編程)三大技術(shù)體系,分別對(duì)應(yīng)開(kāi)發(fā)調(diào)試、量產(chǎn)燒錄、遠(yuǎn)程升級(jí)等不同場(chǎng)景。...

關(guān)鍵字: 單片機(jī) ISP ICP IAP 嵌入式系統(tǒng)開(kāi)發(fā)

在嵌入式系統(tǒng)開(kāi)發(fā)中,看門狗(Watchdog Timer, WDT)是保障系統(tǒng)可靠性的核心組件,其初始化時(shí)機(jī)的選擇直接影響系統(tǒng)抗干擾能力和穩(wěn)定性。本文從硬件架構(gòu)、軟件流程、安全規(guī)范三個(gè)維度,系統(tǒng)分析看門狗初始化的最佳實(shí)踐...

關(guān)鍵字: 單片機(jī) 看門狗 嵌入式系統(tǒng)

本文中,小編將對(duì)單片機(jī)予以介紹,如果你想對(duì)它的詳細(xì)情況有所認(rèn)識(shí),或者想要增進(jìn)對(duì)它的了解程度,不妨請(qǐng)看以下內(nèi)容哦。

關(guān)鍵字: 單片機(jī) 開(kāi)發(fā)板 Keil

隨著單片機(jī)系統(tǒng)越來(lái)越廣泛地應(yīng)用于消費(fèi)類電子、醫(yī)療、工業(yè)自動(dòng)化、智能化儀器儀表、航空航天等各領(lǐng)域,單片機(jī)系統(tǒng)面臨著電磁干擾(EMI)日益嚴(yán)重的威脅。電磁兼容性(EMC)包含系統(tǒng)的發(fā)射和敏感度兩方面的問(wèn)題。

關(guān)鍵字: 單片機(jī) 電磁兼容

以下內(nèi)容中,小編將對(duì)單片機(jī)的相關(guān)內(nèi)容進(jìn)行著重介紹和闡述,希望本文能幫您增進(jìn)對(duì)單片機(jī)的了解,和小編一起來(lái)看看吧。

關(guān)鍵字: 單片機(jī) 復(fù)位電路

在這篇文章中,小編將為大家?guī)?lái)單片機(jī)的相關(guān)報(bào)道。如果你對(duì)本文即將要講解的內(nèi)容存在一定興趣,不妨繼續(xù)往下閱讀哦。

關(guān)鍵字: 單片機(jī) 異常復(fù)位

今天,小編將在這篇文章中為大家?guī)?lái)單片機(jī)的有關(guān)報(bào)道,通過(guò)閱讀這篇文章,大家可以對(duì)它具備清晰的認(rèn)識(shí),主要內(nèi)容如下。

關(guān)鍵字: 單片機(jī) 仿真器

單片機(jī)將是下述內(nèi)容的主要介紹對(duì)象,通過(guò)這篇文章,小編希望大家可以對(duì)它的相關(guān)情況以及信息有所認(rèn)識(shí)和了解,詳細(xì)內(nèi)容如下。

關(guān)鍵字: 單片機(jī) 中斷 boot

一直以來(lái),單片機(jī)都是大家的關(guān)注焦點(diǎn)之一。因此針對(duì)大家的興趣點(diǎn)所在,小編將為大家?guī)?lái)單片機(jī)的相關(guān)介紹,詳細(xì)內(nèi)容請(qǐng)看下文。

關(guān)鍵字: 單片機(jī) 數(shù)字信號(hào) 模擬信號(hào)
關(guān)閉