ds1302.h
#ifndef __DS1302_H#define __DS1302_HvoidWrite_Ds1302_Byte(unsignedchartemp); voidWrite_Ds1302( unsignedcharaddress,unsignedchardat ); unsignedcharRead_Ds1302 ( unsignedcharaddress ); #endif
ds1302.c
/*程序说明: DS1302驱动程序软件环境: KeiluVision4.10硬件环境: CT107单片机综合实训平台8051,12MHz日期: 2011-8-9*/#include <stc15f2k60s2.h>#include <intrins.h>sbitSCK=P1^7; sbitSDA=P2^3; sbitRST=P1^3; //DS1302复位voidWrite_Ds1302_Byte(unsignedchartemp) { unsignedchari; for (i=0;i<8;i++) { SCK=0; SDA=temp&0x01; temp>>=1; SCK=1; } } voidWrite_Ds1302( unsignedcharaddress,unsignedchardat ) { unsignedcharnum; RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_(); Write_Ds1302_Byte(address); num=((dat/10)<<4)|(dat%10); Write_Ds1302_Byte(num); RST=0; } unsignedcharRead_Ds1302 ( unsignedcharaddress ) { unsignedchari,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_(); SDA=0; return (temp); }
main.c
#include <stc15f2k60s2.h>#include <intrins.h>#include <ds1302.h>#define uchar unsigned char #define uint unsigned int uchards[]={55,59,23,10,10,1,16}; ucharshijian[7]; ucharseg[]={ 0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e, 0xff}; ucharyi=16, er=16,san=16,si=16,wu=16,liu=16,qi=16,ba=16; voidallinit(); voiddsinit(); voidreadtime(); voiddisplay(ucharyi,er,san,si,wu,liu,qi,ba); voidDelay1ms(); voidDelayms(uintms); voidmain() { allinit(); dsinit(); while(1) { readtime(); yi=shijian[2]/16;er=shijian[2]%16;san=16; si=shijian[1]/16;wu=shijian[1]%16;liu=16; qi=shijian[0]/16;ba=shijian[0]%16; display(yi,er,san,si,wu,liu,qi,ba); } } voidallinit() { P2=0xa0;P0=0x00; P2=0x80;P0=0xff; P2=0xe0;P0=0xff; P2=0xc0;P0=0xff; } voiddisplay(ucharyi,er,san,si,wu,liu,qi,ba) { P2=0xe0;//段选P0=seg[yi]; P2=0xc0;//位选P0=0x01; Delay1ms(); Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[er]; P2=0xc0;//位选P0=0x02; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[san]; P2=0xc0;//位选P0=0x04; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[si]; P2=0xc0;//位选P0=0x08; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[wu]; P2=0xc0;//位选P0=0x10; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[liu]; P2=0xc0;//位选P0=0x20; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[qi]; P2=0xc0;//位选P0=0x40; Delay1ms();Delay1ms();Delay1ms(); P2=0xe0;//段选P0=seg[ba]; P2=0xc0;//位选P0=0x80; Delay1ms();Delay1ms();Delay1ms(); } voidDelay1ms() //@11.0592MHz{ unsignedchari, j; _nop_(); _nop_(); _nop_(); i=11; j=190; do { while (--j); } while (--i); } voidDelayms(uintms) //@11.0592MHz{ unsignedchari, j,k; for(k=ms;k>0;k--) { _nop_(); _nop_(); _nop_(); i=11; j=190; do { while (--j); } while (--i); } } voiddsinit() { uchari; ucharadd=0x80; Write_Ds1302(0x8e,0x00); for(i=0;i<7;i++) { Write_Ds1302(add,ds[i]); add=add+2; } Write_Ds1302(0x8e,0x80); } voidreadtime() { uchari; ucharadd=0x81; Write_Ds1302(0x8e,0x00); for(i=0;i<7;i++) { shijian[i]=Read_Ds1302(add); add=add+2; } Write_Ds1302(0x8e,0x80); }
上述代码:数码管实现时钟显示
然后使用eeprom和ad的iic文件,这里功能就不做过多演示了,会结合后面的初赛题进行练习使用
#ifndef _IIC_H#define _IIC_H#include "intrins.h"#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}//总线引脚定义sbitSDA=P2^1; /*数据线*/sbitSCL=P2^0; /*时钟线*///函数声明voidIIC_Start(void); voidIIC_Stop(void); voidIIC_Ack(unsignedcharackbit); voidIIC_SendByte(unsignedcharbyt); bitIIC_WaitAck(void); unsignedcharIIC_RecByte(void); //======================AD转换unsignedcharAD_read(unsignedcharadd); //====================E2PROM//unsignedEEPROM_read(unsignedcharadd); voidEEPROM_write(unsignedcharadd,unsignedchardat); #endif
iic.c:
#include "STC15F2K60S2.h"#include "intrins.h"#include "iic.h"typedefunsignedintuint; typedefunsignedcharuchar; voidIIC_Start()//开始{ SDA=1; SCL=1; somenop; SDA=0; somenop; SCL=0; } voidIIC_Stop(void)//开始{ SDA=0; SCL=1; somenop; SDA=1; } voidIIC_Ack(ucharackbit)//应答位控制{ if (ackbit) { SDA=0; } else { SDA=1; } somenop; SCL=1; somenop; SCL=0; SDA=1; somenop; } bitIIC_WaitAck(void)//等待应答{ SDA=1; somenop; SCL=1; somenop; if (SDA) { SCL=0; IIC_Stop(); return0; } else { SCL=0; return1; } } voidIIC_SenByte(ucharbyt)//发送数据{ uchari; for(i=0;i<8;i++) { if (byt&0x80) { SDA=1; } else { SDA=0; } somenop; SCL=1; byt<<=1; somenop; SCL=0; } } ucharIIC_RecByte(void)//接收数据{ ucharda; uchari; for(i=0;i<8;i++) { SCL=1; somenop; da<<=1; if (SDA) { da|=0x01; } SCL=0; somenop; } returnda; } //======================以下程序都要自己写ucharAD_read(ucharadd)//写进数据,然后读取AD值{ floattemp; //写地址器件操作IIC_Start(); IIC_SenByte(0x90);//发送寻址IIC_WaitAck(); IIC_SenByte(add);//发送0x03,器件地址IIC_WaitAck(); IIC_Stop(); //读取操作IIC_Start(); IIC_SenByte(0x91);//发送寻址IIC_WaitAck(); IIC_SenByte(add); IIC_WaitAck(); temp=IIC_RecByte(); IIC_Stop(); returntemp; } ucharEEPROM_read(ucharadd)//写进地址{ uinttemp; IIC_Start(); IIC_SenByte(0xa0); IIC_WaitAck(); IIC_SenByte(add); IIC_WaitAck(); IIC_Stop(); IIC_Start(); IIC_SenByte(0xa1);//IIC的读命令操作IIC_WaitAck(); temp=IIC_RecByte(); IIC_Stop(); returntemp; } voidEEPROM_write(ucharadd, uchardat)//写进EEPROM需要分别写进地址和数据{ IIC_Start(); IIC_SenByte(0xa0);//IIC的写命令操作IIC_WaitAck(); IIC_SenByte(add); IIC_WaitAck(); IIC_SenByte(dat); IIC_WaitAck(); IIC_Stop(); }