蓝桥杯STC15单片机复习——DS1302
前言
倒计时9小时,终于到1302了,DS1302为时钟芯片,有掉电存储功能(并非真的掉电),对于国信长天的板子来说,只要插上了USB线,就一直是供电状态。
上图为板子上的DS1302接线图,由于官方示例已经给出了底层驱动,所以我们不再关心底层的实现。
从数据手册给的文档可以看出,读与写的地址的分开的,且每一位的间隔为2个字节,因此我们只需要在对应地址进行写入对应的数据即可,值得注意的是在进行数据写入的时候,我们需要将写保护关闭,即向0x8E的最高位写入0。
1、写入数据
主函数
/*
彭某的蓝桥杯复习——DS1302
1、写入初始时间
2、上电自动读取
3、实现时钟功能
*/
#include <STC15F2K60S2.h>
#include <intrins.h>
#include <ds1302.h>
#define uint unsigned int
#define uchar unsigned char
uchar SEG_num[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
uchar write_time[3] = {12,23,34};
uchar read_time[3];
void ALL_Init();
void delay_ms(uint ms);
void Time_show(uint hours,uint mintue,uint seconds);
void main()
{
ALL_Init();
Time_write(write_time);
while(1)
{
// Time_read(read_time);
// Time_show(read_time[0],read_time[1],read_time[2]);
}
}
void Time_show(uint hours,uint mintue,uint seconds)
{
P25 = 0;P26 = 1;P27 = 1;P0 = 0x01;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[hours/10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x02;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[hours%10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x04;
P25 = 1;P26 = 1;P27 = 1;
P0 = 0xbf;
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x08;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[mintue/10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x10;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[mintue%10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x20;
P25 = 1;P26 = 1;P27 = 1;
P0 = 0xbf;
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x40;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[seconds/10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x80;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[seconds%10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x00;
}
void delay_ms(uint ms)
{
uint i;
for(;ms>0;ms--)
for(i = 864;i>0;i--);
}
void ALL_Init()
{
P25 = 1;P26 = 0;P27 = 1;
P0 = 0x00;
P25 = 0;P26 = 1;P27 = 1;
P0 = 0x00;
P25 = 0;P26 = 0;P27 = 1;
P0 = 0xff;
}
写入函数
void Time_write(unsigned char *Time)
{
int i;
unsigned char addr = 0x80;
Write_Ds1302_Byte(0x8E,0x00);
for(i=2;i>=0;i--)
{
Write_Ds1302_Byte(addr,Time[i]);
addr+=2;
}
Write_Ds1302_Byte(0x8E,0x80);
}
2、读取数据并显示
主函数
/*
彭某的蓝桥杯复习——DS1302
1、写入初始时间
2、上电自动读取
3、实现时钟功能
*/
#include <STC15F2K60S2.h>
#include <intrins.h>
#include <ds1302.h>
#define uint unsigned int
#define uchar unsigned char
uchar SEG_num[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
uchar write_time[3] = {12,23,34};
uchar read_time[3];
void ALL_Init();
void delay_ms(uint ms);
void Time_show(uint hours,uint mintue,uint seconds);
void main()
{
ALL_Init();
// Time_write(write_time);
while(1)
{
Time_read(read_time);
Time_show(read_time[0],read_time[1],read_time[2]);
}
}
void Time_show(uint hours,uint mintue,uint seconds)
{
P25 = 0;P26 = 1;P27 = 1;P0 = 0x01;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[hours/10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x02;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[hours%10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x04;
P25 = 1;P26 = 1;P27 = 1;
P0 = 0xbf;
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x08;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[mintue/10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x10;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[mintue%10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x20;
P25 = 1;P26 = 1;P27 = 1;
P0 = 0xbf;
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x40;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[seconds/10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x80;
P25 = 1;P26 = 1;P27 = 1;
P0 = SEG_num[seconds%10];
delay_ms(1);
P25 = 0;P26 = 1;P27 = 1;P0 = 0x00;
}
void delay_ms(uint ms)
{
uint i;
for(;ms>0;ms--)
for(i = 864;i>0;i--);
}
void ALL_Init()
{
P25 = 1;P26 = 0;P27 = 1;
P0 = 0x00;
P25 = 0;P26 = 1;P27 = 1;
P0 = 0x00;
P25 = 0;P26 = 0;P27 = 1;
P0 = 0xff;
}
读取函数
void Time_read(unsigned char *Time)
{
int i;
unsigned char addr = 0x81;
Write_Ds1302_Byte(0x8E,0x80);
for(i=2;i>=0;i--)
{
Time[i] = Read_Ds1302_Byte(addr);
addr+=2;
}
}
注意!!!!
由于官方提供的底层驱动的写入与读取都是基于十六进制进行的,而我们定义时间变量与显示常常使用的是十进制的方式,因此,我们在进行设定的时候需要对其数据进行处理,在写入时应将十进制转换为十六进制,在读取时应将十六进制转换为十进制。
十进制转换为十六进制
(dat/10)<<4|dat%10
十六进制转换为十进制
high = temp/16;
low = temp%16;
temp = high*10+low;
结语
至此,DS1302的使用测试结束。