原创 处理器伴侣FM33256源码之1

2011-3-23 17:07 2279 11 11 分类: MCU/ 嵌入式

一年多过去了,也没有给大家答复。

干脆,今天把我在C8051F020上调试通过的代码贴上来,大家共同学习吧。大笑

/********************* FM33256.C ************************/

#include "c8051f020.h"
#include "MyType.h"

//该源程序基于C8051F020编写

//FM33256操作码>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//写允许
#define FM33256_OP_CODE_WREN 0x06
//写禁止
#define FM33256_OP_CODE_WRDI 0x04
//读状态寄存器
#define FM33256_OP_CODE_RDSR 0x05
//写状态寄存器
#define FM33256_OP_CODE_WRSR 0x01
//读存储器
#define FM33256_OP_CODE_READ 0x03
//写存储器
#define FM33256_OP_CODE_WRITE 0x02
//读处理器伴侣
#define FM33256_OP_CODE_RDPC 0x13
//写处理器伴侣
#define FM33256_OP_CODE_WRPC 0x12
//FM33256操作码<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//FM33256处理器伴侣各寄存器(地址)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
typedef enum
    {
     FM33256_RTC_ALARM_CONTROL = 0x00,
     FM33256_CAL_CONTROL       = 0x01,
     FM33256_SECOND            = 0x02,
     FM33256_MINUTE            = 0x03,
     FM33256_HOUR              = 0x04,
     FM33256_DAY               = 0x05,
     FM33256_DATE              = 0x06,
     FM33256_MONTH             = 0x07,
     FM33256_YEAR              = 0x08,
     FM33256_DOG_FLAGS         = 0x09,
     FM33256_DOG_RESTART       = 0x0A,
     FM33256_DOG_CONTROLA      = 0x0B,
     FM33256_DOG_CONTROLB      = 0x0C,
     FM33256_COUNTER_CONTROL   = 0x0D,
     FM33256_COUNTER0          = 0x0E,
     FM33256_COUNTER1          = 0x0F,
     FM33256_SN0               = 0x10,
     FM33256_SN1               = 0x11,
     FM33256_SN2               = 0x12,
     FM33256_SN3               = 0x13,
     FM33256_SN4               = 0x14,
     FM33256_SN5               = 0x15,
     FM33256_SN6               = 0x16,
     FM33256_SN7               = 0x17,
     FM33256_COMPANION_CONTROL = 0x18,
     FM33256_ALARM_SECOND      = 0x19,
     FM33256_ALARM_MINUTE      = 0x1A,
     FM33256_ALARM_HOUR        = 0x1B,
     FM33256_ALARM_DATE        = 0x1C,
     FM33256_ALARM_MONTH       = 0x1D
    }FM33256_REG;
//FM3FM33256_3256处理器伴侣各寄存器(地址)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//FM33256处理器伴侣各寄存器功能位掩码>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//RTC/闹钟控制寄存器(00H)各位
#define FM33256_R_BIT       BIT8(0) //读时间位
#define FM33256_W_BIT       BIT8(1) //写时间位
#define FM33256_CAL_BIT     BIT8(2) //校准模式位
#define FM33256_AEN_BIT     BIT8(4) //闹钟允许位
#define FM33256_CF_BIT      BIT8(5) //世纪标志位
#define FM33256_AF_BIT      BIT8(6) //闹钟标志位
#define FM33256_OSCEN_BIT   BIT8(7) //振荡器允许位
//校准控制寄存器(01H)各位
#define FM33256_CALCODE_BIT 0x1F    //校准码
#define FM33256_CALS_BIT    BIT8(5) //校准符号
//看门狗标志寄存器(09H)各位
#define FM33256_LB_BIT      BIT8(4) //电池电压低标志位
#define FM33256_POR_BIT     BIT8(5) //上电复位标志位
#define FM33256_LWDF_BIT    BIT8(6) //后期看门狗失败复位标志位
#define FM33256_EWDF_BIT    BIT8(7) //早期看门狗失败复位标志位
//看门狗控制寄存器A(0BH)各位
#define FM33256_WDST_BIT    0x1F    //看门狗StartTime位
//看门狗控制寄存器B(0CH)各位
#define FM33256_WDET_BIT    0x1F    //看门狗EndTime位
#define FM33256_WDE_BIT     BIT8(7) //看门狗允许位
//事件计数器控制寄存器(0DH)各位
#define FM33256_CP_BIT      BIT8(0) //有效边沿位
#define FM33256_POLL_BIT    BIT8(1) //查询模式位
#define FM33256_WC_BIT      BIT8(2) //写计数器允许位
#define FM33256_RC_BIT      BIT8(3) //读计数器允许位
#define FM33256_NVC_BIT     BIT8(7) //非易失/易失计数器选择位
//伴侣控制寄存器(18H)各位
#define FM33256_VTP_BIT     0x03    //VTP选择位
#define FM33256_FC_BIT      BIT8(2) //快速充电位
#define FM33256_VBC_BIT     BIT8(3) //充电控制位
#define FM33256_F_BIT       0x30    //方波频率位
#define FM33256_AL_SW_BIT   BIT8(6) //闹钟/方波选择位
#define FM33256_SNL_BIT     BIT8(7) //SN锁定位
//闹钟寄存器(19H~1DH)各位
#define FM33256_M_BIT       BIT8(7) //闹钟匹配位
//FM33256处理器伴侣各寄存器功能位掩码<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//FM33256状态寄存器功能位掩码>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define FM33256_BP_BIT      0x0C0   //存储器写保护位
#define FM33256_WEL_BIT     BIT8(1) //写允许锁存位
//FM33256状态寄存器功能位掩码<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//冻结时间类型
typedef enum
    {
     RTIME, //冻结读时间
     WTIME  //冻结写时间
    }FREEZE_TIME_TYPE;

//#define 
/***********************************************************************************************************************************
*函数名称 : cbcd_to_hex
*函数功能 : 将单字节BCD码转换为十六进制数
*输    入 : bcd -> 待转换数据
*返    回 : 转换后的十六进制数
*作    者 : 张剑勇
*完成日期 : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
INT8U cbcd_to_hex(INT8U bcd)
{
    if(bcd > 0x99)
    {
        return 0;      
    }
    return ((bcd & 0x0F) + ((bcd >> 4) * 10));
}

/***********************************************************************************************************************************
*函数名称 : chex_to_bcd
*函数功能 : 将单字节十六进制数转换为BCD码
*输    入 : hex -> 待转换数据
*返    回 : 转换后的BCD码
*作    者 : 张剑勇
*完成日期 : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
INT8U chex_to_bcd(INT8U hex)
{
    hex %= 100;
    return (((hex / 10) << 4) + (hex % 10));
}

/***********************************************************************************************************************************
*函数名称  : write_byte_to_SPI
*简要描述  : 向C8051F020的SPI接口写入一字节数据
*输     入 : dat -> 要写入的数据
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.14
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
static void write_byte_to_SPI(const INT8U dat)
{
    SPI0DAT = dat;
    while(!_testbit_(SPIF));
}

/***********************************************************************************************************************************
*函数名称  : read_byte_from_SPI
*简要描述  : 从C8051F020的SPI接口读入一字节数据
*输     入 : dat -> 要写入的数据
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.15
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
static INT8U read_byte_from_SPI(void)
{
    SPI0DAT = 0x0FF;
    while(!_testbit_(SPIF));
    return SPI0DAT;
}

/***********************************************************************************************************************************
*函数名称  : read_PC
*简要描述  : 读FM33256处理器伴侣寄存器
*输     入 : reg  -> FM33256处理器伴侣寄存器名称
*            len  -> 要读取的字节数
*            buff -> 指向输出区域
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
static void read_PC(FM33256_REG reg,INT8U len,INT8U * buff)
{
    SELECT_FM33256;                             //片选
    write_byte_to_SPI(FM33256_OP_CODE_RDPC);    //发出读伴侣操作码RDPC
    write_byte_to_SPI((INT8U)reg);              //发出寄存器地址
    while(len)
    {
        *buff = read_byte_from_SPI();           //从FM33256读出
        buff++;
        len--;
    }
    DESELECT_FM33256;                           //释放片选
}

/***********************************************************************************************************************************
*函数名称  : write_PC
*简要描述  : 写FM33256处理器伴侣寄存器
*输     入 : reg  -> FM33256处理器伴侣寄存器名称
*            len  -> 要写入的字节数
*            buff -> 指向输入区域
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
static void write_PC(FM33256_REG reg,INT8U len,INT8U * buff)
{
    SELECT_FM33256;                             //片选
    write_byte_to_SPI(FM33256_OP_CODE_WREN);    //发出写允许操作码WREN
    DESELECT_FM33256;                           //释放片选

    SELECT_FM33256;                             //片选
    write_byte_to_SPI(FM33256_OP_CODE_WRPC);    //发出写伴侣操作码WRPC
    write_byte_to_SPI((INT8U)reg);              //发出寄存器地址
    while(len)
    {
        write_byte_to_SPI(*buff);               //写入FM33256
        buff++;
        len--;
    }
    DESELECT_FM33256;                           //释放片选
}

/***********************************************************************************************************************************
*函数名称  : lock_time
*简要描述  : 锁定/解锁时间值
*输     入 : RorW = RTIME 对R位操作
*                 = WTIME 对W位操作
*            lock = TRUE  锁定
*                 = FALSE 解锁
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
static void lock_time(FREEZE_TIME_TYPE RorW,BOOLEAN lock) //reentrant
{
    INT8U uc_temp1;

    //读RTC/闹钟控制寄存器
    read_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);

    if(RorW == WTIME)
    {
        (lock ? (uc_temp1 |= FM33256_W_BIT) : (uc_temp1 &= ~FM33256_W_BIT));    //对W位操作
    }
    else
    {
        (lock ? (uc_temp1 |= FM33256_R_BIT) : (uc_temp1 &= ~FM33256_R_BIT));    //对R位操作
    }
   
    //写RTC/闹钟控制寄存器
    write_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : get_sn0
*简要描述  : 读取FM33256第0个串码
*输     入 : 无
*返     回 : FM33256第0个串码
*作     者 : 张剑勇
*完成日期  : 2009.07.23
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
INT8U get_sn0(void)
{
    INT8U uc_temp1;

    read_PC(FM33256_SN0,1,&uc_temp1);
    return uc_temp1;
}

/***********************************************************************************************************************************
*函数名称  : set_sn0
*简要描述  : 写FM33256第0个串码
*输     入 : sn -> 串码值
*返     回 : SUCCESS  -> 写成功
*            FAILURE  -> 写失败
*作     者 : 张剑勇
*完成日期  : 2009.07.23
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
BOOLEAN set_sn0(INT8U sn)
{
    INT8U uc_temp1;

    //读伴侣控制寄存器
    read_PC(FM33256_COMPANION_CONTROL,1,&uc_temp1);
    if((uc_temp1 & FM33256_SNL_BIT) == 0)
    //串码未锁定
    {
        write_PC(FM33256_COMPANION_CONTROL,1,&sn);
        return SUCCESS;
    }
    //串码已锁定
    return FAILURE;
}

/***********************************************************************************************************************************
*函数名称  : get_time
*简要描述  : 从FM33256读取时间值
*输     入 : hex_time -> 指向输出时间值的RTC_TIME结构体指针
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void get_time(RTC_TIME * hex_time)
{
    //锁定时间
    lock_time(RTIME,TRUE);
    //读出时间
    read_PC(FM33256_SECOND,3,&hex_time->second);
    //解除时间锁定
    lock_time(RTIME,FALSE);

    //将BCD格式时间转换为HEX格式时间
    hex_time->second = cbcd_to_hex(hex_time->second);
    hex_time->minute = cbcd_to_hex(hex_time->minute);
    hex_time->hour   = cbcd_to_hex(hex_time->hour);
}

/***********************************************************************************************************************************
*函数名称  : set_time
*简要描述  : 设置FM33256时间值
*输     入 : hex_time -> 时间设置目标值
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void set_time(RTC_TIME hex_time)
{
   
    //将HEX格式时间转换为BCD格式时间
    hex_time.second = chex_to_bcd(hex_time.second);
    hex_time.minute = chex_to_bcd(hex_time.minute);
    hex_time.hour   = chex_to_bcd(hex_time.hour);

    //锁定时间
    lock_time(WTIME,TRUE);
    //写入时间
    write_PC(FM33256_SECOND,3,&hex_time.second);
    //解除时间锁定
    lock_time(WTIME,FALSE);
}

/***********************************************************************************************************************************
*函数名称  : get_week
*简要描述  : 从FM33256读取星期值
*输     入 : week -> 指向输出星期值的指针
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.30
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void get_week(INT8U * week)
{
    //锁定时间
    lock_time(RTIME,TRUE);
    //读出时间
    read_PC(FM33256_DAY,1,week);
    //解除时间锁定
    lock_time(RTIME,FALSE);
}

/***********************************************************************************************************************************
*函数名称  : set_week
*简要描述  : 设置FM33256星期值
*输     入 : week -> 星期设置目标值
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.30
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void set_week(INT8U week)
{
    week &= 0x07;
    //锁定时间
    lock_time(WTIME,TRUE);
    //写入时间
    write_PC(FM33256_DAY,1,&week);
    //解除时间锁定
    lock_time(WTIME,FALSE);
}

/***********************************************************************************************************************************
*函数名称  : get_date
*简要描述  : 从FM33256读取日期值
*输     入 : hex_date -> 指向输出日期值的RTC_DATE结构体指针
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void get_date(RTC_DATE * hex_date)
{
    //锁定时间
    lock_time(RTIME,TRUE);
    //读出时间
    read_PC(FM33256_DATE,3,(INT8U *)&hex_date->date);
    //解除时间锁定
    lock_time(RTIME,FALSE);

    //将BCD格式日期转换为HEX格式日期
    hex_date->date  = cbcd_to_hex(hex_date->date);
    hex_date->month = cbcd_to_hex(hex_date->month);
    hex_date->year  = cbcd_to_hex(hex_date->year);
}

/***********************************************************************************************************************************
*函数名称  : set_date
*简要描述  : 设置FM33256日期值
*输     入 : hex_date -> 日期设置目标值
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void set_date(RTC_DATE hex_date)
{
    //将HEX格式日期转换为BCD格式日期
    hex_date.date  = chex_to_bcd(hex_date.date);
    hex_date.month = chex_to_bcd(hex_date.month);
    hex_date.year  = chex_to_bcd(hex_date.year);

    //锁定时间
    lock_time(WTIME,TRUE);
    //写入时间
    write_PC(FM33256_DATE,3,&hex_date.date);
    //解除时间锁定
    lock_time(WTIME,FALSE);
}

/***********************************************************************************************************************************
*函数名称  : set_day_alarm
*简要描述  : 设置以天为周期的闹钟
*输     入 : hex_time -> 闹钟时间目标值
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void set_day_alarm(RTC_TIME hex_time)
{
    INT16U u16_temp1;

    //禁止日、月闹钟匹配
    read_PC(FM33256_ALARM_DATE,2,(INT8U *)&u16_temp1);
    ((INT8U *)&u16_temp1)[0] |= FM33256_M_BIT;
    ((INT8U *)&u16_temp1)[1] |= FM33256_M_BIT;
    write_PC(FM33256_ALARM_DATE,2,(INT8U *)&u16_temp1);

    //将HEX格式时间转换为BCD格式时间,并使能匹配位
    hex_time.second = chex_to_bcd(hex_time.second) & ~FM33256_M_BIT;
    hex_time.minute = chex_to_bcd(hex_time.minute) & ~FM33256_M_BIT;
    hex_time.hour   = chex_to_bcd(hex_time.hour)   & ~FM33256_M_BIT;
    //写入闹钟时间
    write_PC(FM33256_ALARM_SECOND,3,&hex_time.second);
}

/***********************************************************************************************************************************
*函数名称  : get_day_alarm
*简要描述  : 读取以天为周期的闹钟值
*输     入 : hex_time -> 指向输出闹钟值的RTC_DATE结构体指针
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void get_day_alarm(RTC_TIME * hex_time)
{
    read_PC(FM33256_ALARM_SECOND,3,&hex_time->second);

    //将BCD格式时间转换为HEX格式时间
    hex_time->second = cbcd_to_hex(hex_time->second);
    hex_time->minute = cbcd_to_hex(hex_time->minute);
    hex_time->hour   = cbcd_to_hex(hex_time->hour);
}

/***********************************************************************************************************************************
*函数名称  : enable_alarm
*简要描述  : 使能/禁止闹钟
*输     入 : enable = TRUE  使能闹钟
*                   = FALSE 禁止闹钟
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void enable_alarm(BOOLEAN enable)
{
    INT8U uc_temp1;

    //读RTC/闹钟控制寄存器
    read_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);
    //设定闹钟使能/禁止
    enable ? (uc_temp1 |= FM33256_AEN_BIT) : (uc_temp1 &= ~FM33256_AEN_BIT);   
    //写RTC/闹钟控制寄存器
    write_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : check_alarm
*简要描述  : 检查闹钟
*输     入 : 无
*返     回 : TRUE  -> 闹钟已发生
*            FALSE -> 闹钟未发生
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
BOOLEAN check_alarm(void)
{
    INT8U uc_temp1;

    //读RTC/闹钟控制寄存器
    read_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);

    return uc_temp1 & FM33256_AF_BIT;
}

/***********************************************************************************************************************************
*函数名称  : clear_alarm
*简要描述  : 清除闹钟
*输     入 : 无
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void clear_alarm(void) //reentrant
{
    INT8U uc_temp1;

    //读RTC/闹钟控制寄存器
    read_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);
    //清除闹钟位
    uc_temp1 &= ~FM33256_AF_BIT;                           
    //写RTC/闹钟控制寄存器
    write_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : set_watchdog_starttime
*简要描述  : 设置看门狗的窗口定时器开始时间
*输     入 : starttime -> 开始时间为该值×25ms;设置范围0~31,对应0~775ms
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void set_watchdog_starttime(INT8U starttime)
{
    starttime &= FM33256_WDST_BIT;
    write_PC(FM33256_DOG_CONTROLA,1,&starttime);
}

/***********************************************************************************************************************************
*函数名称  : set_watchdog_endtime
*简要描述  : 设置看门狗的窗口定时器结束时间
*输     入 : endtime -> 结束时间为该值×60ms;设置范围0,1~31,设为0时禁止定时器,其余对应60~1860ms
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void set_watchdog_endtime(INT8U endtime)
{
    INT8U uc_temp1;

    //读看门狗控制寄存器B(0CH)
    read_PC(FM33256_DOG_CONTROLB,1,&uc_temp1);
    //保留WDE位
    uc_temp1 &= FM33256_WDE_BIT;
    endtime |= uc_temp1;
    //写看门狗控制寄存器B(0CH)
    endtime &= (FM33256_WDET_BIT | FM33256_WDE_BIT);
    write_PC(FM33256_DOG_CONTROLB,1,&endtime);
}

/***********************************************************************************************************************************
*函数名称  : enable_watchdog
*简要描述  : 使能/禁止看门狗
*输     入 : enable = TRUE  使能看门狗
*                   = FALSE 禁止看门狗
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void enable_watchdog(BOOLEAN enable)
{
    INT8U uc_temp1;

    //读看门狗控制寄存器B(0CH)
    read_PC(FM33256_DOG_CONTROLB,1,&uc_temp1);
    //保留endtime位
    uc_temp1 &= FM33256_WDET_BIT;
    if(enable)
    {
        uc_temp1 |= FM33256_WDE_BIT;
    }
    //写看门狗控制寄存器B(0CH)
    write_PC(FM33256_DOG_CONTROLB,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : restart_watchdog
*简要描述  : 重启看门狗定时器
*输     入 : 无
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void restart_watchdog(void)
{
    INT8U uc_temp1 = 0x0A;

    write_PC(FM33256_DOG_RESTART,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : get_reset_flag
*简要描述  : 查看FM33256监测到的复位源
*输     入 : 无
*返     回 : 复位源类型
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
FM33256_RESET_SOURCE get_reset_flag(void)
{
    INT8U uc_temp1;

    read_PC(FM33256_DOG_FLAGS,1,&uc_temp1);
    uc_temp1 &= (FM33256_EWDF_BIT | FM33256_LWDF_BIT | FM33256_POR_BIT);
    return uc_temp1;
}

/***********************************************************************************************************************************
*函数名称  : clear_reset_flag
*简要描述  : 清除FM33256监测到的复位源标志
*输     入 : 无
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void clear_reset_flag(void)
{
    INT8U uc_temp1;

    read_PC(FM33256_DOG_FLAGS,1,&uc_temp1);
    uc_temp1 &= ~(FM33256_EWDF_BIT | FM33256_LWDF_BIT | FM33256_POR_BIT);
    write_PC(FM33256_DOG_FLAGS,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : get_VBAK_state
*简要描述  : 查看FM33256备份电源状态
*输     入 : 无
*返     回 : TRUE  -> 备份电源正常
*            FALSE -> 备份电源电压低
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
BOOLEAN get_VBAK_state(void)
{
    INT8U uc_temp1;

    read_PC(FM33256_DOG_FLAGS,1,&uc_temp1);
    uc_temp1 &= FM33256_LB_BIT;
    return !uc_temp1;
}

/***********************************************************************************************************************************
*函数名称  : clear_VBAK_flag
*简要描述  : 清除FM33256备份电源状态标志
*输     入 : 无
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void clear_VBAK_flag(void)
{
    INT8U uc_temp1;

    read_PC(FM33256_DOG_FLAGS,1,&uc_temp1);
    uc_temp1 &= ~FM33256_LB_BIT;
    write_PC(FM33256_DOG_FLAGS,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : set_ACS_pin
*简要描述  : 设置FM33256 ACS引脚的功能
*输     入 : alarm = TRUE  ACS引脚由闹钟驱动
*                  = FALSE ACS引脚由方波驱动,方波频率由freq指定
*            freq -> 当ACS引脚由方波驱动时,freq指定方波频率,对应关系为:
*                    freq值 方波频率
*                      0         1Hz
*                      1       512Hz
*                      2      4096Hz
*                      3     32768Hz
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void set_ACS_pin(BOOLEAN alarm,INT8U freq)
{
    INT8U uc_temp1;

    read_PC(FM33256_COMPANION_CONTROL,1,&uc_temp1);
    if(alarm)
    {
        uc_temp1 |= FM33256_AL_SW_BIT;
    }
    else
    {
        uc_temp1 &= ~FM33256_AL_SW_BIT;
        uc_temp1 &= ~FM33256_F_BIT;
        uc_temp1 |= (freq << 4);
    }
    write_PC(FM33256_COMPANION_CONTROL,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : enable_charge
*简要描述  : 允许/禁止FM33256充电功能
*输     入 : enable = TRUE  允许充电功能
*                   = FALSE 禁止充电功能
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void enable_charge(BOOLEAN enable)
{
    INT8U uc_temp1;

    read_PC(FM33256_COMPANION_CONTROL,1,&uc_temp1);
    enable ? (uc_temp1 |= FM33256_VBC_BIT) : (uc_temp1 &= ~FM33256_VBC_BIT);
    write_PC(FM33256_COMPANION_CONTROL,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : enable_fast_charge
*简要描述  : 允许/禁止FM33256快速充电功能。该功能仅在充电功能有效时有作用
*输     入 : enable = TRUE  允许快速充电功能
*                   = FALSE 禁止快速充电功能
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void enable_fast_charge(BOOLEAN enable)
{
    INT8U uc_temp1;

    read_PC(FM33256_COMPANION_CONTROL,1,&uc_temp1);
    enable ? (uc_temp1 |= FM33256_FC_BIT) : (uc_temp1 &= ~FM33256_FC_BIT);
    write_PC(FM33256_COMPANION_CONTROL,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : set_VTP
*简要描述  : 设置FM33256低电压复位的动作点
*输     入 : threshold -> 指定低电压复位动作点
*               设定值  对应动作点
*                    0      2.60V
*                    1      2.75V
*                    2      2.90V
*                    3      3.00V
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void set_VTP(INT8U threshold)
{
    INT8U uc_temp1;

    read_PC(FM33256_COMPANION_CONTROL,1,&uc_temp1);
    uc_temp1 &= ~FM33256_VTP_BIT;
    uc_temp1 |= (threshold & FM33256_VTP_BIT);
    write_PC(FM33256_COMPANION_CONTROL,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : enable_RTC_osc
*简要描述  : 允许/禁止FM33256振荡器
*输     入 : enable = TRUE  允许
*                   = FALSE 禁止
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void enable_RTC_osc(BOOLEAN enable)
{
    INT8U uc_temp1;

    read_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);
    enable ? (uc_temp1 &= ~FM33256_OSCEN_BIT) : (uc_temp1 |= FM33256_OSCEN_BIT);
    write_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : enable_RTC_CAL
*简要描述  : 允许/禁止FM33256校准模式
*输     入 : enable = TRUE  允许
*                   = FALSE 禁止
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.23
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void enable_RTC_CAL(BOOLEAN enable)
{
    INT8U uc_temp1;

    //读RTC/闹钟控制寄存器
    read_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);
    //设定闹钟使能/禁止
    enable ? (uc_temp1 |= FM33256_CAL_BIT) : (uc_temp1 &= ~FM33256_CAL_BIT);   
    //写RTC/闹钟控制寄存器
    write_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);
}

/***********************************************************************************************************************************
*函数名称  : get_RTC_CAL
*简要描述  : 读取FM33256校准码
*输     入 : 无
*返     回 : FM33256校准码
*作     者 : 张剑勇
*完成日期  : 2009.07.23
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
INT8U get_RTC_CAL(void)
{
    INT8U uc_temp1;

    read_PC(FM33256_CAL_CONTROL,1,&uc_temp1);
    return (uc_temp1 & (FM33256_CALS_BIT | FM33256_CALCODE_BIT));
}

/***********************************************************************************************************************************
*函数名称  : set_RTC_CAL
*简要描述  : 设置FM33256校准码
*输     入 : cal_code -> 校准码
*返     回 : SUCCESS  -> 设置成功
*            FAILURE  -> 设置失败
*作     者 : 张剑勇
*完成日期  : 2009.07.23
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
BOOLEAN set_RTC_CAL(INT8U cal_code)
{
    INT8U uc_temp1;

    //读RTC/闹钟控制寄存器
    read_PC(FM33256_RTC_ALARM_CONTROL,1,&uc_temp1);
    if(uc_temp1 & FM33256_CAL_BIT)
    //校准模式位有效
    {
        write_PC(FM33256_CAL_CONTROL,1,&cal_code);
        return SUCCESS;
    }
    //校准模式位无效
    return FAILURE;
}

/***********************************************************************************************************************************
*函数名称  : get_protect_range
*简要描述  : 查看FM33256中存储器的写保护情况
*输     入 : 无
*返     回 : 存储器保护范围
*作     者 : 张剑勇
*完成日期  : 2009.07.16
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
FRAM_PROTECT_RANGE get_protect_range(void)
{
    INT8U uc_temp1;

    SELECT_FM33256;                             //片选
    write_byte_to_SPI(FM33256_OP_CODE_RDSR);    //发出读伴侣操作码RDPC
    uc_temp1 = read_byte_from_SPI();            //读一字节
    DESELECT_FM33256;                           //释放片选

    return uc_temp1 & FM33256_BP_BIT;
}

/***********************************************************************************************************************************
*函数名称  : set_protect_range
*简要描述  : 设定FM33256中存储器的写保护范围
*输     入 : range -> 指定写保护范围
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.24
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void set_protect_range(FRAM_PROTECT_RANGE range)
{
    SELECT_FM33256;                             //片选
    write_byte_to_SPI(FM33256_OP_CODE_WREN);    //发出写允许操作码WREN
    DESELECT_FM33256;                           //释放片选

    SELECT_FM33256;                             //片选
    write_byte_to_SPI(FM33256_OP_CODE_WRSR);    //发出写状态寄存器操作码WRSR
    write_byte_to_SPI(range);                   //写状态寄存器
    DESELECT_FM33256;                           //释放片选
}

/***********************************************************************************************************************************
*函数名称  : read_FRAM
*简要描述  : 读FRAM
*输     入 : start_address -> 16位起始地址
*            len           -> 要读取的字节数
*            buff          -> 指向输出缓存区
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void read_FRAM(INT16U start_address,INT16U len,INT8U * buff)
{
    SELECT_FM33256;                             //片选
    write_byte_to_SPI(FM33256_OP_CODE_READ);    //发出读存储器操作码READ
    //write_byte_to_SPI(((INT8U *)&start_address)[0]);    //高地址
    //write_byte_to_SPI(((INT8U *)&start_address)[1]);    //低地址
    write_byte_to_SPI((INT8U)(start_address >> 8));     //高地址
    write_byte_to_SPI((INT8U)start_address);            //低地址
    while(len)
    {
        *buff = read_byte_from_SPI();           //从FM33256读出
        buff++;
        len--;
    }
    DESELECT_FM33256;                           //释放片选
}

/***********************************************************************************************************************************
*函数名称  : write_FRAM
*简要描述  : 写FRAM
*输     入 : start_address -> 16位起始地址
*            len           -> 要写入的字节数
*            buff          -> 指向输入缓存区
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.27
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void write_FRAM(INT16U start_address,INT16U len,const INT8U * buff)
{
    SELECT_FM33256;                             //片选
    write_byte_to_SPI(FM33256_OP_CODE_WREN);    //发出写允许操作码WREN
    DESELECT_FM33256;                           //释放片选

    SELECT_FM33256;                             //片选
    write_byte_to_SPI(FM33256_OP_CODE_WRITE);   //发出写存储器操作码WRITE
    write_byte_to_SPI((INT8U)(start_address >> 8));     //高地址
    write_byte_to_SPI((INT8U)start_address);            //低地址
    while(len)
    {
        write_byte_to_SPI(*buff);               //写入FM33256
        buff++;
        len--;
    }
    DESELECT_FM33256;                           //释放片选
}

/***********************************************************************************************************************************
*函数名称  : fm33256_interface_init
*简要描述  : 对C8051F020与FM33256的SPI接口进行初始化
*输     入 : 无
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.14
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void fm33256_interface_init(void)
{
    /*
    //C8051F020 SPI模式0,帧长8位
    SPI0CFG &= 0x3F;
    SPI0CFG |= 0x07;
    */
    //C8051F020 SPI模式3,帧长8位
    SPI0CFG |= 0x0C7;
    //SPI时钟速率 = SYSCLK / (2 * (SPI0CKR + 1))
    SPI0CKR = 0;
    //使能C8051F020 SPI为主方式
    SPI0CN |= 0x03;
}

/***********************************************************************************************************************************
*函数名称  : fm33256_init
*简要描述  : FM33256初始化
*输     入 : 无
*返     回 : 无
*作     者 : 张剑勇
*完成日期  : 2009.07.30
*-----------------------------------------
*修改人    :
*修改描述  :
*修改日期1 :
******************************************/
void fm33256_init(void)
{
    //对C8051F020与FM33256的SPI接口进行初始化
    fm33256_interface_init();

    //是否首次上电或后备电池是否失效过
    if(get_VBAK_state() == FALSE)
    {
        RTC_TIME time_temp;
        RTC_DATE date_temp;

        //初始化电池备份的寄存器
        enable_RTC_osc(TRUE);   //启动振荡器
        enable_RTC_CAL(FALSE);  //禁止校准模式

        time_temp.second = 0;   //初始化时间
        time_temp.minute = 0;
        time_temp.hour   = 0;
        set_time(time_temp);

        set_week(4);            //初始化星期

        date_temp.date  = 1;    //初始化日期
        date_temp.month = 1;
        date_temp.year  = 9;
        set_date(date_temp);

        time_temp.second = 0;   //初始化闹钟
        time_temp.minute = 0;
        time_temp.hour   = 8;
        set_day_alarm(time_temp);

        enable_alarm(FALSE);    //禁止闹钟
        clear_alarm();          //清除闹钟

        clear_reset_flag();     //清除复位源标志
        enable_charge(FALSE);      //禁止充电
        enable_fast_charge(FALSE); //禁止快速充电

        clear_VBAK_flag();      //清除电池失效位
    }
    //enable_alarm(TRUE);         //使能闹钟
    FM33256_ALARM_INT_MODE;     //FM33256 闹钟中断触发方式配置
    CLEAR_FM33256_ALARM_INT;
    //ENABLE_FM33256_ALARM_INT;   //允许FM33256 闹钟中断

    restart_watchdog();
    set_watchdog_starttime(0);  //设置看门狗的窗口定时器开始时间
    set_watchdog_endtime(20);   //设置看门狗的窗口定时器结束时间
#ifdef DEBUG
    enable_watchdog(FALSE);     //调试状态下禁止看门狗
#else
    enable_watchdog(TRUE);      //启动看门狗
#endif
}

/************** End of file *************/
 

文章评论0条评论)

登录后参与讨论
我要评论
0
11
关闭 站长推荐上一条 /2 下一条