蓝桥杯CT107D之DS1302
DS1302时序(SPI协议简介)
- CE:为低电平时终止传输;高电平时启动传输。
- SCLK:数据必须在有效时钟的上升沿输入,下降沿输出。
- I/O:前八个时钟周期写入命令字节;后八个时钟周期写入数据字节。
DS1302命令字节
- bit7为控制字有效位,必须为1才可写入数据。
- bit6为0则表示可以存取日历时钟数据。
- bit5~bit1是地址。
- bit0为读写操作位,0:表示写操作,1:表示读取操作。
- 传输时低位在前。
DS1302数据地址
- 地址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);
}
小结
- 注意DS1302传输数据格式BCD码
- 对SPI协议有简单的了解
- 本文仅限于对DS1302简单的了解和快速编程入手
- 大家可以提意见交流学习或者有问题留言
版权声明:本文为qq_42676921原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。