蓝桥杯单片机学习笔记——DS1302

ds1302就是一个新买的时钟

DS1302的原理大家可以参考

欧浩源老师的视频

【进阶强化03】蓝桥杯中DS1302的基本应用

或者是西风老师的视频

第四讲 DS1302模块

大家可以去了解iic总线的工作原理和ds1302的工作原理

我自己看的是这个up主的介绍 我只是看了怎么使用ds1302 具体的显示代码还是结合欧浩源老师的代码来写的

【蓝桥杯单片机入门】8.DS1302时钟芯片(硬件介绍+软件编程)

我这里就简单展示一下这个具体的用法

首先是引脚的定义  iic总线的数据脚需要自己定义 这段定义我是写在iic.c中的

这个原理图截图如下

然后就是使用

首先要写入一个初始值 就是给新买的时钟设置时间

图片来自up主小菜OvO                                                            

附上真爱粉图片

读取的时候 不需要对0x8e操作,其他操作反过来就可以了 

下面直接看代码吧 这里使用的是传入的数组地址 这个数组是什么呢 就是我们提前设置好的时间数组和用于存放读取数据的数组 还有DS1302的寄存器地址数组

这个是设置在 mian.c 里面的数组 (设置数组的方法是来自欧浩源老师)

u8 w_addr[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//写入寄存器地址
u8 r_addr[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//读取寄存器地址
u8 time[7]={0x49,0x40,0x20,0x27,0x03,0x03,0x24};//想要设置的时间 这个是24年 周三 3月 27号 20:40:49
u8 time1[7];// 用于存放读取的数据
void time_w (u8* w_addr, u8* time)
{
    // 设置DS1302的写使能,0x8e为启动写命令的地址,0x00为写使能的值
    Write_Ds1302_Byte(0x8e, 0x00);
    
    // 循环写入7个时间寄存器的数据
    for (u8 n = 0; n < 7; n++)
    {
        // 写入对应地址的数据
        Write_Ds1302_Byte(w_addr[n], time[n]);
    }
    
    // 设置DS1302的写禁止,0x80为禁止写入的值
    Write_Ds1302_Byte(0x8e, 0x80);
}

/**
 * @brief 从DS1302实时时钟芯片读取时间
 * 
 * @param r_addr 要读取的地址数组,包含了DS1302的7个时间寄存器的地址
 * @param time 存储读取到的时间数据的数组
 */
void time_r (u8* r_addr, u8* time)
{
    u8 n;
    // 循环读取7个时间寄存器的数据
    for (n = 0; n < 7; n++)
    {
        // 读取对应地址的数据并存储到time数组中
        time[n] = Read_Ds1302_Byte(r_addr[n]);
    }
}
//这个u8 就是unsigned char

展示一下全部代码 采用了模块化编程

首先是数码管部分

smg.h

#ifndef __SMG_H
#define __SMG_H

#include "main.h"

void smg_display(u8 pos,u8 value);
void selecthc573(u8 channel);
void smg_clear();
#endif

smg.c

#include "main.h"

void selecthc573(u8 channel){
	switch(channel){
		case 4:
			P2=(P2&0x1f)|0x80;
		break;
		case 5:
			P2=(P2&0x1f)|0xa0;
		break;
		case 6:
			P2=(P2&0x1f)|0xc0;
		break;
		case 7:
			P2=(P2&0x1f)|0xe0;
		break;
	}
}
void smg_display(u8 pos,u8 value){
	selecthc573(6);
	P0=0x01<<pos;
	selecthc573(7);
	P0=0xff;
	P0=value;
}
void smg_clear(){
	int n;
	for(n=0;n<8;n++){
	smg_display(n,0xff);
	}
}

ds1302.h

#ifndef __DS1302_H
#define __DS1302_H

#include "main.h"

void Write_Ds1302(unsigned  char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte ( unsigned char address );
void time_w(u8* w_addr,u8* time);
void time_r(u8* r_addr,u8* time);
#endif

ds1302.c

/*	# 	DS1302代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/								

#include "main.h"

sbit SCK=P1^7;//对照原理图补充
sbit SDA=P2^3;
sbit RST=P1^3;



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

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

//
unsigned char Read_Ds1302_Byte ( unsigned char 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);			
}
void time_w (u8* w_addr,u8* time)
	{
	u8 n;
	Write_Ds1302_Byte(0x8e,0x00);
	for(n=0;n<7;n++){
		Write_Ds1302_Byte(w_addr[n],time[n]);
	}
	Write_Ds1302_Byte(0x8e,0x80);
}
void time_r(u8* r_addr,u8* time)
{
	u8 n;
	for(n=0;n<7;n++){
		time[n]=Read_Ds1302_Byte(r_addr[n]);
	}
}





main.h

#ifndef __MAIN_H
#define __MAIN_H
typedef unsigned char u8;
typedef unsigned int u16;

#include <reg52.h>
#include "ds1302.h"
#include <intrins.h>
#include "smg.h"

#endif

main.c

#include "main.h"
u8 code smg_duanma[18]={
	0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
	0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
	0xbf,0x7f};

u8 w_addr[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
u8 r_addr[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
u8 time[7]={0x49,0x40,0x20,0x27,0x03,0x03,0x24};
u8 time1[7];
u8 count=0;

void delay(u16 t){
	int n;
	while(t--){
		for(n=0;n<12;n++);
	}
}

void ds1302_display1(){
		smg_display(0,smg_duanma[time1[6]/16]);
		delay(50);
		smg_display(1,smg_duanma[time1[6]%16]);
		delay(50);
		smg_display(2,smg_duanma[16]);
		delay(50);
		smg_display(3,smg_duanma[time1[4]/16]);
		delay(50);
		smg_display(4,smg_duanma[time1[4]%16]);
		delay(50);
		smg_display(5,smg_duanma[16]);
		delay(50);
		smg_display(6,smg_duanma[time1[3]/16]);
		delay(50);
		smg_display(7,smg_duanma[time1[3]%16]);
		delay(50);
		smg_display(0,0xff);
}
void ds1302_display2(){
		smg_display(7,smg_duanma[time1[5]%16]);
}
void ds1302_display3(){
		smg_display(0,smg_duanma[time1[2]/16]);
		delay(50);
		smg_display(1,smg_duanma[time1[2]%16]);
		delay(50);
		smg_display(2,smg_duanma[16]);
		delay(50);
		smg_display(3,smg_duanma[time1[1]/16]);
		delay(50);
		smg_display(4,smg_duanma[time1[1]%16]);
		delay(50);
		smg_display(5,smg_duanma[16]);
		delay(50);
		smg_display(6,smg_duanma[time1[0]/16]);
		delay(50);
		smg_display(7,smg_duanma[time1[0]%16]);
		delay(50);
		smg_display(0,0xff);
}
void init_t0(){//初始化定时器函数
	TMOD=0x01;//设置定时器模式 这个是16位定时器 手动装载初值
	TH0=(65536-50000)/256;//设置初值 转换成16进制 存放高位
	TL0=(65536-50000)%256;//低位
	
	ET0=1;//允许定时器0中断
	EA=1;//总中断开关
	TR0=1;//定时器!启动!!!!
}
void servicetimer0() interrupt 1{// 定时中断函数的标志 不可以忘记写
	TH0=(65536-50000)/256;//因为不会自动装载初值 所以需要手动装载
	TL0=(65536-50000)%256;
	count++;
}

void main(){
	time_w(w_addr,time);
	init_t0();
	while(1)
	{
		time_r(r_addr,time1);
		if(count<60){
			ds1302_display1();
		}
		if(count>=60&&count<120){
			smg_clear();
			delay(50);
			ds1302_display2();
		}
		if(count>=120&&count<180){
			ds1302_display3();
		}
		if(count==180){
			count=0;
		}
}
}

这段其实可以写成switch的形式

效果展示

DS1302功能演示

还有PCF8591  超声波 555定时器 冲冲冲

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值