找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1620|回復(fù): 4
收起左側(cè)

單片機(jī)+ds1302寫字節(jié)不是上升沿嗎,這里是下降沿?

[復(fù)制鏈接]
ID:880294 發(fā)表于 2021-7-5 20:50 來自手機(jī) | 顯示全部樓層 |閱讀模式
程序出自 手把手教你學(xué)51單片機(jī)

#include <reg52.h>

sbit DS1302_CE = P1^7;
sbit DS1302_CK = P3^5;
sbit DS1302_IO = P3^4;

bit flag200ms = 0;       //200ms定時(shí)標(biāo)志
unsigned char T0RH = 0;  //T0重載值的高字節(jié)
unsigned char T0RL = 0;  //T0重載值的低字節(jié)

void ConfigTimer0(unsigned int ms);
void InitDS1302();
unsigned char DS1302SingleRead(unsigned char reg);
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);

void main()
{
    unsigned char i;
    unsigned char psec=0xAA;  //秒備份,初值A(chǔ)A確保首次讀取時(shí)間后會(huì)刷新顯示
    unsigned char time[8];    //當(dāng)前時(shí)間數(shù)組
    unsigned char str[12];    //字符串轉(zhuǎn)換緩沖區(qū)

    EA = 1;           //開總中斷
    ConfigTimer0(1);  //T0定時(shí)1ms
    InitDS1302();     //初始化實(shí)時(shí)時(shí)鐘
    InitLcd1602();    //初始化液晶
   
    while (1)
    {
        if (flag200ms)  //每200ms讀取依次時(shí)間
        {
            flag200ms = 0;
            for (i=0; i<7; i++)  //讀取DS1302當(dāng)前時(shí)間
            {
                time[ i] = DS1302SingleRead(i);
            }
            if (psec != time[0]) //檢測(cè)到時(shí)間有變化時(shí)刷新顯示
            {
                str[0] = '2';  //添加年份的高2位:20
                str[1] = '0';
                str[2] = (time[6] >> 4) + '0';  //“年”高位數(shù)字轉(zhuǎn)換為ASCII碼
                str[3] = (time[6]&0x0F) + '0';  //“年”低位數(shù)字轉(zhuǎn)換為ASCII碼
                str[4] = '-';  //添加日期分隔符
                str[5] = (time[4] >> 4) + '0';  //“月”
                str[6] = (time[4]&0x0F) + '0';
                str[7] = '-';
                str[8] = (time[3] >> 4) + '0';  //“日”
                str[9] = (time[3]&0x0F) + '0';
                str[10] = '\0';
                LcdShowStr(0, 0, str);  //顯示到液晶的第一行
               
                str[0] = (time[5]&0x0F) + '0';  //“星期”
                str[1] = '\0';
                LcdShowStr(11, 0, "week");
                LcdShowStr(15, 0, str);  //顯示到液晶的第一行
               
                str[0] = (time[2] >> 4) + '0';  //“時(shí)”
                str[1] = (time[2]&0x0F) + '0';
                str[2] = ':';  //添加時(shí)間分隔符
                str[3] = (time[1] >> 4) + '0';  //“分”
                str[4] = (time[1]&0x0F) + '0';
                str[5] = ':';
                str[6] = (time[0] >> 4) + '0';  //“秒”
                str[7] = (time[0]&0x0F) + '0';
                str[8] = '\0';
                LcdShowStr(4, 1, str);  //顯示到液晶的第二行
               
                psec = time[0];  //用當(dāng)前值更新上次秒數(shù)
            }
        }
    }
}
/* 發(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;
}
/* DS1302初始化,如發(fā)生掉電則重新設(shè)置初始時(shí)間 */
void InitDS1302()
{
    unsigned char i;
    unsigned char code InitTime[] = {  //2013年10月8日 星期二 12:30:00
        0x00,0x30,0x12, 0x08, 0x10, 0x02, 0x13
    };
   
    DS1302_CE = 0;  //初始化DS1302通信引腳
    DS1302_CK = 0;
    i = DS1302SingleRead(0);  //讀取秒寄存器
    if ((i & 0x80) != 0)      //由秒寄存器最高位CH的值判斷DS1302是否已停止
    {
        DS1302SingleWrite(7, 0x00);  //撤銷寫保護(hù)以允許寫入數(shù)據(jù)
        for (i=0; i<7; i++)          //設(shè)置DS1302為默認(rèn)的初始時(shí)間
        {
            DS1302SingleWrite(i, InitTime[ i]);
        }
    }
}
/* 配置并啟動(dòng)T0,ms-T0定時(shí)時(shí)間 */
void ConfigTimer0(unsigned int ms)
{
    unsigned long tmp;  //臨時(shí)變量
   
    tmp = 11059200 / 12;      //定時(shí)器計(jì)數(shù)頻率
    tmp = (tmp * ms) / 1000;  //計(jì)算所需的計(jì)數(shù)值
    tmp = 65536 - tmp;        //計(jì)算定時(shí)器重載值
    tmp = tmp + 12;           //補(bǔ)償中斷響應(yīng)延時(shí)造成的誤差
    T0RH = (unsigned char)(tmp>>8);  //定時(shí)器重載值拆分為高低字節(jié)
    T0RL = (unsigned char)tmp;
    TMOD &= 0xF0;   //清零T0的控制位
    TMOD |= 0x01;   //配置T0為模式1
    TH0 = T0RH;     //加載T0重載值
    TL0 = T0RL;
    ET0 = 1;        //使能T0中斷
    TR0 = 1;        //啟動(dòng)T0
}
/* T0中斷服務(wù)函數(shù),執(zhí)行200ms定時(shí) */
void InterruptTimer0() interrupt 1
{
    static unsigned char tmr200ms = 0;
   
    TH0 = T0RH;  //重新加載重載值
    TL0 = T0RL;
    tmr200ms++;
    if (tmr200ms >= 200)  //定時(shí)200ms
    {
        tmr200ms = 0;
        flag200ms = 1;
    }
}
回復(fù)

使用道具 舉報(bào)

ID:752974 發(fā)表于 2021-7-6 08:28 | 顯示全部樓層
仔細(xì)看看IIC總線協(xié)議,注意IIC總線的啟動(dòng),停止,數(shù)據(jù)讀寫等對(duì)時(shí)序的要求。
回復(fù)

使用道具 舉報(bào)

ID:401564 發(fā)表于 2021-7-6 15:01 | 顯示全部樓層
注意這里,在初始化的時(shí)候,時(shí)鐘線CK就是0了
在這1變成0
實(shí)際上數(shù)據(jù)端口是經(jīng)歷了一個(gè)上升沿和一個(gè)下降沿的,自己分析一下這循環(huán)就知道了
一般的程序是不會(huì)管你上升沿還下降沿輸入的,數(shù)據(jù)會(huì)經(jīng)歷一個(gè)完整的上升和下降沿的
20210706145630.png

回復(fù)

使用道具 舉報(bào)

ID:390416 發(fā)表于 2021-7-6 20:34 | 顯示全部樓層
STC8單片機(jī)+DS1302+DS18B20+74HC595的LED16x32點(diǎn)陣溫度萬年歷源代碼分享 http://www.torrancerestoration.com/bbs/dpj-200968-1.html
回復(fù)

使用道具 舉報(bào)

ID:390416 發(fā)表于 2021-7-6 20:35 | 顯示全部樓層
STC8單片機(jī)+DS1302+DS18B20+74HC595的LED16x32點(diǎn)陣溫度萬年歷源代碼分享 http://www.torrancerestoration.com/bbs/dpj-200968-1.html
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表