使用DS1302模块参加蓝桥杯单片机比赛

文章目录

  • 一、DS1302基础知识
  • 二、实际使用
  • 1.蓝桥杯小蜜蜂讲解
  • 2.官方给的示例
  • 总结

  • 一、DS1302基础知识

    大家查阅单片机的芯片手册可以看到DS1302 的电路图

     一、DS1302是时钟芯片,有12个寄存器,其中7个寄存器和日历、时钟相关,DS1302使用BCD码存放数据。

      二、DS1302在官方给出的比赛指导书里面有很详细的描述,但是根据我自己的理解,分成控制字节、读操作和写操作三块。

    1、根据指导书里的内容,可以得DS1302的控制字格式如下

    BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
    1 1:RAM 0:CK A4 A3 A2 A1 A0 1:RD 0:WR

    BIT7=1时才能写入数据;
    BIT6:0表示存取日历时钟数据,BIT5~BIT1:表示操作单元的地址
    2、读操作:看下时序图,读操作的时候SCLK是下降沿锁存数据。因而同法可得,写操作SCLK是上升沿所存数据,这也说明在实际读取一个数据的时候,需要有一个由高到低的跳变过程,才能读取成功。
    3、DS1302的基本操作:(1)设定时间参数;(2)读取实时时间
    4、解释下DS1302的时钟寄存器:CH是时钟停止位,是秒寄存器的第7位,12/24小时标志位;CH=0 振荡器工作允许,BIT7=12小时工作模式,反之振荡器停止就是24小时工作模式。
    WP是写保护位:WP=0寄存器数据能写入,否则是不能改写时间寄存器的。

    5、设置时分秒的地址分别为0x84,0x82,0x80,读取的地址分别为0x85,0x83,0x81

    二、实际使用

    1.蓝桥杯小蜜蜂讲解

    main.c

    #include <config.h> //自定义了一个头文件的包
    
    u8 code list[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,  0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
         0xbf,0x7f};	//数码管共阳极
    //ds1302读取数据地址
    u8 Write_DS1302_adrr[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
    u8 Read_DS1302_adrr[7] ={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
    //定义时间为20年4月16日 周六 23点59分24秒
    u8 Timer[7]={0x24,0x59,0x23,0x18,0x04,0x06,0x20};
    
    //DS1302的一个初始化
    void DS1302_config()
    {
    	 u8 i;		//u8是自定义unsigned char 
    	 Write_Ds1302_Byte(0x8e,0x00);	//首先把WP写保护位打开地址0x8e
    	 for(i=0;i<7;i++)
    	 {
    	 	Write_Ds1302_Byte( Write_DS1302_adrr[i],Timer[i]);//写入设定的时间数据到寄存器当中去
    	 }
    	 Write_Ds1302_Byte(0x8e,0x80);//关闭写保护位
    }
    //DS1302读取数据
    void Read_ds1302_Timer()
    {
    	u8 i;
    	for(i=0;i<7;i++)
    	{
    		Timer[i] = Read_Ds1302_Byte(Read_DS1302_adrr[i]);
    	}
    	
    }
    //设置数码管显示
    void Display_ds1302()
    {
       Display_bit(list[Timer[2]/16],0);
       Delaysmg(100);
       Display_bit(list[Timer[2]%16],1);
       Delaysmg(100);
    
       Display_bit(0xbf,2);
       Delaysmg(100);
    
       Display_bit(list[Timer[1]/16],3);
       Delaysmg(100);
       Display_bit(list[Timer[1]%16],4);
       Delaysmg(100);
    
       Display_bit(0xbf,5);
       Delaysmg(100);
    
       Display_bit(list[Timer[0]/16],6);
       Delaysmg(100);				 
       Display_bit(list[Timer[0]%16],7);
       Delaysmg(100);
    
       Display_all(0xff);
    }
    
    void main()
    {
    	Init_close();	//自定义关闭外设灯和蜂鸣器、继电器
    	DS1302_config();	//DS1302初始化
    	while(1)
    	{
    		Read_ds1302_Timer();	//读数据
    		Display_ds1302();	//1602显示
    	}
    }
    

    smg.c
    数码管这部分先写延时就不多说了

    #include<smg.h>
    void Delaysmg(u8 t)//延时
    {
    	while(t--);
    }
    

    后面的单个数码管点亮可以优化下

    void Display_bit(u8 dat,u8 pos) //单个数码管点亮
    {
    	Init_HC573(6);
    	P0 = 0x01 << pos;
    	Init_HC573(7);
    	P0 = dat;
    	Init_HC573(6);	//消隐,防止闪烁
    	P0 = 0x00;
    }
    void Display_all(u8 dat)	//整体
    {
    	Init_HC573(6);
    	P0 = 0xff;
    	Init_HC573(7);
    	P0 = dat;
    }
    

    因为之前写HC573和HC138那一节的时候有提到优化,所以这部分可以用outputP0来进行

    void displaysmg_bit(u8 pos,u8 dat)
    {
    	outputP0(6,(0x01<<pos));
    	outputP0(7,dat);
    	outputP0(6,0x00);	
    }
    //display_all同理即可
    

    2.官方给的示例

    代码如下(示例):

    #include <ds1302.h>
    
    sbit SCK=P1^7;		
    sbit SDA=P2^3;	//引入IIC会有冲突,可以提前重命名下1302的SDA	
    sbit RST = P1^3;   // DS1302复位												
    
    void Write_Ds1302(u8 temp) 
    {
    	unsigned char i;
    	for (i=0;i<8;i++)     	
    	{ 
    		SCK=0;
    		SDA=temp&0x01;
    		temp>>=1; 
    		SCK=1;
    	}
    }   
    
    void Write_Ds1302_Byte( u8 address,u8 dat )     
    {
     	RST=0;	_nop_();
     	SCK=0;	_nop_();
     	RST=1; 	_nop_();  
     	Write_Ds1302(address);	
     	Write_Ds1302(dat);		
     	RST=0; 
    }
    
    u8 Read_Ds1302_Byte ( u8 address )
    {
     	unsigned char i,temp=0x00;
     	RST=0;	_nop_();
     	SCK=0;	_nop_();
     	RST=1;	_nop_();
     	Write_Ds1302(address);
     	for (i=0;i<8;i++) 	
     	{		
    		SCK=0;
    		temp>>=1;	
     		if(SDA)
     		temp|=0x80;	
     		SCK=1;
    	} 
     	RST=0;	_nop_();
     	SCK=0;	_nop_();
    	SCK=1;	_nop_();
    	SDA=0;	_nop_();
    	SDA=1;	_nop_();
    	return (temp);			
    }
    
    
    #ifndef __DS1302_H
    #define __DS1302_H
    
    #include<config.h>
    void Write_Ds1302(u8 temp);
    void Write_Ds1302_Byte( u8 address,u8 dat );
    u8 Read_Ds1302_Byte( u8 address );
    #endif
    
    

    总结

    本人是第一次参加蓝桥杯,外设模块是跟着B站小蜜蜂老师学习的,本专栏文章仅是个人赛后的复盘行为,其他外设会陆续发在专栏当中,本文涉及到的所有的.h和.c文也会陆续发在专栏里,文内有错误的地方可以评论区留一下。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用DS1302模块参加蓝桥杯单片机比赛

    发表评论