国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

stm32畢業(yè)設(shè)計(jì) 電子時(shí)鐘設(shè)計(jì)與實(shí)現(xiàn)

這篇具有很好參考價(jià)值的文章主要介紹了stm32畢業(yè)設(shè)計(jì) 電子時(shí)鐘設(shè)計(jì)與實(shí)現(xiàn)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


單片機(jī)電子時(shí)鐘程序設(shè)計(jì)

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

選題指導(dǎo),項(xiàng)目分享:

https://gitee.com/yaa-dc/warehouse-1/blob/master/iot/README.md文章來源地址http://www.zghlxwxcb.cn/news/detail-478020.html

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

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

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

  • 定義一個(gè)變量 setIndex 來控制當(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 對應(yīng)位置上進(jìn)行光標(biāo)閃爍,所以 Lcd1602.c 在之前文件的基礎(chǔ)上添加了兩個(gè)控制光標(biāo)的函數(shù);

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

/***************************DS1302.c 文件程序源代碼*****************************/
#include <reg52.h>

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

/***************************Lcd1602.c 文件程序源代碼*****************************/
#include <reg52.h>
#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ù)檢測直到其等于 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)-對應(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{
        addr = 0x40 + x; //第二行字符地址從 0x40 起始
    }
    LcdWriteCmd(addr | 0x80); //設(shè)置 RAM 地址
}
/* 在液晶上顯示字符串,(x,y)-對應(yīng)屏幕上的起始坐標(biāo),str-字符串指針 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str){
    LcdSetCursor(x, y); //設(shè)置起始地址
    while (*str != '\0'){ //連續(xù)寫入字符串?dāng)?shù)據(jù),直到檢測到結(jié)束符
        LcdWriteDat(*str++);
    }
}
/* 打開光標(biāo)的閃爍效果 */
void LcdOpenCursor(){
    LcdWriteCmd(0x0F);
}
/* 關(guān)閉光標(biāo)顯示 */
void LcdCloseCursor(){
    LcdWriteCmd(0x0C);
}
/* 初始化 1602 液晶 */
void InitLcd1602(){
    LcdWriteCmd(0x38); //16*2 顯示,5*7 點(diǎn)陣,8 位數(shù)據(jù)接口
    LcdWriteCmd(0x0C); //顯示器開,光標(biāo)關(guān)閉
    LcdWriteCmd(0x06); //文字不動(dòng),地址自動(dòng)+1
    LcdWriteCmd(0x01); //清屏
}

實(shí)現(xiàn)效果

stm32畢業(yè)設(shè)計(jì) 電子時(shí)鐘設(shè)計(jì)與實(shí)現(xiàn)
stm32畢業(yè)設(shè)計(jì) 電子時(shí)鐘設(shè)計(jì)與實(shí)現(xiàn)

stm32畢業(yè)設(shè)計(jì) 電子時(shí)鐘設(shè)計(jì)與實(shí)現(xiàn)


**選題指導(dǎo),項(xiàng)目分享:**

https://gitee.com/yaa-dc/warehouse-1/blob/master/iot/README.md

到了這里,關(guān)于stm32畢業(yè)設(shè)計(jì) 電子時(shí)鐘設(shè)計(jì)與實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包