⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds1302.c

📁 在PXA270上替换开发板的实时时钟RTC4513为DS1302的修改说明,自己写的,拿上来和大家共享,也希望大家提意见
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************/

/*
 *	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 + -