📄 ds1302.c
字号:
/*****************************************************************************/
/*
* ds1302.c -- driver for Dallas Semiconductor DS1302 Real Time Clock.
*
* (C) Copyright 2001, Greg Ungerer (gerg@snapgear.com)
*/
/*****************************************************************************/
#include <windows.h>
#include <types.h>
#include <memory.h>
#include <nkintr.h>
#include <oal.h>
#include <CEDDK.h>
#include <bulverde.h>
#include "xllp_gpio.h"
#include "xsbase270_g.h"
#include "ds1302.h"
static BULVERDE_GPIO_REG *g_pBaseAddressGPIORegs = NULL;
/*********************************************************************
DS1302.C Pat Adamo, ADEMCO
05/26/99
This file handles the Dallas DS1302 Real Time Clock.
On the Motorola Coldfire MCF5206, the DS1302 requires three port
pins, designated as follows...
RESET* Port PP0
CLOCK Port PP1
DATA Port PP2
**********************************************************************/
//MBAR must have been set to this by someone else
//This must match the setting done by the hardware set-up
#define MCF_MBAR 0x10000000
//Additional Sim registers
#define MCFPP_PPDDR 0x1c5 //Port A Data Direction Register (byte, r/w)
#define MCFPP_PPDAT 0x1c9 //Port A Data Register (byte, r/w)
#define MCFSIM_PAR 0xcb //Pin Assignment reg (r/w)
//三个线的GPIO索引,得根据硬件连接而修改
#define VAL_GPIO_INDEX_DATA 105
#define VAL_GPIO_INDEX_CLK 104
#define VAL_GPIO_INDEX_RST 103
XLLP_UINT32_T DS1302IN(unsigned char ds1302_bit)
{
XLLP_UINT32_T uiPinIndex = 0;
switch(ds1302_bit)
{
case DAT_1302: //是数据引脚
uiPinIndex = VAL_GPIO_INDEX_DATA;
break;
default: //没用的
return 0;
}
return XllpGpioGetState(g_pBaseAddressGPIORegs, uiPinIndex);
}
//write(这个函数必须改)
void DS1302(unsigned char ds1302_bit, unsigned int logical_value)
{
XLLP_UINT32_T uiArrPin[2] = {1, 0};
switch(ds1302_bit)
{
case CLK_1302: //是时钟引脚
uiArrPin[1] = VAL_GPIO_INDEX_CLK;
break;
case DAT_1302: //是数据引脚
uiArrPin[1] = VAL_GPIO_INDEX_DATA;
break;
case RST_1302: //复位引脚
uiArrPin[1] = VAL_GPIO_INDEX_RST;
break;
default: //没用的
return ;
}
if (logical_value) //写1
{
XllpGpioSetOutputState1(g_pBaseAddressGPIORegs, uiArrPin);
}
else
{
XllpGpioSetOutput0(g_pBaseAddressGPIORegs, uiArrPin);
}
}
void SetPinDirection(unsigned char p_ucPinType, BOOL p_bInput)
{
XLLP_UINT32_T uiArrPin[2] = {1, 0};
switch(p_ucPinType)
{
case CLK_1302: //是时钟引脚
uiArrPin[1] = VAL_GPIO_INDEX_CLK;
break;
case DAT_1302: //是数据引脚
uiArrPin[1] = VAL_GPIO_INDEX_DATA;
break;
case RST_1302: //复位引脚
uiArrPin[1] = VAL_GPIO_INDEX_RST;
break;
default: //没用的
return ;
}
if(p_bInput) //是输入
{
XllpGpioSetDirectionIn(g_pBaseAddressGPIORegs, uiArrPin);
}
else
{
XllpGpioSetDirectionOut(g_pBaseAddressGPIORegs, uiArrPin);
}
}
/*******************************************************************
Setup_1302_Port
Initialize Port Pins to access DS1302 Clock.
Note that all three pins are defined initialliy as outputs.
When you want to read a port pin, you have to turn it
around.
MCF5206...
PP0 = CLOCK
PP1 = RST*
PP2 = DATA
********************************************************************/
//设置管脚分配寄存器信息,就是设置GPIO之类的,跟我们关系不大
void Setup_1302_Port(void)
{
unsigned char c;
//get the current value of the Pin Assignment Register
c = *(volatile unsigned char *)(MCF_MBAR + MCFSIM_PAR);
c = c & 0xef; //PAR4 = 0, selects PP0-4 on port instead of
//BDM PST0-3
*(volatile unsigned char *)(MCF_MBAR + MCFSIM_PAR) = c;
//and make sure that we have the appropriate direction for
//the port pins
//设置三个我们相关的管脚的方向
c = *(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR);
c = c | (CLK_1302 + RST_1302 + DAT_1302); //selects all output
*(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR) = c;
Idle_1302(); /* set the port pins idle */
return;
} //end proc Setup_1302_Port()
/*******************************************************************
Read_1302_Data
Reads all 8 bytes of data from the DS1302.
Inputs: TimeBuffer- Pointer to 8 byte unsigned char array where data
will be placed once read from the clock
Returns in TimeBuffer:
TimeBuffer[0] seconds: msb=1, clock hold, BCD seconds
TimeBuffer[1] minutes: 0,BCD minutes
TimeBuffer[2] hours: msb=1,12 hour/0,24 hour, BCD hour
msb=0, 0-23 BCD
msb=1, {10}{0=am/1=pm}01-12 BCD
TimeBuffer[3] day of month: BCD day 0-31
TimeBuffer[4] month: BCD 1-12
TimeBuffer[5] day of week: BCD 1-7 1=Sunday
TimeBuffer[6] year: BCD 00-99
TimeBuffer[7] write protect: msb=1, write protect msb=0, write en
returns: 0 if all is well, non-zero if clock was stopped
NOTE: If clock was stopped, returns non-zero and time is
indicated as Jan 1, 1999, 12:00:00 Noon
********************************************************************/
//如果以后调不通,这个函数估计要加上延时
unsigned int Read_1302_Data(unsigned char * TimeBuffer)
{
unsigned char Cmd_Byte; /*clock command*/
unsigned char databyte; /*temp data byte*/
unsigned char shifter; /* bit selector */
unsigned int i,j;
//时钟拉低,数据拉低
DS1302(CLK_1302,LOW);
DS1302(DAT_1302,LOW);
//RST拉高,表示要开始数据传输了,后面的时钟变换会被送入移位寄存器
DS1302(RST_1302,HIGH);
//时钟触发方式读(先写命令)
Cmd_Byte = READ_CMD; /* set command to the 1302 for burst read operation */
shifter = 0x01;
for(i=0; i<8; i++) /* shift the read command */
{
if (shifter & Cmd_Byte)
DS1302(DAT_1302,HIGH);
else
DS1302(DAT_1302,LOW); /* set up the data line */
//参照RTC4513,这个地方好像要加延时吧????
//在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,这个上升就是要数据写入DS1302的
DS1302(CLK_1302,HIGH); //时钟由高变低,表示触发写数据????(应该是表示下一个时钟周期到来)
shifter = shifter << 1;
DS1302(CLK_1302,LOW); /* toggle the clock */
} //next i
// PB5 (DATA Line) is input
// write_word_port((unsigned long)(PIO_PBDDR+OCP_BASE),
// read_word_port((unsigned long)(PIO_PBDDR+OCP_BASE)) & (65535-DAT_1302));
//and make sure that we have the appropriate direction for
//the data port pin - to INPUT
//这里设置GPIO为输入方向,才可以确保能收到数据
SetPinDirection(DAT_1302, TRUE);
// c = *(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR);
// c = c & (0xff - DAT_1302); //selects data line as input
// *(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR) = c;
//按照协议读入所有的7个字节
for(i=0; i<8; i++) /* read in the next 7 bytes returned */
{
databyte = 0; /* start clean */
for(j=0; j<8; j++) /* read in a byte */
{
//make room for the new bit
databyte = databyte >> 1; /* shift the collected data right */
if (DS1302IN(DAT_1302)) //读数据那个比特位,不为0则认为是1
databyte |= 0x80;
else
databyte &= 0x7f; /* capture the state of the data line */
DS1302(CLK_1302,HIGH); //一高一低应该表示一个周期完成
DS1302(CLK_1302,LOW); /* clock the chip */
} //next j
TimeBuffer[i] = databyte; /* save it in the buffer */
} //next i
// //PB5 (DATA Line) is output
// write_word_port((unsigned long)(PIO_PBDDR+OCP_BASE),
// read_word_port((unsigned long)(PIO_PBDDR+OCP_BASE)) | DAT_1203);
//and make sure that we have the appropriate direction for
//the data port pin - back to OUTPUT
//设置回GPIO为OUTPUT方向,因为要写空闲状态了
// c = *(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR);
// c = c | DAT_1302; //selects data line as output
// *(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR) = c;
SetPinDirection(DAT_1302, FALSE);
//把RST拉低,其他拉高,就可以置为空闲状态了,好像DataSheet上面也没有说
Idle_1302(); /* set the port pins idle */
//clean-up of time if time is bad (like when clock is stopped...)
if (TimeBuffer[0] > 0x59)
{
//The time is bogus, make an assumption
TimeBuffer[5] = 4; //day of week: BCD 1-7 1=Sunday
TimeBuffer[6] = 0x99; //year: BCD 00-99
TimeBuffer[4] = 0x1; //month: BCD 1-12
TimeBuffer[3] = 0x1; //day of month: BCD day 0-31
TimeBuffer[1] = 0x00; //minutes: 0,BCD minutes
TimeBuffer[2] = 0x12; //hours: msb=1,12 hour/0,24 hour, BCD hour
//msb=0, 0-23 BCD
//msb=1, {10}{0=am/1=pm}01-12 BCD
TimeBuffer[0] = 0; //0 sec
//seconds: msb=1, clock hold, BCD seconds
return(1); //indicate that clock was stopped
} //end if (TimeBuffer[0] > 59)
return(0); //indicate that clock is running
} /* end Read_1302_Data() */
/********************************************************************
WRITE_1302_Data
This routine will write all 8 bytes to the 1302 clock chip.
Inputs: TimeBuffer- Pointer to 8 byte unsigned char array where data
will be placed once read from the clock
Obtains from TimeBuffer:
TimeBuffer[0] seconds: msb=1, clock hold, BCD seconds
TimeBuffer[1] minutes: 0,BCD minutes
TimeBuffer[2] hours: msb=1,12 hour/0,24 hour, BCD hour
msb=0, 0-23 BCD
msb=1, {10}{0=am/1=pm}01-12 BCD
TimeBuffer[3] day of month: BCD day 0-31
TimeBuffer[4] month: BCD 1-12
TimeBuffer[5] day of week: BCD 1-7 1=Sunday
TimeBuffer[6] year: BCD 00-99
TimeBuffer[7] write protect: msb=1, write protect
msb=0, write en
Returns: None
*********************************************************************/
void Write_1302_Data(unsigned char * TimeBuffer)
{
unsigned char Cmd_Byte; /*clock command*/
unsigned char databyte; /*temp data byte*/
unsigned char shifter; /* bit selector */
unsigned int i,j;
DS1302(CLK_1302,LOW);
DS1302(DAT_1302,LOW);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -