ds1302程序及原理图

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/**************************************************
;文件名:DS1302.c
;功能:设置时间,然后将时间读出显示在数码管上
;硬件描述:PORTD口接数码管的8个笔段
; PORTA 0~2及PORTE 0~2分别接6位数码管的位
;RC3接SCK,RC4接SDA,RC2接RST
*/
#include "pic.h"
#define uchar unsigned char
#define uint unsigned int
#define Hidden 16
__CONFIG(HS&WDTDIS&LVPDIS); //配置文件,设置为HS方式振荡,禁止看门狗,低压编程关闭
uchar
DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x8 6,0x8E,0xFF};
uchar BitTab[]={0xfb,0xfd,0xfe};
uchar DispBuf[6];
#define LSB 0x01
#define WrEnDisCmd 0x8e //写允许/禁止指令代码
#define WrEnDat 0x00 //写允许数据
#define WrDisDat 0x80 //写禁止数据
#define OscEnDisCmd 0x80 //振荡器允许/禁止指令代码
#define OscEnDat 0x00 //振荡器允许数据
#define OscDisDat 0x80 //振荡器禁止数据
#define WrMulti 0xbe //写入多个字节的指令代码
#define WrSingle 0x84 //写入单个字节的指令代码
#define RdMulti 0xbf //读出多个字节的指令代码
#define cClk RC3 //与时钟线相连的PIC16F877A芯片的管脚
#define cDat RC4 //与数据线相连的PIC16F877A芯片的管脚
#define cRst RC2 //与复位端相连的PIC16F877A芯片的管脚
#define SCL_CNT TRISC3 //SCL管脚控制位
#define SDA_CNT TRISC4 //SDA管脚控制位
#define RST_CNT TRISC2 //RST管脚控制位
void mDelay(uint DelayTime)
{ uint temp;
for(;DelayTime>0;DelayTime--)
{ for(temp=0;temp<270;temp++)
{;}
}
}
void interrupt Disp()
{ static uchar dCount; //用作显示的计数器
if(TMR1IF==1&&TMR1IE==1)//Timer 1 inetrrupt
{
TMR1H=-(8000/256);
TMR1L=-(8000%256); //重置定时初值
}
PORTA|=0x07; //关前面的显示
PORTE|=0X07; //关前面的显示
PORTD=DispTab[DispBuf[dCount]]; //显示第i位显示缓冲区中的内容if(dCount<3)
PORTE&=BitTab[dCount]; //第1~3位是由PORTE控制的else
PORTA&=BitTab[dCount-3]; //第4~6位是由PORTA的低3位控制的dCount++;
if(dCount==6)
dCount=0;
TMR1IF=0; //清中断标志
}
//数码管位 1 2 3 4 5 6
//引脚RE0 RE1 RE2 RA2 RA1 RA0
//根据这个表,只要改变PORTA&=0xfe,即可点亮任意一个数码管
//例:PORTA&=0xfd //点亮第5位数码管
// PORTE&=0xfe //点亮第3位数码管
void uDelay(uchar i)
{ for(;i>0;i--)
{;}
}
void SendDat(uchar Dat)
{ uchar i;
for(i=0;i<8;i++)
{
cDat=Dat&LSB; //数据端等于tmp数据的末位值
Dat>>=1;
cClk=1;
uDelay(1);
cClk=0;
}
}
/*写入1个或者多个字节,第1个参数是相关命令
#define WrMulti 0xbe //写入多个字节的指令代码
#define WrSingle 0x84 //写入单个字节的指令代码
第2个参数是待写入的值
第3个参数是待写入数组的指针
*/
void WriteByte(uchar CmdDat,uchar Num,uchar *pSend)
{
uchar i=0;
SDA_CNT=0; //数据端设为输出
cRst=0;
uDelay(1);
cRst=1;
SendDat(CmdDat);
for(i=0;i<Num;i++)
{ SendDat(*(pSend+i));
}
cRst=0;
}
/*读出字节,第一个参数是命令
#define RdMulti 0xbf //读出多个字节的指令代码
第2个参数是读出的字节数,第3个是指收数据数组指针
*/
void RecByte(uchar CmdDat,uchar Num,uchar *pRec)
{
uchar i,j,tmp;
SDA_CNT=0; //数据端设为输出
cRst=0; //复位引脚为低电平
uDelay(1);
cClk=0;
uDelay(1);
cRst=1;
SendDat(CmdDat); //发送命令
SDA_CNT=1; //数据端设为输入
for(i=0;i<Num;i++)
{ for(j=0;j<8;j++)
{ tmp>>=1;
if(cDat)
tmp|=0x80;
cClk=1;
uDelay(1);
cClk=0;
}
*(pRec+i)=tmp;
}
uDelay(1);
cRst=0;
}
/*
当写保护寄存器的最高位为0时,允许数据写入寄存器。

写保护寄存器可以通过命令字节8E、8F来规定禁止写入/读出。

写保护位不能在多字节传送模式下写入。

当写保护寄存器的最高位为1时,禁止数据写入寄存器。

时钟停止位操作:当把秒寄存器的第7位时钟停止位设置为0时起动时钟开始
当把秒寄存器的第7位时钟停止位设置为1时,时钟振荡器停止。

根据传入的参数决定相关命令,
第一个参数:命令字,第2个参数:写入的数据
写允许命令;8EH,00H
写禁止命令;8EH,80H
振荡器允许命令;80H,00H
振荡器禁止命令;80H,80H
*/
void WrCmd(uchar CmdDat,uchar CmdWord)
{ uchar CmdBuf[2];
CmdBuf[0]=CmdWord;
WriteByte(CmdDat,1,CmdBuf);
}
void Init()
{
ADCON1=0x06; //设定为数字端口
TRISA&=0xf8; //PORTA 0~2设为输出
TRISE&=0xf8; //PORTE 0~2设为输出
TRISD=0; //PORTD 设为输出
//////////////////Timer1 设置
TMR1CS=0; //将T1设为定时器
TMR1ON=1; //启动T1
TMR1IE=1;
////以下设置DS1302操作相关引脚
SCL_CNT=0; //SCL管脚控制位
SDA_CNT=0; //SDA管脚控制位
RST_CNT=0; //RST管脚控制位
GIE=1;
PEIE=1;
}
void main()
{ uchar SendBuf[8]={0x30,0x32,0x01,0x10,0x01,0x01,0x08,33}; //发送数据缓冲区/*秒,分,时,日,月,星期,年*/
uchar RecBuf[8]; //接收数据缓冲区
Init();
WrCmd(WrEnDisCmd,WrEnDat); //写允许
WrCmd(OscEnDisCmd,OscEnDat); //振荡器允许
WriteByte(WrMulti,8,SendBuf);
for(;;)
{
RecByte(RdMulti,8,RecBuf); //
mDelay(100); //延时100ms,
DispBuf[0]=RecBuf[2]/16;
DispBuf[1]=RecBuf[2]%16;
DispBuf[2]=RecBuf[1]/16;
DispBuf[3]=RecBuf[1]%16; //分
DispBuf[4]=RecBuf[0]/16;
DispBuf[5]=RecBuf[0]%16; //秒}
}。

相关文档
最新文档