蓝桥杯_单片机_入门基础知识(六)_DS1302时钟

持续关注阿杰在线更新保姆式蓝桥杯笔记~~坚持日更

目录

一、实时时钟芯片DS1302概述

​ 二、性能指标

三、基本组成及工作原理

管脚排列及描述​

内部寄存器​

四、DS1302的读写时序图

五、DS1302模块化编程思路

六、代码区


一、实时时钟芯片DS1302概述

 二、性能指标

三、基本组成及工作原理

管脚排列及描述

 CD107D开发板为例,电路原理图如下:

内部寄存器

 

 

 

四、DS1302的读写时序图

五、DS1302模块化编程思路

Main()
{
    Key_Proc()
    Seg_Proc()
    Led_Proc()
}


Time_1() interrupt 3
{
  ++ Key_Slow_Down降速
  ++Seg_Slow_Down  降速

  Led_Disp()
  Seg_Disp(seg_buf, pos); //显示刷新
  if( ++pos == 8 ) 	pos = 0;
}

void Key_Proc(void)//按键处理,底层数据变更
{	//永远不变
	if(Key_Slow_Down) return;
	…
	Key_Down = Key_Value & (Key_Old ^ Key_Value	Key_Old = Key_Value;
	…
	//根据代码需求发生变化
	 Key_Down 控制状态信息变化
}


void Seg_Proc(void)//显示处理,显示信息生成
{
	//永远不变
	if(Seg_Slow_Down) return;
	Seg_Slow_Down = 1;//减速程序

	//根据代码需求发生变化
	根据状态信息,控制显示内容的采集和更换

	//永远不变
	Seg_Tran(seg_string, seg_buf);
}

void Led_Proc(void)//LED处理,显示信息生成
{
	显示信息的处理
}

六、代码区


 **main.c文件**
#include "bsp_key.h"
#include "bsp_led.h"
#include "bsp_seg.h"
#include "ds1302.h"
#include "bsp_init.h"
#include "timer.h"
#include "stdio.h"
//---------------------------
/*函数声明*/
//三个主体循环,基本上永远不变
void Key_Proc(void);//按键处理,底层数据变更
void Seg_Proc(void);//显示处理,显示信息生成
void Led_Proc(void);//LED处理,LED状态信息表示

//---------------------------
/*全局变量声明*/

//数码管显示专用,基本上永远不变
unsigned char seg_buf[8];//放置字符串转换后的段码到数组
unsigned char seg_string[10];//放置字符串
unsigned char pos = 0;//中断显示专用

//LED显示专用,基本上永远不变
unsigned char ucLed;//记录LED的状态信息

//按键专用,基本上永远不变
unsigned char Key_Value;//读取按键的数值存储变量
unsigned char Key_Down,Key_Old;//读取按键的数值存储变量	

//按键和显示函数减速专用,基本永远不变
unsigned int Key_Slow_Down;//按键减速
unsigned int Seg_Slow_Down;//按键减速

//ds1302专用,当使用DS1302时,基本永远不变
unsigned char ucRTC[3] = {23,59,55};

//根据代码需求发生变化
unsigned int ms_count;//记录毫秒数据
unsigned char s_count;//记录秒数据

unsigned char Running_State;//记录运行状态

//---------------------------
/*main*/
void main()
{
	//根据代码需求发生变化
	Cls_peripheral();//关闭外设	
	Timer1Init();//定时器1初始化,并且使能定时器1中断,1ms进入一次
	EA = 1;//打开总中断
	
	Set_Rtc(ucRTC);//设置RTC时间,23-59-55
	
	while(1)
	{
		//永远不变
		Key_Proc();//按键处理,底层数据变更
		Seg_Proc();//显示处理,显示信息生成
		Led_Proc();//LED处理,LED状态信息表示		
	}
}

//---------------------------
/*timer1*/
void timer1()interrupt 3
{
	//永远不变
	if(++Key_Slow_Down == 10)	Key_Slow_Down = 0;
	if(++Seg_Slow_Down == 500)	Seg_Slow_Down = 0;
	
	if(++ms_count == 1000)//记录运行时间
	{
		s_count++;
		ms_count=0;
	}
	
	//永远不变
	Seg_Disp(seg_buf,pos);//数码管显示刷新
	if(++pos == 8)	pos = 0;
	
	Led_Disp(ucLed);
    //LED显示-->防止LED的P0受数码管等外设的P0的干扰置数产生其他为点亮的小灯余影
}

//---------------------------
/*Key_Proc*/
void Key_Proc()//按键处理,底层数据变更
{
	//永远不变
	if(Key_Slow_Down)	return;
	Key_Slow_Down = 1;//减速程序
	
	Key_Value = Key_Read_BTN();//读取按键按下的编号
	Key_Down = Key_Value & (Key_Value ^ Key_Old);
	Key_Old = Key_Value;
	
	//根据代码需求发生变化
	if(Key_Down)//如果捕捉到下降沿跳变
	{
		if(++Running_State == 2)	Running_State = 0;//保证Running_State在0-1之间翻滚
	}
}

//---------------------------
/*Seg_Proc*/
void Seg_Proc()
{
	//永远不变
	if(Seg_Slow_Down)	return;
	Seg_Slow_Down = 1;//减速程序
	
	//根据代码需求发生变化
	switch(Running_State)
	{
		case 0:
			Read_Rtc(ucRTC);//读取1302内部时分秒的数据,放到预定义的数组空间中	
			sprintf(seg_string,"%02d-%02d-%02d",(unsigned int)ucRTC[0],(unsigned             
                    int)ucRTC[1],(unsigned int)ucRTC[2]);
			//将要显示的数值打印到字符串当中
		break;
		case 1:
			sprintf(seg_string,"-----%03d",(unsigned int)s_count);
            //将要显示的数值打印到字符串当中
		break;
	}
	
	//永远不变
	Seg_Tran(seg_string,seg_buf);
}

//---------------------------
/*Led_Proc*/
void Led_Proc()
{
	//根据代码需求发生变化
	switch(Running_State)
	{
		case 0:	ucLed = 0x0f;	break;
		case 1:	ucLed = 0xf0;	break;
	}
}

 **bsp_key.c文件**
#include "ds1302.h"


void Write_Ds1302_Byte(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		SDA=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

void Write_Ds1302( unsigned char address,unsigned char dat )     
{
 	RST=0;
	_nop_();
 	SCK=0;
	_nop_();
 	RST=1;	
   	_nop_();
 	Write_Ds1302_Byte(address);	
 	Write_Ds1302_Byte(dat);		
 	RST=0; 
}


unsigned char Read_Ds1302 ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;
	_nop_();
 	SCK=0;
	_nop_();
 	RST=1;
	_nop_();
 	Write_Ds1302_Byte(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;
	_nop_();
 	RST=0;
	SCK=0;
	_nop_();
	SCK=1;
	_nop_();
	SDA=0;
	_nop_();
	SDA=1;
	return (temp);			
}

//函数名:设置DS1302时分秒函数
//入口参数:包含时分秒数据的数组指针
//返回值:无
//函数功能:设置DS1302时分秒函数
void Set_Rtc(unsigned char* ucRtc)
{
	unsigned char temp;//中间局部变量,存放时分秒
	
	Write_Ds1302(0x8e,0);//wp = 0, 允许写操作
	temp = (((ucRtc[0]/10)<<4) | (ucRtc[0]%10));//数组的第0个数据,小时,用BCD码的形式存储	
	Write_Ds1302(0x84,temp);//写入到小时的寄存器
	temp = (((ucRtc[1]/10)<<4) | (ucRtc[1]%10));//数组的第1个数据,分钟,用BCD码的形式存储
	Write_Ds1302(0x82,temp);//写入到分钟的寄存器
	temp = (((ucRtc[2]/10)<<4) | (ucRtc[2]%10));//数组的第2个数据,秒,用BCD码的形式存储
	Write_Ds1302(0x80,temp);//写入到秒的寄存器
	Write_Ds1302(0x8e,0x80);//wp = 1, 不允许写操作
}

//函数名:读取DS1302时分秒函数
//入口参数:将读取到的时分秒数据存放到数组的指针
//返回值:无
//函数功能:读取DS1302时分秒函数,将读取到的数据放到数组指针指向的位置
void Read_Rtc(unsigned char* ucRtc)
{
	unsigned char temp;//中间局部变量,存放时分秒
	
	temp = Read_Ds1302(0x85);//读取小时数据
	ucRtc[0] = (((temp>>4)*10) + (temp & 0x0f));
    // 23(BCD) = 0010 0011(B) = 35(D),不能直接赋值,要进行BCD到十进制数据的转换
	temp = Read_Ds1302(0x83);//读取分钟数据
	ucRtc[1] = (((temp>>4)*10) + (temp & 0x0f));
    // 23(BCD) = 0010 0011(B) = 35(D),不能直接赋值,要进行BCD到十进制数据的转换	
	temp = Read_Ds1302(0x81);//读取秒数据
	ucRtc[2] = (((temp>>4)*10) + (temp & 0x0f));
    // 23(BCD) = 0010 0011(B) = 35(D),不能直接赋值,要进行BCD到十进制数据的转换	
}

巧:

1、配置一个设置时间的函数

2、配置一个读取函数

注:对于这种编程写法。要把延迟时间这个函数去掉哦,不然可能会出现BUG哦。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值