1、SD2405ALPI.h
#ifndef __SD2405ALPI_H__
#define __SD2405ALPI_H__
#include "stm32f10x.h"
//EEPROM/NVSRAM地址定义。尾缀为A的内部不带EEPROM存储器
#define EE_FirstPage_Address 0xA0//第一页(尾缀B、C、D、E、F型有)
#define EE_SecondPage_Address 0xA2//第二页(尾缀B、C型有)
#define EE_ThirdPage_Address 0xA4//第三页(尾缀C型)
#define EE_FourthPage_Address 0xA6//第四页(尾缀C型)
#define EE_FifthPage_Address 0xA8//第五页(尾缀C型)
#define EE_SixthPage_Address 0xAA//第六页(尾缀C型)
#define EE_SeventhPage_Address 0xAC//第七页(尾缀C型)
#define EE_EighthPage_Address 0xAE//第八页(尾缀C型)
void SD2405ALPI_bsp_Init(void);
void SD2405ALPI_I2CStop(void);
void SD2405ALPI_ClrDjs(void);
void SD2405ALPI_WriteALARM(uint8_t BCD_hour , uint8_t BCD_minute);
BOOL SD2405ALPI_I2CWriteTime(uint8_t BCD_second , uint8_t BCD_minute , uint8_t BCD_hour , uint8_t BCD_week , uint8_t BCD_day , uint8_t BCD_month , uint8_t BCD_year);
BOOL SD2405ALPI_I2CReadTime(uint8_t *BCD_second , uint8_t *BCD_minute , uint8_t *BCD_hour , uint8_t *BCD_week , uint8_t *BCD_day , uint8_t *BCD_month , uint8_t *BCD_year);
BOOL SD2405ALPI_SetDjs(uint8_t DECIMAL_djs_Minute);
#endif
// I2CWriteSerial(EE_FirstPage_Address,0,8,Sram); //Sram1数据写入EEPROM的00-07地址
// Delayms(6); //写完EEPROM以后需要延时10ms
// I2CReadSerial(EE_FirstPage_Address,0,8,data1); //读从EEPROM第一页的00地址开始读8字节数据(00-07地址)演示
2、SD2405ALPI.C
#include "SD2405ALPI.h"
#define RCC_SD2405ALPI_PORT RCC_APB2Periph_GPIOD
#define GPIO_SD2405ALPI_PORT GPIOD
#define GPIO_SD2405ALPI_SCL_Pin GPIO_Pin_1
#define GPIO_SD2405ALPI_SDA_Pin GPIO_Pin_0
#define SD2405ALPI_SCL_1() GPIO_SetBits( GPIO_SD2405ALPI_PORT, GPIO_SD2405ALPI_SCL_Pin) // SCL = 1
#define SD2405ALPI_SCL_0() GPIO_ResetBits( GPIO_SD2405ALPI_PORT, GPIO_SD2405ALPI_SCL_Pin) // SCL = 0
#define SD2405ALPI_SDA_1() GPIO_SetBits( GPIO_SD2405ALPI_PORT, GPIO_SD2405ALPI_SDA_Pin) // SDA = 1
#define SD2405ALPI_SDA_0() GPIO_ResetBits( GPIO_SD2405ALPI_PORT, GPIO_SD2405ALPI_SDA_Pin) // SDA = 0
#define SD2405ALPI_SDA_READ() GPIO_ReadInputDataBit(GPIO_SD2405ALPI_PORT, GPIO_SD2405ALPI_SDA_Pin) // 读SDA口线状态
#define SD2405ALPI_SCL_READ() GPIO_ReadInputDataBit(GPIO_SD2405ALPI_PORT, GPIO_SD2405ALPI_SCL_Pin) // 读SCL口线状态
void SD2405ALPI_bsp_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_SD2405ALPI_PORT , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_SD2405ALPI_SCL_Pin | GPIO_SD2405ALPI_SDA_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
GPIO_Init(GPIO_SD2405ALPI_PORT , &GPIO_InitStructure);
// 给一个停止信号, 复位I2C总线上的所有设备到待机模式
SD2405ALPI_I2CStop();
}
void SD2405ALPI_SDA_INPUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_SD2405ALPI_SDA_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_SD2405ALPI_PORT , &GPIO_InitStructure);
}
void SD2405ALPI_SDA_OUTPUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_SD2405ALPI_SDA_Pin;
GPIO_Init(GPIO_SD2405ALPI_PORT , &GPIO_InitStructure);
}
void SD2405ALPI_delay_us(uint8_t time)
{
uint8_t i;
for (i = 0 ; i < time ; i++)
{
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
}
}
//
//开启SD2405的I2C总线
//--------------------------------------------------------------
//启动I2C总线,当时钟SCL为高电平时,数据线SDA产生一个下降沿
//
BOOL SD2405ALPI_I2CStart(void)
{
SD2405ALPI_SDA_OUTPUT();
SD2405ALPI_SDA_1(); //发送起始条件的数据信号(释放SDA总线)
SD2405ALPI_delay_us(20);
SD2405ALPI_SCL_1();
SD2405ALPI_delay_us(50); //起始条件建立时间大于4.7us,延时
SD2405ALPI_SDA_INPUT();
if (!SD2405ALPI_SDA_READ()) //如果SDA线为低电平则总线忙,退出
return (FALSE);
SD2405ALPI_SDA_OUTPUT();
SD2405ALPI_SDA_0(); //发送起始信号
SD2405ALPI_delay_us(50);
//SD2405ALPI_SDA_INPUT(); //警告:此处如果增加SD2405ALPI_SDA_INPUT()语句,总线就出错然后返回FALSE
while (SD2405ALPI_SDA_READ()) //如果SDA线为高电平则总线出错,退出
return FALSE;
SD2405ALPI_SCL_0(); //时序图上SDA从高到低后,SCL必须回到低电平,才允许SDA上的数据改变
//钳住I2C总线准备发送或接收数据(解释:I2C 总线在空闲状态下都是被上
//拉为高电平的,所以当它们处于低电平时就表示忙的状态.)
SD2405ALPI_delay_us(10);
return (TRUE);
}
//
//关闭SD2405的I2C总线
//终止I2C总线,当时钟SCL为高电平时,数据线SDA产生一个上升沿表示I2C总线停止信号
//
void SD2405ALPI_I2CStop(void)
{
SD2405ALPI_SDA_OUTPUT();
SD2405ALPI_SDA_0(); //发送结束条件的数据信号
SD2405ALPI_delay_us(10);
SD2405ALPI_SCL_0(); //发送结束条件的时钟信号
SD2405ALPI_delay_us(30);
SD2405ALPI_SCL_1();
SD2405ALPI_delay_us(50);
SD2405ALPI_SDA_1(); //发送I2C总线结束信号
SD2405ALPI_delay_us(10);
}
//
//发送 ACK
//SCL在高电平期间,SDA被从设备拉为低电平表示应答
//
void SD2405ALPI_I2CAck(void)
{
SD2405ALPI_SDA_OUTPUT();
SD2405ALPI_SDA_0(); // CPU驱动SDA = 0
SD2405ALPI_delay_us(10);
SD2405ALPI_SCL_1();
SD2405ALPI_delay_us(50);
SD2405ALPI_SCL_0();
SD2405ALPI_delay_us(10);
}
//
//发送 NO ACK
//
void SD2405ALPI_I2CNoAck(void)
{
SD2405ALPI_SDA_OUTPUT();
SD2405ALPI_SDA_1(); // CPU驱动SDA = 1
SD2405ALPI_delay_us(10);
//SD2405ALPI_SCL_0();
//SD2405ALPI_delay_us(30);
SD2405ALPI_SCL_1();
SD2405ALPI_delay_us(50);
SD2405ALPI_SCL_0();
SD2405ALPI_delay_us(10);
}
//
//读取 ACK信号(返回为:1 = 有ACK ,0 = 无ACK)
//
BOOL SD2405ALPI_I2CWaitAck(void)
{
uint8_t errtime = 255;
SD2405ALPI_SDA_INPUT();
SD2405ALPI_SCL_0();
SD2405ALPI_delay_us(30);
SD2405ALPI_SCL_1(); // CPU驱动SCL = 1, 此时器件会返回ACK应答
SD2405ALPI_delay_us(50);
while (SD2405ALPI_SDA_READ())
{
errtime--;
SD2405ALPI_delay_us(10);
if (!errtime)
{
SD2405ALPI_delay_us(10);
SD2405ALPI_SCL_0();
SD2405ALPI_I2CStop();
return (FALSE);
}
}
SD2405ALPI_SCL_0();
SD2405ALPI_delay_us(10);
return (TRUE);
}
//
//MCU向SD2405发送一个字节(数据从高位到低位)
//
void SD2405ALPI_I2CSendByte(uint8_t data)
{
uint8_t i;
SD2405ALPI_SDA_OUTPUT();
for (i = 0 ; i < 8 ; i++)
{
SD2405ALPI_SCL_0();
SD2405ALPI_delay_us(10);
if (data & 0x80)
SD2405ALPI_SDA_1();
else
SD2405ALPI_SDA_0();
data <<= 0x01;
SD2405ALPI_delay_us(10); //保证时钟高电平周期大于 4us
SD2405ALPI_SCL_1();
SD2405ALPI_delay_us(50); //保证时钟高电平周期大于 4us
}
SD2405ALPI_SCL_0();
SD2405ALPI_delay_us(10);
}
//
//MCU从SD2405读入一字节(数据从高位到低位)
//
uint8_t SD2405ALPI_I2CReceiveByte(void)
{
uint8_t i;
uint8_t data = 0x00;
//SD2405ALPI_SDA_INPUT();
//SD2405ALPI_SDA_1(); //置数据总线为输入方式,作为接收方要释放SDA.
//SD2405ALPI_delay_us(10);
for (i = 0 ; i < 8 ; i++) //第1个读到的bit为数据的bit7
{
SD2405ALPI_SDA_OUTPUT();
SD2405ALPI_SDA_1(); //使能内部上拉,准备读取数据
SD2405ALPI_delay_us(10);
SD2405ALPI_SCL_0(); //置时钟线为低准备接收数据位
SD2405ALPI_delay_us(30); //时钟低电平周期大于4.7us
SD2405ALPI_SCL_1(); //置时钟线为高使数据有效
SD2405ALPI_delay_us(50);
SD2405ALPI_SDA_INPUT();
data <<= 0x01; //数据从高位开始读取
if (SD2405ALPI_SDA_READ())
data |= 0x01;
SD2405ALPI_delay_us(10);
}
SD2405ALPI_SCL_0();
SD2405ALPI_delay_us(10);
return (data);
}
//
//I2C写一个字节
//
BOOL SD2405ALPI_I2CWriteOneByte(uint8_t DeviceAddress , uint8_t register_address , uint8_t data)
{
if (!SD2405ALPI_I2CStart())
return (FALSE);
SD2405ALPI_I2CSendByte(DeviceAddress); //器件地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(register_address); //设置写寄存器地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(data); //写数据
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
return (TRUE);
}
//
//I2C读一个字节程序
//
uint8_t SD2405ALPI_I2CReadOneByte(uint8_t DeviceAddress , uint8_t register_address)
{
uint8_t data;
if (!SD2405ALPI_I2CStart())
return (FALSE);
SD2405ALPI_I2CSendByte(DeviceAddress);
if (!SD2405ALPI_I2CWaitAck())
{
SD2405ALPI_I2CStop();
return (FALSE);
}
SD2405ALPI_I2CSendByte(register_address); //设置要读的地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(DeviceAddress+1);
SD2405ALPI_I2CWaitAck();
data = SD2405ALPI_I2CReceiveByte(); //读数据
SD2405ALPI_I2CNoAck();
SD2405ALPI_I2CStop();
return (data);
}
//
//SD2405写允许程序
//
BOOL SD2405ALPI_WriteTimeOn(void)
{
// SD2405ALPI_I2CStart();
// SD2405ALPI_I2CSendByte(0x64);
// SD2405ALPI_I2CWaitAck();
// SD2405ALPI_I2CSendByte(0x10); //设置写地址10H
// SD2405ALPI_I2CWaitAck();
// SD2405ALPI_I2CSendByte(0x80); //置WRTC1=1
// SD2405ALPI_I2CWaitAck();
// SD2405ALPI_I2CStop();
if (!SD2405ALPI_I2CWriteOneByte(0x64 , 0x10 , 0x80)) //设置写地址10H,置WRTC1=1
return (FALSE);
//SD2405ALPI_I2CStart();
//SD2405ALPI_I2CSendByte(0x64);
//SD2405ALPI_I2CWaitAck();
//SD2405ALPI_I2CSendByte(0x0F); //设置写地址0FH
//SD2405ALPI_I2CWaitAck();
//SD2405ALPI_I2CSendByte(0x84); //置WRTC2=1,置WRTC3=1
//SD2405ALPI_I2CWaitAck();
//SD2405ALPI_I2CStop();
if (!SD2405ALPI_I2CWriteOneByte(0x64 , 0x0F , 0x84)) //设置写地址0FH,置WRTC2=1,置WRTC3=1
return (FALSE);
return (TRUE);
}
//
//SD2405写禁止程序
//
BOOL SD2405ALPI_WriteTimeOff(void)
{
//SD2405ALPI_I2CStart();
//SD2405ALPI_I2CSendByte(0x64);
//SD2405ALPI_I2CWaitAck();
//SD2405ALPI_I2CSendByte(0x0F); //设置写地址0FH
//SD2405ALPI_I2CWaitAck();
//SD2405ALPI_I2CSendByte(0x0) ; //置WRTC2,WRTC3=0
//SD2405ALPI_I2CWaitAck();
if (!SD2405ALPI_I2CWriteOneByte(0x64 , 0x0F , 0x00)) //设置写地址0FH,置WRTC2=0,置WRTC3=0
return (FALSE);
//SD2405ALPI_I2CSendByte(0x0) ; //置WRTC1=0(10H地址)
//SD2405ALPI_I2CWaitAck();
//SD2405ALPI_I2CStop();
if (!SD2405ALPI_I2CWriteOneByte(0x64 , 0x10 , 0x00)) //设置写地址10H,置WRTC1=0
return (FALSE);
return (TRUE);
}
///
//BCD转换成16进制数(例如:0x16转换成16)---读时钟使用(例如:读的秒=26代表:0x26,为BCD码,需要转换成十进制:38)
//
uint8_t BCDtoHEX(uint8_t BCD)
{
uint8_t tempData;
tempData = (BCD >> 4) * 10 + (BCD & 0x0F);
return (tempData);
}
///
//16进制数转换成BCD码(例如:16转换成0x16)---写时钟使用(写的秒=26,为十进制,需要转换成BCD码=0x26))
//
uint8_t HEXtoBCD(uint8_t HEX)
{
uint8_t tempData;
tempData = ((HEX / 10) << 0x04) + (HEX % 10);
return (tempData);
}
///
//读SD2405实时数据寄存器
//
BOOL SD2405ALPI_I2CReadTime(uint8_t *second , uint8_t *minute , uint8_t *hour , uint8_t *week , uint8_t *day , uint8_t *month , uint8_t *year)
{
if (!SD2405ALPI_I2CStart())
return (FALSE);
SD2405ALPI_I2CSendByte(0x65);
if (!SD2405ALPI_I2CWaitAck())
{
SD2405ALPI_I2CStop();
return (FALSE);
}
*second = BCDtoHEX(SD2405ALPI_I2CReceiveByte());
SD2405ALPI_I2CAck();
*minute = BCDtoHEX(SD2405ALPI_I2CReceiveByte());
SD2405ALPI_I2CAck();
*hour = BCDtoHEX(SD2405ALPI_I2CReceiveByte() & 0x3F); //hour,最高位=0:代表十二小时制;最高位=1:代表二十四小时制
SD2405ALPI_I2CAck();
*week = BCDtoHEX(SD2405ALPI_I2CReceiveByte());
SD2405ALPI_I2CAck();
*day = BCDtoHEX(SD2405ALPI_I2CReceiveByte());
SD2405ALPI_I2CAck();
*month = BCDtoHEX(SD2405ALPI_I2CReceiveByte());
SD2405ALPI_I2CAck();
*year = BCDtoHEX(SD2405ALPI_I2CReceiveByte());
SD2405ALPI_I2CNoAck(); //注:最后一个数据不应答
SD2405ALPI_I2CStop();
return (TRUE);
}
///
//写SD2405实时数据寄存器
//Android 星期对应的数字
// 1---星期天
// 2---星期一
// 3---星期二
// 4---星期三
// 5---星期四
// 6---星期五
// 7---星期六
//SD2405ALPI 星期对应的数字(7进制)
// 0---星期天
// 1---星期一
// 2---星期二
// 3---星期三
// 4---星期四
// 5---星期五
// 6---星期六
//
BOOL SD2405ALPI_I2CWriteTime(uint8_t second , uint8_t minute , uint8_t hour , uint8_t week , uint8_t day , uint8_t month , uint8_t year)
{
SD2405ALPI_WriteTimeOn();
if (!SD2405ALPI_I2CStart())
return (FALSE);
SD2405ALPI_I2CSendByte(0x64);
if (!SD2405ALPI_I2CWaitAck())
{
SD2405ALPI_I2CStop();
return (FALSE);
}
SD2405ALPI_I2CSendByte(0x00); //设置写起始地址(00H=秒寄存器)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(HEXtoBCD(second));
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(HEXtoBCD(minute));
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(HEXtoBCD(hour)|0x80); //hour ,最高位=0:代表十二小时制;最高位=1:代表二十四小时制
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(HEXtoBCD(week));
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(HEXtoBCD(day));
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(HEXtoBCD(month));
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(HEXtoBCD(year));
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
if (!SD2405ALPI_I2CStart())
return (FALSE);
SD2405ALPI_I2CSendByte(0x64);
if (!SD2405ALPI_I2CWaitAck())
{
SD2405ALPI_I2CStop();
return (FALSE);
}
SD2405ALPI_I2CSendByte(0x12); //设置写起始地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x00); //清零数字调整寄存器
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_WriteTimeOff();
return (TRUE);
}
///
//设置SD2405中断程序(设置报警时间:2012年2月14日 8:00)
//
void SD2405ALPI_WriteALARM(uint8_t hour , uint8_t minute)
{
SD2405ALPI_WriteTimeOn();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x08); //发送起始地址(0x08=分钟报警寄存器)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(HEXtoBCD(minute)); //分钟
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x09); //发送起始地址(0x09=小时报警寄存器)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(HEXtoBCD(hour)); //小时
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x0E); //发送起始地址(0x0E=报警允许寄存器)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x06); //设置报警允许(使能小时、分钟报警)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x10); //发送起始地址(0x10=CTR2控制寄存器)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x92); //设置INT中断选通(INTS1,INTS0),及报警中断总允许位(INTAE)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_WriteTimeOff();
}
///
//关闭报警中断
//
void SD2405ALPI_ClrALARM(void)
{
SD2405ALPI_WriteTimeOn();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x10); //发送起始地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x90); //清报警中断总允许位(INTAE)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_WriteTimeOff();
}
///
//设置倒计时中断(单位:分钟)
//
BOOL SD2405ALPI_SetDjs(uint8_t djs_Minute)
{
SD2405ALPI_WriteTimeOn();
if (!SD2405ALPI_I2CStart())
return (FALSE);
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
if (!SD2405ALPI_I2CWaitAck())
{
SD2405ALPI_I2CStop();
return (FALSE);
}
SD2405ALPI_I2CSendByte(0x10); //发送起始地址(0x10=CTR2控制寄存器)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0xF0); //清倒计时中断总允许位(INTDE)
SD2405ALPI_I2CWaitAck(); //【WRTC=1】写寄存器允许,【IM=1】周期性报警,【INTS1=1,INTS0=1】倒计时中断
SD2405ALPI_I2CStop(); //【INTDE=0】--->清除倒计时中断允许
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x10); //发送起始地址(0x10=CTR2控制寄存器)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0xF4); //【WRTC=1】写寄存器允许设置周期性中断(IM=1);INT中断选通(INTS1=1,INTS0=1选择倒计时中断),配置倒计时中断总允许位(INTDE=1)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x11); //发送起始地址(0x11=CTR3控制寄存器)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x30); //选择定时器频率源(TDS1=1、TDS0=1)为1/60Hz
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x13); //发送起始地址(0x13=倒计时寄存器)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(djs_Minute); //设置计数初值(单位:分钟)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_WriteTimeOff();
return (TRUE);
}
///
//关闭倒计时中断
//
void SD2405ALPI_ClrDjs(void)
{
SD2405ALPI_WriteTimeOn();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x10); //发送起始地址(0x10=CTR2控制寄存器)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0xF0); //清倒计时中断总允许位(INTDE)
SD2405ALPI_I2CWaitAck(); //【WRTC=1】写寄存器允许,【IM=1】周期性报警,【INTS1=1,INTS0=1】倒计时中断
SD2405ALPI_I2CStop(); //【INTDE=0】--->清除倒计时中断允许
SD2405ALPI_WriteTimeOff();
}
///
//设置频率中断
//
void SD2405ALPI_SetFrq(void)
{
SD2405ALPI_WriteTimeOn();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令,
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x10); //发送起始地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0xA1); //设置频率中断总允许位(INTFE)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x09); //设置2Hz频率中断总
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_WriteTimeOff();
}
///
//关闭频率中断
//
void SD2405ALPI_ClrFrq(void)
{
SD2405ALPI_WriteTimeOn();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(0x64); //发送SD2405写寄存器命令
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0x10); //发送起始地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(0xA0); //清频率中断总允许位(INTFE)
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStop();
SD2405ALPI_WriteTimeOff();
}
//|************I2C连续读多个字节************|
//|***尾缀B、C、F型读EEPROM程序(连续读)***|
BOOL SD2405ALPI_I2CReadSerial(uint8_t DeviceAddress , uint8_t Address , uint8_t length , uint8_t *ps)
{
uint8_t i;
if (!SD2405ALPI_I2CStart())
return (FALSE);
SD2405ALPI_I2CSendByte(DeviceAddress); //器件地址
if (!SD2405ALPI_I2CWaitAck())
{
SD2405ALPI_I2CStop();
return (FALSE);
}
SD2405ALPI_I2CSendByte(Address); //设置要读的寄存器地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(DeviceAddress + 1);
SD2405ALPI_I2CWaitAck();
for (i = 0 ; i < length - 1 ; i++ , ps++)
{
*ps = SD2405ALPI_I2CReceiveByte(); //读数据
SD2405ALPI_I2CAck();
}
*ps = SD2405ALPI_I2CReceiveByte();
SD2405ALPI_I2CNoAck();
SD2405ALPI_I2CStop();
return (TRUE);
}
//|******************I2C连续写多个字节******************|
//|******尾缀B、C型和F型写EEPROM程序(连续写)演示******|
BOOL SD2405ALPI_I2CWriteSerial(uint8_t DeviceAddress , uint8_t Address , uint8_t length , uint8_t *ps)
{
uint8_t i;
if (!SD2405ALPI_I2CStart())
return (FALSE);
SD2405ALPI_I2CSendByte(DeviceAddress); //器件地址(或EEPROM页地址)
if (!SD2405ALPI_I2CWaitAck())
{
SD2405ALPI_I2CStop();
return (FALSE);
}
SD2405ALPI_I2CSendByte(Address); //设置起始地址
SD2405ALPI_I2CWaitAck();
for (i = 0 ; i < length ; i++)
{
SD2405ALPI_I2CSendByte(*(ps++)); //B、C型最多连续发送16个字节数据,F型最多连续发送8个字节数据,若使
SD2405ALPI_I2CAck(); //用的是NVSRAM则无此限制,可连续写任意多个数据直到存储器的末地址。
}
SD2405ALPI_I2CStop();
return (TRUE);
}
/******尾缀D、E型写EEPROM程序(连续写)******/
void SD2405ALPI_WriteEE_DE(uint8_t sramadd_hi , uint8_t sramadd_lo , uint8_t sramdata)
{
uint8_t n;
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(EE_FirstPage_Address); //发送页地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(sramadd_hi); //先发送高8位地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(sramadd_lo); //再发送低8位地址
SD2405ALPI_I2CWaitAck();
for (n = 0 ; n < 8 ; n++)
{
SD2405ALPI_I2CSendByte(sramdata++); //D型最多连续发送32个字节数据,E型最多连续发送64个字节数据,若使用
SD2405ALPI_I2CWaitAck(); //的是NVSRAM则无此限制,可连续写任意多个数据直到存储器的末地址。
}
SD2405ALPI_I2CStop();
}
/******D、E型读EEPROM程序******/
void SD2405ALPI_ReadEE_DE(uint8_t sramadd_hi , uint8_t sramadd_lo , uint8_t m , uint8_t buffer[])
{
uint8_t n;
SD2405ALPI_I2CStart();
SD2405ALPI_I2CSendByte(EE_FirstPage_Address); //发送页地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(sramadd_hi); //先发送高8位地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CSendByte(sramadd_lo); //再发送低8位地址
SD2405ALPI_I2CWaitAck();
SD2405ALPI_I2CStart(); //重发起始信号
SD2405ALPI_I2CSendByte(EE_FirstPage_Address+1);//发送读EEPROM命令
SD2405ALPI_I2CWaitAck();
for (n = 0 ; n < m ; n++) //可读任意多个数据,直到存储器的末地址
{
buffer[n] = SD2405ALPI_I2CReceiveByte();
if (n != m-1) //最后一个数据不应答
{
SD2405ALPI_I2CAck();
}
}
SD2405ALPI_I2CNoAck();
SD2405ALPI_I2CStop();
}
// I2CWriteSerial(EE_FirstPage_Address,0,8,Sram); //Sram1数据写入EEPROM的00-07地址
// Delayms(6); //写完EEPROM以后需要延时10ms
// I2CReadSerial(EE_FirstPage_Address,0,8,data1); //读从EEPROM第一页的00地址开始读8字节数据(00-07地址)演示
3.main.c
uint8_t year = 20;
uint8_t month = 12;
uint8_t day = 01;
uint8_t week = 2;
uint8_t hour = 8;
uint8_t minute = 59;
uint8_t second = 0;
SD2405ALPI_I2CWriteTime(second , minute , hour , week , day , month , year);
SD2405ALPI_I2CReadTime(second , minute , hour , week , day , month , year);