阅读量:0
DS1302时钟芯片驱动和工作模式配置的方法:
在有如此DS1302文件的前提下:
ds1302.c:
#include "ds1302.h" code unsigned char w_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //??????? code unsigned char r_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; unsigned char set[6] = {2,3,5,9,5,5}; unsigned char rtc[6]; /* */ 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; _nop_(); return (temp); } /* */ unsigned char* ReadRTC(void) { unsigned char i, *p; unsigned char tmp[3]; p = (unsigned char *)r_rtc_address; //???? for(i=0;i<3;i++){ tmp[i]=Read_Ds1302(*p); p++; } rtc[0] = (tmp[2] >> 4); rtc[1] = (tmp[2] & 0x0F); rtc[2] = (tmp[1] >> 4); rtc[3] = (tmp[1] & 0x0F); rtc[4] = (tmp[0] >> 4); rtc[5] = (tmp[0] & 0x0F); return rtc; } /* */ void SetRTC(void) { Write_Ds1302(0x8E,0X00); Write_Ds1302(w_rtc_address[0], (set[4]<<4) | (set[5])); Write_Ds1302(w_rtc_address[1], (set[2]<<4) | (set[3])); Write_Ds1302(w_rtc_address[2], (set[0]<<4) | (set[1])); Write_Ds1302(0x8E,0x80); }
ds1302.h:
#ifndef __DS1302_H #define __DS1302_H #include <STC15F2K60S2.H> #include "intrins.h" sbit SCK=P1^7; sbit SDA=P2^3; sbit RST = P1^3; // DS1302?? void SetRTC(void); unsigned char* ReadRTC(void); #endif
在使用ReadRTC()前需要先引用SetRTC()
示例代码以及讲解:
#include <STC15F2K60S2.H> #include "ds1302.h" code unsigned char tab[] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xFF, 0xbf}; unsigned char buf[8]={10,10,10,10,10,10,10,10},com,ms; //段选、位选、定时扫描参数 bit flag; void display(); //关闭蜂鸣器 void cls_buzz() { P2=(P2&0x1f)|0xa0; P0=0x00; P2&=0x1f; } //关闭led void cls_led() { P2=(P2&0x1f)|0x80; P0=0xff; P2&=0x1f; } //延时100ms void Delay100ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); _nop_(); i = 5; j = 52; k = 195; do { do { while (--k); } while (--j); } while (--i); } //定时器0初始化+开启中断 void Timer0Init(void) //1毫秒@11.0592MHz { AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0xCD; //设置定时初值 TH0 = 0xD4; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0=1; EA=1; } //主函数 void main() { unsigned char *r_in; cls_buzz(); cls_led(); Timer0Init(); Delay100ms(); SetRTC(); while(1) { if(flag) { flag=0; r_in=ReadRTC(); buf[0]=r_in[0]; buf[1]=r_in[1]; buf[2]=11; buf[3]=r_in[2]; buf[4]=r_in[3]; buf[5]=11; buf[6]=r_in[4]; buf[7]=r_in[5]; } } } //中断服务函数 void Timer0_Proc() interrupt 1 { if(++ms==200) { ms=0; flag=1; } display(); } //数码管显示’ void display() { //消影 P2=(P2&0x1f)|0xe0; P0=0xff; P2&=0x1f; //位选‘ P2=(P2&0x1f)|0xc0; P0=(1<<com); P2&=0x1f; //段选 P2=(P2&0x1f)|0xe0; P0=tab[buf[com]]; P2&=0x1f; //刷新 if(++com==8) { com=0; } }
实验现象:数码管动态显示
学习总结:基础学习有了大致的掌握,暂告一段落,之后进入真题学习阶段