蓝桥杯CT107D之DS1302

标签: CT107D  c语言

DS1302时序(SPI协议简介)

ds1302时序

  • CE:为低电平时终止传输;高电平时启动传输。
  • SCLK:数据必须在有效时钟的上升沿输入,下降沿输出。
  • I/O:前八个时钟周期写入命令字节;后八个时钟周期写入数据字节。

DS1302命令字节

ds1302_cmd_byte

  • bit7为控制字有效位,必须为1才可写入数据。
  • bit6为0则表示可以存取日历时钟数据。
  • bit5~bit1是地址。
  • bit0为读写操作位,0:表示写操作,1:表示读取操作。
  • 传输时低位在前。

DS1302数据地址

ds1302_adress

  • 地址8Eh的bit7,即WP是写保护位,设置为0才可以对日历时钟寄存器进行写操作。
  • /***********************************************************
    设置时间和读取时间均以BCD码形式传输
    如:读取到小时为23小时,则接受到的数据位BCD码:0x23
    对0x23转换为十进制数进行显示,
    提取十位:0x23/16 -> 得到十进制:2
    提取个位:0x23%16 -> 得到十进制:3
    ************************************************************/

DS1302写字节操作

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

DS1302向固定地址写单个字节

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; 
}

DS1302读取固定地址单字节数据

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);			
}

DS1302设置时间(时、分、秒)

void Set_Time(unsigned char shi,unsigned char fen,unsigned char miao)
{
	Write_Ds1302_Byte(0x8e,0);
	Write_Ds1302_Byte(0x80,(miao/10)*16+miao%10);
	Write_Ds1302_Byte(0x82,(fen/10)*16+fen%10);
	Write_Ds1302_Byte(0x84,(shi/10)*16+shi%10);
	Write_Ds1302_Byte(0x8e,0x80);
}

DS1302设置时间和读取时间8位数码管显示主函数部分

#include "reg52.h"
#include "ds1302.h"
#include "key.h"
#include "smg.h"

#define FOSC 11059200L

#define T1MS (65536-FOSC/1000)      //1T模式
//#define T1MS (65536-FOSC/12/1000) //12T模式

sfr AUXR = 0x8e;                    //Auxiliary register

unsigned char code Duan[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f  ,0x40 /*显示一杠*/}; //共阴极段选0~9
unsigned char code Wei[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //共阴极位选 1--8
char KEY;
unsigned char shi,fen,miao;
unsigned char s=0;

void Timer0Init();


void main()
{
	Timer0Init();
	Set_Time(13,14,52);
//	shi = 0x13;
//	fen = 0x14;
//	miao = 0x52;
	while(1)
	{
		P0=0xff;    									//关闭下段选,达到消隐的目的。
		if(s == 0)
		{	P2 = 0xe0;	P0=~Duan[miao%16];  P2 = 0x00;	}
		if(s == 1)
		{	P2 = 0xe0;	P0=~Duan[miao/16];  P2 = 0x00;	}
		if(s == 2)
		{	P2 = 0xe0;	P0=~Duan[10];  P2 = 0x00;	}
		if(s == 3)
		{	P2 = 0xe0;	P0=~Duan[fen%16];  P2 = 0x00;	}
		if(s == 4)
		{	P2 = 0xe0;	P0=~Duan[fen/16];  P2 = 0x00;	}
		if(s == 5)
		{	P2 = 0xe0;	P0=~Duan[10];  P2 = 0x00;	}
		if(s == 6)
		{	P2 = 0xe0;	P0=~Duan[shi%16];  P2 = 0x00;	}
		if(s == 7)
		{	P2 = 0xe0;	P0=~Duan[shi/16];  P2 = 0x00;	}
		 
		P0=0x00;							    		//进入位选前先把P0清零,禁止选通数码管。	  
		P2 = 0xc0;	P0=~Wei[7-s];	 P2 = 0x00;
		P0=0xff;
	}
}

//T0初始化
void Timer0Init()
{
	AUXR |= 0x80;                   //定时器0为1T模式
//  AUXR &= 0x7f;                   //定时器0为12T模式

    TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)
    TL0 = T1MS;                     //初始化计时值
    TH0 = T1MS >> 8;
    TR0 = 1;                        //定时器0开始计时
    ET0 = 1;                        //使能定时器0中断
    EA = 1;
}

//T0 interrupt
void tm0_isr() interrupt 1 
{
	static char count=10;
	if(s<7)
	{
		s++;
	}
	else
	s=0;

	if(count-- == 0)
	{
		count = 10;
		KEY = read_key();
	}

	shi = Read_Ds1302_Byte(0x85);
	fen = Read_Ds1302_Byte(0x83);
	miao = Read_Ds1302_Byte(0x81);
}

小结

  1. 注意DS1302传输数据格式BCD码
  2. 对SPI协议有简单的了解
  3. 本文仅限于对DS1302简单的了解和快速编程入手
  4. 大家可以提意见交流学习或者有问题留言
版权声明:本文为qq_42676921原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42676921/article/details/106146969