一年多过去了,也没有给大家答复。
干脆,今天把我在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条评论)
登录后参与讨论