• 51单片机学习:DS1302时钟实验


    实验名称:DS1302时钟实验
    接线说明:    
    实验现象:下载程序后,数码管上显示电子时钟时分秒,格式为“XX-XX-XX”
    注意事项:                                                                                  
    ***************************************************************************************/
    #include "public.h"
    #include "smg.h"
    #include "ds1302.h"


    /*******************************************************************************
    * 函 数 名       : main
    * 函数功能         : 主函数
    * 输    入       : 无
    * 输    出         : 无
    *******************************************************************************/
    void main()
    {    
        u8 time_buf[8];
        
        ds1302_init();//初始化DS1302

        while(1)
        {                
            ds1302_read_time();
            time_buf[0]=gsmg_code[gDS1302_TIME[2]/16];
            time_buf[1]=gsmg_code[gDS1302_TIME[2]&0x0f];
            time_buf[2]=0x40;
            time_buf[3]=gsmg_code[gDS1302_TIME[1]/16];
            time_buf[4]=gsmg_code[gDS1302_TIME[1]&0x0f];
            time_buf[5]=0x40;
            time_buf[6]=gsmg_code[gDS1302_TIME[0]/16];
            time_buf[7]=gsmg_code[gDS1302_TIME[0]&0x0f];
            smg_display(time_buf,1);
        }        
    }

    #include "ds1302.h"
    #include "intrins.h"

    //---DS1302写入和读取时分秒的地址命令---//
    //---秒分时日月周年 最低位读写位;-------//
    u8 gREAD_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 
    u8 gWRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

    //---DS1302时钟初始化2021年5月20日星期四13点51分47秒。---//
    //---存储顺序是秒分时日月周年,存储格式是用BCD码---//
    u8 gDS1302_TIME[7] = {0x47, 0x51, 0x13, 0x20, 0x04, 0x05, 0x21};


    /*******************************************************************************
    * 函 数 名       : ds1302_write_byte
    * 函数功能         : DS1302写单字节
    * 输    入       : addr:地址/命令
                       dat:数据
    * 输    出         : 无
    *******************************************************************************/
    void ds1302_write_byte(u8 addr,u8 dat)
    {
        u8 i=0;
        
        DS1302_RST=0;
        _nop_();    
        DS1302_CLK=0;//CLK低电平
        _nop_();
        DS1302_RST=1;//RST由低到高变化
        _nop_();

        for(i=0;i<8;i++)//循环8次,每次写1位,先写低位再写高位
        {
            DS1302_IO=addr&0x01;
            addr>>=1;
            DS1302_CLK=1;
            _nop_();
            DS1302_CLK=0;//CLK由低到高产生一个上升沿,从而写入数据
            _nop_();        
        }
        for(i=0;i<8;i++)//循环8次,每次写1位,先写低位再写高位
        {
            DS1302_IO=dat&0x01;
            dat>>=1;
            DS1302_CLK=1;
            _nop_();
            DS1302_CLK=0;
            _nop_();        
        }
        DS1302_RST=0;//RST拉低
        _nop_();    
    }

    /*******************************************************************************
    * 函 数 名       : ds1302_read_byte
    * 函数功能         : DS1302读单字节
    * 输    入       : addr:地址/命令
    * 输    出         : 读取的数据
    *******************************************************************************/
    u8 ds1302_read_byte(u8 addr)
    {
        u8 i=0;
        u8 temp=0;
        u8 value=0;

        DS1302_RST=0;
        _nop_();    
        DS1302_CLK=0;//CLK低电平
        _nop_();
        DS1302_RST=1;//RST由低到高变化
        _nop_();
        
        for(i=0;i<8;i++)//循环8次,每次写1位,先写低位再写高位
        {
            DS1302_IO=addr&0x01;
            addr>>=1;    
            DS1302_CLK=1;
            _nop_();
            DS1302_CLK=0;//CLK由低到高产生一个上升沿,从而写入数据
            _nop_();        
        }
        for(i=0;i<8;i++)//循环8次,每次读1位,先读低位再读高位
        {
            temp=DS1302_IO;
            value=(temp<<7)|(value>>1);//先将value右移1位,然后temp左移7位,最后或运算
            DS1302_CLK=1;
            _nop_();
            DS1302_CLK=0;
            _nop_();        
        }
        DS1302_RST=0;//RST拉低
        _nop_();    
        DS1302_CLK=1;//对于实物中,P3.4口没有外接上拉电阻的,此处代码需要添加,使数据口有一个上升沿脉冲。
        _nop_();
        DS1302_IO = 0;
        _nop_();
        DS1302_IO = 1;
        _nop_();    
        return value;        
    }

    /*******************************************************************************
    * 函 数 名       : ds1302_init
    * 函数功能         : DS1302初始化时间
    * 输    入       : 无
    * 输    出         : 无
    *******************************************************************************/
    void ds1302_init(void)
    {
        u8 i=0;
        ds1302_write_byte(0x8E,0X00);
        for(i=0;i<7;i++)
        {
            ds1302_write_byte(gWRITE_RTC_ADDR[i],gDS1302_TIME[i]);    
        }
        ds1302_write_byte(0x8E,0X80);    
    }

    /*******************************************************************************
    * 函 数 名       : ds1302_read_time
    * 函数功能         : DS1302读取时间
    * 输    入       : 无
    * 输    出         : 无
    *******************************************************************************/
    void ds1302_read_time(void)
    {
        u8 i=0;
        for(i=0;i<7;i++)
        {
            gDS1302_TIME[i]=ds1302_read_byte(gREAD_RTC_ADDR[i]);    
        }    
    }
     

    #include "smg.h"

    //共阴极数码管显示0~F的段码数据
    u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                    0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

    /*******************************************************************************
    * 函 数 名       : smg_display
    * 函数功能         : 动态数码管显示
    * 输    入       : dat:要显示的数据
                       pos:从左开始第几个位置开始显示,范围1-8
    * 输    出         : 无
    *******************************************************************************/
    void smg_display(u8 dat[],u8 pos)
    {
        u8 i=0;
        u8 pos_temp=pos-1;

        for(i=pos_temp;i<8;i++)
        {
               switch(i)//位选
            {
                case 0: LSC=1;LSB=1;LSA=1;break;
                case 1: LSC=1;LSB=1;LSA=0;break;
                case 2: LSC=1;LSB=0;LSA=1;break;
                case 3: LSC=1;LSB=0;LSA=0;break;
                case 4: LSC=0;LSB=1;LSA=1;break;
                case 5: LSC=0;LSB=1;LSA=0;break;
                case 6: LSC=0;LSB=0;LSA=1;break;
                case 7: LSC=0;LSB=0;LSA=0;break;
            }
            SMG_A_DP_PORT=dat[i-pos_temp];//传送段选数据
            delay_10us(100);//延时一段时间,等待显示稳定
            SMG_A_DP_PORT=0x00;//消音
        }
    }
     

    #include "public.h"

    /*******************************************************************************
    * 函 数 名       : delay_10us
    * 函数功能         : 延时函数,ten_us=1时,大约延时10us
    * 输    入       : ten_us
    * 输    出         : 无
    *******************************************************************************/
    void delay_10us(u16 ten_us)
    {
        while(ten_us--);    
    }

    /*******************************************************************************
    * 函 数 名       : delay_ms
    * 函数功能         : ms延时函数,ms=1时,大约延时1ms
    * 输    入       : ms:ms延时时间
    * 输    出         : 无
    *******************************************************************************/
    void delay_ms(u16 ms)
    {
        u16 i,j;
        for(i=ms;i>0;i--)
            for(j=110;j>0;j--);
    }

    纷传单片机学习资料放在纷传小程序里了,需要的可以加入圈子有资料百度网盘下载地址及提取码。

  • 相关阅读:
    最新CLion + STM32 + CubeMX 开发环境搭建
    echart 三角形柱状图
    [纯理论] FCOS
    十分钟教会你如何使用VitePress搭建及部署个人博客站点
    遥感图像应用:在低分辨率图像上实现洪水损害检测
    分布式搜索引擎 ElasticSearch(ES)
    【MATLAB】绘制柱状图、设置照明方式
    Java异常机制
    高性能MySQL实战第11讲:如何做到MySQL高扩展性?
    深度学习模型部署与优化:策略与实践;L40S与A100、H100的对比分析
  • 原文地址:https://blog.csdn.net/qq_63964231/article/details/126917054