找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6304|回复: 2
打印 上一主题 下一主题
收起左侧

dspic33F系列的单片机驱动rx8025T C语言程序

[复制链接]
跳转到指定楼层
楼主
ID:59583 发表于 2014-3-21 13:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "config.h"
#include    "p33FJ256MC710.h"

/* r8025N寄存器定义 */
#define RX8025_REG_SEC          0x00
#define RX8025_REG_MIN          0x01
#define RX8025_REG_HOUR         0x02
#define RX8025_REG_WDAY         0x03
#define RX8025_REG_MDAY         0x04
#define RX8025_REG_MONTH        0x05
#define RX8025_REG_YEAR         0x06
#define RX8025_REG_RAM          0x07//#define RX8025_REG_DIGOFF       0x07  8025
#define RX8025_REG_ALWMIN       0x08
#define RX8025_REG_ALWHOUR      0x09
#define RX8025_REG_ALWWDAY      0x0a
#define RX8025_REG_TMCNT0       0x0b//#define RX8025_REG_ALDMIN       0x0b
#define RX8025_REG_TMCNT1       0x0c//#define RX8025_REG_ALDHOUR      0x0c
/* 0x0d is reserved */
#define RX8025_REG_FLAG         0x0e//#define RX8025_REG_CTRL1        0x0e
#define RX8025_REG_CTRL         0x0f//#define RX8025_REG_CTRL2         0x0f
#define RX8025_BIT_FLAG_VDET     (1<<0)//用于检测温度补偿的状态
#define RX8025_BIT_FLAG_VLF      (1<<1)//用于检测电压低的状态
typedef struct strtime{
        BYTE        cSecond;
        BYTE        cMinute;
        BYTE        cHour;
        BYTE        cMonth;
        BYTE        cWeek;
        BYTE        cDay;  
        UINT16        sYear;           
}strTIME;
BYTE rx8025_get_time(strTIME *get_time);

/* I2C定义 */
INT Time_Adjust(strTIME *dt);
BYTE is_leap_year(UINT16 year);
UINT16 bcd2bin(BYTE val);
BYTE bin2bcd(unsigned val);

VOID IdleI2C(VOID);
VOID StartI2C(VOID);
BYTE WriteI2C(BYTE byte);
VOID StopI2C(VOID);
VOID RestartI2C(VOID);
BYTE getsI2C(BYTE*, BYTE);
VOID NotAckI2C(VOID);
VOID InitI2C(VOID);
UINT16 ACKStatus(VOID);
BYTE getI2C(VOID);
VOID AckI2C(VOID);
UINT16 EEAckPolling(BYTE);
UINT16 putstringI2C(BYTE *wrptr,BYTE Write_Data_Length);
UINT32 TimeToMinute(strTIME *Time_Set);
UINT32 TimeToSecond(strTIME *Time_Set);
VOID MinuteToTime(UINT32 Minute,strTIME *T);
VOID SecondToTime(UINT32 SecondT,strTIME *T);
void TimeDir(strTIME *T);
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:读取rx8025n内部寄存器      
**  Input:               
**  Output:               
**  Attention
***********************************************************************/
UINT16 rx8025_read_regs(BYTE Add, BYTE ReadDatatLength,BYTE *Data)
{
    BYTE ErrorCode;
//        Add=Add<<4;//地址(高4位)加传送模式00(低四位)
        IdleI2C();                                                //Wait for bus Idle
        StartI2C();                                                //Generate Start condition
        WriteI2C(0x64);                        //发送写控制命令,0x64
        IdleI2C();                                                //Wait for bus Idle
      
    ErrorCode = ACKStatus();                //Return ACK Status
        WriteI2C(Add);                                //Send High Address
        IdleI2C();                                                //Wait for bus Idle
        ErrorCode = ACKStatus();                //Return ACK Status
        RestartI2C();                                        //Generate Restart
        WriteI2C(0x65);                                //发送读控制命令
        IdleI2C();                                                //Wait for bus Idle
        ErrorCode = ACKStatus();                //Return ACK Status
        getsI2C(Data,ReadDatatLength);                        //Read Length number of bytes to Data
        NotAckI2C();                                        //send Not Ack
        StopI2C();                                                //Send Stop Condition
        return(ErrorCode);      
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:写rx8025n内部寄存器      
**  Input:        ControlByte, Add, *wrptr.      
**  Output:        None      
**  Attention:先发命令地址,再发地址,最后发数据
***********************************************************************/
INT rx8025_write_regs(BYTE Add,BYTE WriteDataLength,BYTE *wrptr)
{
        BYTE ErrorCode;
//        Add=Add<<4;//地址(高4位)加传送模式00(低四位)
        IdleI2C();                                        //wait for bus Idle
        StartI2C();                                        //Generate Start condition
        WriteI2C(0x64);                          //send controlbyte for a write,0x64h
        IdleI2C();                                        //wait for bus Idle
        ErrorCode = ACKStatus();                //Return ACK Status
        WriteI2C(Add);                        //send low address
        IdleI2C();                                        //wait for bus Idle
        ErrorCode = ACKStatus();                //Return ACK Status
        putstringI2C(wrptr,WriteDataLength);                //send data
        IdleI2C();                                        //wait for bus Idle
        StopI2C();                                        //Generate Stop
        return(ErrorCode);
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:从8025N获取时间      
**  Input:               
**  Output:        None      
**  Attention:
***********************************************************************/
BYTE rx8025_get_time(strTIME *get_time)
{
    BYTE date[7];
    BYTE err;
    err = rx8025_read_regs(RX8025_REG_SEC,7,date);
    if (!err)return err; //err为0时表示错误,err=1表示正常接收
    get_time->cSecond =(BYTE)bcd2bin(date[RX8025_REG_SEC]&0x7f);
    get_time->cMinute =(BYTE)bcd2bin(date[RX8025_REG_MIN]&0x7f);
    get_time->cHour = bcd2bin(date[RX8025_REG_HOUR] & 0x3f);  
    get_time->cDay = bcd2bin(date[RX8025_REG_MDAY] & 0x3f);
    get_time->cMonth= bcd2bin(date[RX8025_REG_MONTH] & 0x1f);
    get_time->sYear= bcd2bin(date[RX8025_REG_YEAR]);
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:校正8025N的时间      
**  Input:               
**  Output:        None      
**  Attention:
***********************************************************************/  
INT Time_Adjust(strTIME *dt)
{
      
    BYTE date[7];
    //该8025假定能被4整除是闰年,但2100年不是闰年(BUG)
    date[RX8025_REG_SEC] = bin2bcd(dt->cSecond);     
    date[RX8025_REG_MIN] = bin2bcd(dt->cMinute);   
    date[RX8025_REG_HOUR] = bin2bcd(dt->cHour);   
//  date[RX8025_REG_WDAY] = bin2bcd(dt->cWeek);
    date[RX8025_REG_MDAY] = bin2bcd(dt->cDay);
    date[RX8025_REG_MONTH] = bin2bcd(dt->cMonth);
    date[RX8025_REG_YEAR] = bin2bcd(dt->sYear% 100);  
    return rx8025_write_regs(RX8025_REG_SEC,7,date);
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:BCD转BIN      
**  Input:               
**  Output:        None      
**  Attention:
***********************************************************************/  
UINT16 bcd2bin(BYTE val)
{
        return ((val&0x0f)+(val >> 4)*10);
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:BIN转BCD      
**  Input:               
**  Output:        None      
**  Attention:
***********************************************************************/  
BYTE bin2bcd(unsigned val)
{
        return ((val / 10) << 4) + val % 10;
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:判断是否为闰年      
**  Input:               
**  Output:        None      
**  Attention:
***********************************************************************/
BYTE is_leap_year(UINT16 year)
{
        return (!(year % 4) && (year % 100)) || !(year % 400);
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:初始化I2C(1)外设      
**  Input:               
**  Output:        None      
**  Attention:Sets up Master mode, No slew rate control, 100Khz
***********************************************************************/  
VOID InitI2C(VOID)
{      

    /*I2C2BRG=[(1/Fscl-PGD)*FCY]-2,当Fsc1=100khz时,1/fsc1=(1/100)*1000000=10000ns,PGD=130ns,即10000-130=9870   
     I2C2BRG=(9870*5.5296)/1000-2=52.5;*/
        I2C2BRG = 0x0034;
        //初始化IIC外设,设为主模式, No Slew Rate
      
        I2C2CONbits.I2CEN=0;// 禁止I2Cx 模块
    I2C2CONbits.DISSLW=1;//禁止斜率控制位
    I2C2CONbits.SCLREL=1;//释放SCLx时钟
      
      
        I2C2RCV = 0x0000;
        I2C2TRN = 0x0000;      
        I2C2CONbits.I2CEN=1;// 使能 I2Cx 模块,并将 SDAx 和 SCLx 引脚配置为串口引脚
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:StartI2C()      
**  Input:               
**  Output:        None      
**  Attention:        Generates an I2C Start Condition
***********************************************************************/  
VOID StartI2C(VOID)
{
        //This function generates an I2C start condition and returns status
        //of the Start.
        I2C2CONbits.SEN = 1;                //Generate Start COndition
        while (I2C2CONbits.SEN);        //Wait for Start COndition
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function: RestartI2C()      
**  Input:               
**  Output:        None      
**  Attention:Generates a restart condition and optionally returns status
***********************************************************************/
VOID RestartI2C(VOID)
{
        I2C2CONbits.RSEN = 1;                //Generate Restart               
        while (I2C2CONbits.RSEN);        //Wait for restart
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function: StopI2C()      
**  Input:               
**  Output:        None      
**  Attention:Generates a bus stop condition
***********************************************************************/
VOID StopI2C(VOID)
{
        I2C2CONbits.PEN = 1;                //Generate Stop Condition
        while (I2C2CONbits.PEN);        //Wait for Stop
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function: WriteI2C()      
**  Input:               
**  Output:        None      
**  Attention:rites a byte out to the bus
***********************************************************************/
BYTE WriteI2C(BYTE byte)
{
        //This function transmits the byte passed to the function
        while (I2C2STATbits.TRSTAT);        //Wait for bus to be idle
        I2C2TRN = byte;                                //Load byte to I2C2 Transmit buffer
        if(I2C2STATbits.IWCOL)        /* If write collision occurs,return -1 */
        return 1;
    else
    {
               while (I2C2STATbits.TBF);                //wait for data transmission        
    }
    return 0;
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function: IdleI2C()      
**  Input:               
**  Output:        None      
**  Attention:Waits for bus to become Idle
***********************************************************************/
VOID IdleI2C(VOID)
{
        while (I2C2STATbits.TRSTAT);                //Wait for bus Idle
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function: ACKStatus()      
**  Input:               
**  Output:        Acknowledge Status.      
**  Attention:Return the Acknowledge status on the bus
***********************************************************************/
UINT16 ACKStatus(VOID)
{
        return (!I2C2STATbits.ACKSTAT);                //Return Ack Status
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function: NotAckI2C()      
**  Input:        None.      
**  Output:        None.      
**  Attention:Generates a NO Acknowledge on the Bus
***********************************************************************/
VOID NotAckI2C(VOID)
{
        I2C2CONbits.ACKDT = 1;                        //Set for NotACk
        I2C2CONbits.ACKEN = 1;
        while(I2C2CONbits.ACKEN);                //wait for ACK to complete
        I2C2CONbits.ACKDT = 0;                        //Set for NotACk
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function: AckI2C()      
**  Input:        None.      
**  Output:        None.      
**  Attention:Generates an Acknowledge.
***********************************************************************/
VOID AckI2C(VOID)
{
        I2C2CONbits.ACKDT = 0;                        //Set for ACk
        I2C2CONbits.ACKEN = 1;
        while(I2C2CONbits.ACKEN);                //wait for ACK to complete
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function: getsI2C()      
**  Input:        array poINTer, Length.      
**  Output:        None.      
**  Attention:read Length number of Bytes INTo array
***********************************************************************/
BYTE getsI2C(BYTE *rdptr, BYTE Length)
{
        while (Length --)
        {
                *rdptr++ = getI2C();                //get a single byte
               
                if(I2C2STATbits.BCL)                //Test for Bus collision
                {
                        return(-1);
                }
                if(Length)
                {
                        AckI2C();                                //Acknowledge until all read
                }
        }
        return(0);
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function: getI2C()      
**  Input:        None.
**  Output:        contents of I2C2 receive buffer.      
**  Attention:Read a single byte from Bus
***********************************************************************/
BYTE getI2C(VOID)
{
        I2C2CONbits.RCEN = 1;                        //Enable Master receive
        Nop();
        while(!I2C2STATbits.RBF);                //Wait for receive bufer to be full
        return(I2C2RCV);                                //Return data in buffer
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function: putstringI2C()      
**  Input:        poINTer to array
**  Output:        None.      
**  Attention:writes a string of data upto PAGESIZE from array
***********************************************************************/
UINT16 putstringI2C(BYTE *wrptr,BYTE Write_Data_Length)
{
        BYTE i;
        for(i= 0; i <Write_Data_Length; i++)                //Transmit Data Until Pagesize
        {      
                if(WriteI2C(*wrptr))                        //Write 1 byte
                {
                        return(-3);                                //Return with Write Collision
                }      
                IdleI2C();                                        //Wait for Idle bus
                if(I2C2STATbits.ACKSTAT)
                {
                        return(-2);                                //Bus responded with Not ACK
                }
                wrptr++;
        }
        return(0);
}

//定义闰年及非闰年中每个月的天数
BYTE MonthDayNum[2][12]={{31,29,31,30,31,30,31,31,30,31,30,31},{31,28,31,30,31,30,31,31,30,31,30,31}};
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:        把时间转换为分钟(从2000年开始的时间)      
**  Input:               
**  Output:               
**  Attention
***********************************************************************/
UINT32 TimeToMinute(strTIME *Time_Set)
{
        BYTE c;
        UINT32        TimeMinute,i;
        Time_Set->sYear &= 0xFF;
      
        TimeMinute=(UINT32)525600*(UINT32)Time_Set->sYear;                        //年//525600=(60*24*365)
        c=((Time_Set->sYear-1)>>2)+1;
        TimeMinute+=(UINT32)1440*(UINT32)c;//1440=60*24
        if(Time_Set->sYear&0x03) c=1;                                        //闰年判断
        else                                         c=0;
        if (Time_Set->cMonth==0) return 0;
        for (i=0;i<(Time_Set->cMonth-1);i++) {                        //月
                TimeMinute+=(UINT32)1440*(UINT32)MonthDayNum[c][i];////1440=60*24      
        }
        if (Time_Set->cDay==0) return 0;
        TimeMinute+=((UINT32)1440*(UINT32)(Time_Set->cDay-1) );                //日
        TimeMinute+=((UINT32)60*(UINT32)Time_Set->cHour);                                        //小时
        TimeMinute+=(UINT32)(Time_Set->cMinute);                                        //分
        return TimeMinute;
}
/***********************************************************************
**  Time:        liwenjin 2012.10
**  Function:        把时间转换为秒(从2000年开始的时间)      
**  Input:               
**  Output:               
**  Attention
***********************************************************************/
UINT32 TimeToSecond(strTIME *Time_Set)
{      
        UINT32 TimeSecond;
        TimeSecond = TimeToMinute(Time_Set)*60;
        TimeSecond += Time_Set->cSecond;                                                //秒
        return TimeSecond;
}
/***********************************************************************
**  Time:               
**  Function:        分钟值转换为年月日时分秒
**  Input:               
**  Output:               
**  Attention
***********************************************************************/
VOID MinuteToTime(UINT32 Minute,strTIME *T)
{
        INT iTemp1,iTemp2,i,HourT;
        T->cSecond=0;
        HourT=Minute/60;
        T->cMinute=Minute%60;
        iTemp1=HourT/(365*24);
        iTemp2=HourT%(365*24);
        T->sYear=iTemp1;
        iTemp2-=((iTemp1>>2)+1)*24;
        if(iTemp1&0x03) iTemp1=1;                                                        //闰年判断
        else                        iTemp1=0;
        for ( i=0;i<12;i++ ) {
                if (iTemp2<MonthDayNum[iTemp1][i]*24) break;
                iTemp2-=MonthDayNum[iTemp1][i]*24;
        }
        T->cMonth=i+1;
        T->cDay=iTemp2/24;
        T->cHour=iTemp2%24;
        T->cDay++;
}
/***********************************************************************
**  Time:                       
**  Function:      
**  Input:               
**  Output:               
**  Attention
***********************************************************************/
VOID SecondToTime(UINT32 SecondT,strTIME *T)
{
        UINT32 iTemp1,iTemp2,i,sTemp,HourT;
        HourT=SecondT/3600;
        sTemp=SecondT%3600;
        T->cMinute=sTemp/60;
        T->cSecond=sTemp%60;
      
        for ( iTemp1=0;iTemp1<100;iTemp1++ ) {
                if(iTemp1&0x03) iTemp2 = 365*24;
                else iTemp2 = 366*24;
                if (HourT>=iTemp2) {
                        HourT -= iTemp2;
                }
                else {
                        break;
                }
        }
        T->sYear=iTemp1;
        if(iTemp1&0x03) iTemp1=1;                                                        //闰年判断
        else                        iTemp1=0;
        for ( i=0;i<12;i++ ) {
                if (HourT < MonthDayNum[iTemp1][i]*24) break;
                HourT -= MonthDayNum[iTemp1][i]*24;
        }
        T->cMonth = i+1;
        T->cDay = HourT/24;
        T->cHour = HourT%24;
        T->cDay++;
        iTemp2=SecondT%(7*24*3600);
        if (iTemp2>=1) T->cWeek=iTemp2-1;
        else                   T->cWeek=6;
}
void TimeDir(strTIME *T)
{
        BYTE buf[64];
        UINT16 len;      
        len = sprintf((char *)buf,"%d年%d月%d日 %d:%d:%d\r\n",T->sYear,T->cMonth,T->cDay,T->cHour,T->cMinute,T->cSecond);
        sioapi_puts(P30f6012SER2,(BYTE*)buf,(UINT)len);
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:62890 发表于 2014-6-12 17:18 | 只看该作者
你好 请教8025读取的时候 分钟寄存器的地址是0x01还是0x10;

http://www.51hei.com/bbs/dpj-24748-1.html
回复

使用道具 举报

板凳
ID:71233 发表于 2022-11-14 13:40 | 只看该作者
请问楼主有没有RX8025T的中文数据手册?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表