移植DS1302到CC3200

首先,DS1302数据读写时序如下图:

移植DS1302到CC3200_第1张图片

51单片机上的程序见附件,将其移植到CC3200上需要做的工作:

1.选择合适的GPIO作为SCLK、I/0、RST,本人选用PIN_50:SCLK(7脚)、PIN_59:I/O(6脚)、PIN_15:RST(5脚),配置相关引脚,定义引脚操作,如下所示:

//RST脚  PIN_15
#define   RST_OUT  MAP_GPIODirModeSet(GPIOA2_BASE, 0x40, GPIO_DIR_MODE_OUT)//SET RST OUTPUT
#define RST_SET  MAP_GPIOPinWrite(GPIOA2_BASE,0x40,0x40)//置高PIN_15
#define RST_CLR  MAP_GPIOPinWrite(GPIOA2_BASE,0x40,0) //拉低PIN_15


//I/O引脚       PIN_59
#define IO_OUT  MAP_GPIODirModeSet(GPIOA0_BASE, 0x10, GPIO_DIR_MODE_OUT)//SET DSIO OUTPUT
#define IO_SET MAP_GPIOPinWrite(GPIOA0_BASE,0x10,0x10)//置高PIN_59
#define IO_CLR MAP_GPIOPinWrite(GPIOA0_BASE,0x10,0)//拉低PIN_59
#define    IO_IN   MAP_GPIODirModeSet(GPIOA0_BASE, 0x10, GPIO_DIR_MODE_IN)//SET DSIO INPUT
#define    IO_Read   MAP_GPIOPinRead(GPIOA0_BASE,0x10)


//SCLK引脚 PIN_50
#define SCLK_OUT MAP_GPIODirModeSet(GPIOA0_BASE, 0x1, GPIO_DIR_MODE_OUT)//SET SCLK OUTPUT
#define SCLK_SET MAP_GPIOPinWrite(GPIOA0_BASE,0x1,0x1)//置高PIN_50
#define SCLK_CLR MAP_GPIOPinWrite(GPIOA0_BASE,0x1,0)//拉低PIN_50

2.将原始延时函数_nop_()替换掉,由于对延时要求不高,所以直接使用UtilsDelay(1),正常的1us延时应该是改为UtilsDelay(27),计算过程见博客《CC3200中1us延时的实现》;

3.读取I/O数据时,若引脚为高电平,则通过函数MAP_GPIOPinRead(GPIOA0_BASE,0x10)读取到的值为引脚的位权,PIN_59引脚读取到的值便为0x10,此时需要对数据进行处理,我采用的简便方法如下:

dat1=IO_Read;
if(dat1)
{
dat1=0x01;
}
else
{
dat1=0x0;
}

也可以定义函数进行统一的操作,函数如下(同学写的,未亲测):

 long  ReadGPIO(unsigned long ulPort, unsigned char ucPins)
{
    //
    // Check the arguments.
    //
    int Num_H=0,Num_L=0,Num=0;
    unsigned char Num_Pins;
    ASSERT(GPIOBaseValid(ulPort));
    switch(ulPort){
      case(GPIOA0_BASE):Num_H = 0;break;
      case(GPIOA1_BASE):Num_H = 1;break;
      case(GPIOA2_BASE):Num_H = 2;break;
      case(GPIOA3_BASE):Num_H = 3;break;
      case(GPIOA4_BASE):Num_H = 4;break;
    }
    Num_Pins = ucPins;
    for(Num_L=0;;Num_L++){
      Num_Pins = Num_Pins/2;
      if(Num_Pins==0)
        break;
    }
    Num = Num_H*8+Num_L;
    //
    // Return the pin value(s).
    //
    return (HWREG(ulPort + (GPIO_O_GPIO_DATA + (ucPins << 2)))&(1<< (Num % 8)))>>(Num % 8);
}

至此,就可以成功通过CC3200读取到DS1302的时间数据。

移植过程中出现的问题:最大的一个问题是一开始读取到的TIME数组的数据都为0,排查许久后才发现原因,就是读取到的某个引脚的高电平不是1,而是该引脚的位权;另外,要注意选择合适的引脚,当初将PIN_60作为RST,结果不成功,应该是引脚复用的问题。

未经许可,严禁转载!

附件1(ds1302_51.h):

#ifndef __DS1302_H_
#define __DS1302_H_


//---包含头文件---//
#include<reg51.h>
#include<intrins.h>


//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif


#ifndef uint 
#define uint unsigned int
#endif


//---定义ds1302使用的IO口---//
sbit DSIO=P3^4;
sbit RST=P3^5;
sbit SCLK=P3^6;


//---定义全局函数---//
void Ds1302Write(uchar addr, uchar dat);
uchar Ds1302Read(uchar addr);
void Ds1302Init();
void Ds1302ReadTime();


//---加入全局变量--//
extern uchar TIME[7]; //加入全局变量


#endif

附件2(ds1302_51.c):

#include"ds1302.h"


//---DS1302写入和读取时分秒的地址命令---//
//---秒分时日月周年 最低位读写位;-------//
uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};


//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
uchar TIME[7] = {0, 0x10, 0x12, 0x02, 0x02, 0x02, 0x13};


/*******************************************************************************
* 函 数 名         : Ds1302Write
* 函数功能   : 向DS1302命令(地址+数据)
* 输    入         : addr,dat
* 输    出         : 无
*******************************************************************************/


void Ds1302Write(uchar addr, uchar dat)
{
uchar n;
RST = 0;
_nop_();


SCLK = 0;//先将SCLK置低电平。
_nop_();
RST = 1; //然后将RST(CE)置高电平。
_nop_();


for (n=0; n<8; n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;//数据从低位开始传送
addr >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
for (n=0; n<8; n++)//写入8位数据
{
DSIO = dat & 0x01;
dat >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
 
RST = 0;//传送数据结束
_nop_();
}


/*******************************************************************************
* 函 数 名         : Ds1302Read
* 函数功能   : 读取一个地址的数据
* 输    入         : addr
* 输    出         : dat
*******************************************************************************/


uchar Ds1302Read(uchar addr)
{
uchar n,dat,dat1;
RST = 0;
_nop_();


SCLK = 0;//先将SCLK置低电平。
_nop_();
RST = 1;//然后将RST(CE)置高电平。
_nop_();


for(n=0; n<8; n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;//数据从低位开始传送
addr >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;//DS1302下降沿时,放置数据
_nop_();
}
_nop_();
for(n=0; n<8; n++)//读取8位数据
{
dat1 = DSIO;//从最低位开始接收
dat = (dat>>1) | (dat1<<7);
SCLK = 1;
_nop_();
SCLK = 0;//DS1302下降沿时,放置数据
_nop_();
}


RST = 0;
_nop_(); //以下为DS1302复位的稳定时间,必须的。
SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
return dat;
}


/*******************************************************************************
* 函 数 名         : Ds1302Init
* 函数功能   : 初始化DS1302.
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/


void Ds1302Init()
{
uchar n;
Ds1302Write(0x8E,0X00);//禁止写保护,就是关闭写保护功能
for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
{
Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
}
Ds1302Write(0x8E,0x80);//打开写保护功能
}


/*******************************************************************************
* 函 数 名         : Ds1302ReadTime
* 函数功能   : 读取时钟信息
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/


void Ds1302ReadTime()
{
uchar n;
for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
{
TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
}

}

附件3(ds1302_3200.h):

/*
 * ds1302.h
 *
 *  Created on: 2016年4月26日
 *      Author: Bug
 */
/*DS1302
 *PIN_50:SCLK(7脚)
 *PIN_59:I/O(6脚)
 *PIN_15:RST(5脚)
 */
#ifndef DS1302_H_
#define DS1302_H_
#include "includes.h"


//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif


#ifndef uint
#define uint unsigned int
#endif


//RST脚  PIN_15
#define   RST_OUT MAP_GPIODirModeSet(GPIOA2_BASE, 0x40, GPIO_DIR_MODE_OUT)//SET RST OUTPUT
#define RST_SET MAP_GPIOPinWrite(GPIOA2_BASE,0x40,0x40)//置高PIN_15
#define RST_CLR MAP_GPIOPinWrite(GPIOA2_BASE,0x40,0) //拉低PIN_15


//I/O引脚       PIN_59
#define IO_OUT  MAP_GPIODirModeSet(GPIOA0_BASE, 0x10, GPIO_DIR_MODE_OUT)//SET DSIO OUTPUT
#define IO_SET MAP_GPIOPinWrite(GPIOA0_BASE,0x10,0x10)//置高PIN_59
#define IO_CLR MAP_GPIOPinWrite(GPIOA0_BASE,0x10,0)//拉低PIN_59
#define    IO_IN  MAP_GPIODirModeSet(GPIOA0_BASE, 0x10, GPIO_DIR_MODE_IN)//SET DSIO INPUT
#define    IO_Read  MAP_GPIOPinRead(GPIOA0_BASE,0x10)


//SCLK引脚 PIN_50
#define SCLK_OUT MAP_GPIODirModeSet(GPIOA0_BASE, 0x1, GPIO_DIR_MODE_OUT)//SET SCLK OUTPUT
#define SCLK_SET MAP_GPIOPinWrite(GPIOA0_BASE,0x1,0x1)//置高PIN_50
#define SCLK_CLR MAP_GPIOPinWrite(GPIOA0_BASE,0x1,0)//拉低PIN_50


//---定义全局函数---//
void Ds1302Write(uchar addr, uchar dat);
uchar Ds1302Read(uchar addr);
void Ds1302Init();
void Ds1302ReadTime();


//---加入全局变量--//
extern uchar TIME[7]; //加入全局变量


#endif /* DS1302_H_ */


附件4(ds1302_3200.c):

/*
 * DS1302.c
 *
 *  Created on: 2016年4月26日
 *      Author: Bug
 */
#include"ds1302.h"
#define Delay_1us  UtilsDelay(1)


//---DS1302写入和读取时分秒的地址命令---//
//---秒分时日月周年 最低位读写位;-------//
uchar  READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
uchar  WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};


//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
uchar TIME[7] = {0, 0x10, 0x12, 0x02, 0x02, 0x02, 0x13};


/*******************************************************************************
* 函 数 名         : Ds1302Write
* 函数功能   : 向DS1302命令(地址+数据)
* 输    入         : addr,dat
* 输    出         : 无
*******************************************************************************/


void Ds1302Write(uchar addr, uchar dat)
{
uchar n;
// RST = 0;
RST_CLR;
// _nop_();
Delay_1us;


// SCLK = 0;//先将SCLK置低电平。
SCLK_CLR;
// _nop_();
Delay_1us;
// RST = 1; //然后将RST(CE)置高电平。
RST_SET;
// _nop_();
Delay_1us;


for (n=0; n<8; n++)//开始传送八位地址命令
{
// DSIO = addr & 0x01;//数据从低位开始传送
if(addr & 0x01)
IO_SET;
else
IO_CLR;
addr >>= 1;
// SCLK = 1;//数据在上升沿时,DS1302读取数据
SCLK_SET;
// _nop_();
Delay_1us;
// SCLK = 0;
SCLK_CLR;
// _nop_();
Delay_1us;
}
for (n=0; n<8; n++)//写入8位数据
{
// DSIO = dat & 0x01;
if(dat & 0x01)
IO_SET;
else
IO_CLR;
dat >>= 1;
// SCLK = 1;//数据在上升沿时,DS1302读取数据
SCLK_SET;
// _nop_();
Delay_1us;
// SCLK = 0;
SCLK_CLR;
// _nop_();
Delay_1us;
}


// RST = 0;//传送数据结束
RST_CLR;
// _nop_();
Delay_1us;
}


/*******************************************************************************
* 函 数 名         : Ds1302Read
* 函数功能   : 读取一个地址的数据
* 输    入         : addr
* 输    出         : dat
*******************************************************************************/


uchar Ds1302Read(uchar addr)
{
uchar n,dat,dat1;
// RST = 0;
RST_CLR;
// _nop_();
Delay_1us;


// SCLK = 0;//先将SCLK置低电平。
SCLK_CLR;
// _nop_();
Delay_1us;
// RST = 1;//然后将RST(CE)置高电平。
RST_SET;
// _nop_();
Delay_1us;


for(n=0; n<8; n++)//开始传送八位地址命令
{
// DSIO = addr & 0x01;//数据从低位开始传送
if(addr & 0x01)
IO_SET;
else
IO_CLR;
addr >>= 1;
// SCLK = 1;//数据在上升沿时,DS1302读取数据
SCLK_SET;
// _nop_();
Delay_1us;
// SCLK = 0;//DS1302下降沿时,放置数据
SCLK_CLR;
// _nop_();
Delay_1us;
}
// _nop_();
Delay_1us;
IO_IN;
for(n=0; n<8; n++)//读取8位数据
{
// dat1 = DSIO;//从最低位开始接收
dat1=IO_Read ;
if(dat1)
{
// UART_PRINT("dat1=%x\n\r",dat1);
dat1=0x01;
}
else
{
dat1=0x0;
}
dat = (dat>>1) | (dat1<<7);
// SCLK = 1;
SCLK_SET;
// _nop_();
Delay_1us;
// SCLK = 0;//DS1302下降沿时,放置数据
SCLK_CLR;
// _nop_();
Delay_1us;
}


// RST = 0;
RST_CLR;
// _nop_(); //以下为DS1302复位的稳定时间,必须的。
Delay_1us;
// SCLK = 1;
SCLK_SET;
// _nop_();
Delay_1us;
IO_OUT;
// DSIO = 0;
IO_CLR;
// _nop_();
Delay_1us;
// DSIO = 1;
IO_SET;
// _nop_();
Delay_1us;
// UART_PRINT("dat=%x\n\r",dat);
return dat;
}


/*******************************************************************************
* 函 数 名         : Ds1302Init
* 函数功能   : 初始化DS1302.
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/


void Ds1302Init()
{
uchar n;
Ds1302Write(0x8E,0X00);//禁止写保护,就是关闭写保护功能
for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
{
Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
}
Ds1302Write(0x8E,0x80);//打开写保护功能
}


/*******************************************************************************
* 函 数 名         : Ds1302ReadTime
* 函数功能   : 读取时钟信息
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/


void Ds1302ReadTime()
{
uchar n;
RST_OUT;
IO_OUT;
SCLK_OUT;
for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
{
TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
}


}







你可能感兴趣的:(问题,移植,ds1302,51单片机,cc3200)