|
#include "bsp_rx8010sj.h"
#include "stdio.h"
#define RX8010_Write_Address 0x64
#define RX8010_Read_Address 0x65
Calendar_OBJ calendar; //日歷結(jié)構(gòu)體
u16 BCD2HEX(u8 val) //BCD轉(zhuǎn)10進(jìn)制
{
return (val-(val>>4)*6);
}
u16 B_BCD(u8 val) //十進(jìn)制轉(zhuǎn)BCD
{
return (val+(val/10)*6);
}
void RX8010_Init(void)
{
uint8_t temp;
IIC_Init();
delay_ms(40);
Write_Data(0x1F,0); //使用時(shí)鐘模塊前要把TEST位清0 并且一直為0
Read_Data(0x1E,temp);//讀0x1E的電壓
if(temp&0x02) //低電壓檢測(cè)
{
printf("vlf=1");
Write_Data(0x1E,0);
delay_us(10);
if((temp&0x02)==0)
{
printf("ture");
}
else
{
printf("false");
}
}
else
{
printf("vlf=0");
}
Write_Data(0x17,0xD8);
Write_Data(0x30,0x00);
Write_Data(0x31,0x08);
Write_Data(0x1E,0);
Write_Data(0x1F,0x40);
Set_RX8010SJ_Time(0x22,0x10,0x22,0x30,0x31,0x00,0x03);
Write_Data(0x1F,0);
}
void Set_RX8010SJ_Time(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec,u8 week)
{
u8 temp=0;
temp=B_BCD(yea);
Write_Data(0x16,temp);
temp=B_BCD(mon);
Write_Data(0x15,temp);
temp=B_BCD(da);
Write_Data(0x14,temp);
temp=hou;
Write_Data(0x12,temp);
temp=B_BCD(min);
Write_Data(0x11,temp);
temp=B_BCD(sec);
Write_Data(0x10,temp);
temp=B_BCD(week);
Write_Data(0x13,temp);
}
void Get_RX8010SJ_Time(void)
{
uint8_t temp;
Read_Data(0x16,temp);
calendar.w_year = temp;
calendar.w_year=BCD2HEX(calendar.w_year);
Read_Data(0x15,temp);
calendar.w_month=temp;
calendar.w_month=BCD2HEX(calendar.w_month);
Read_Data(0x14,temp);
calendar.w_date=temp;
calendar.w_date=BCD2HEX(calendar.w_date);
Read_Data(0x12,temp);
calendar.hour=temp;
calendar.hour&=0x3f;
calendar.hour=BCD2HEX(calendar.hour);
Read_Data(0x11,temp);
calendar.min=temp;
calendar.min=BCD2HEX(calendar.min);
Read_Data(0x10,temp);
calendar.sec=temp;
calendar.sec=BCD2HEX(calendar.sec);
Read_Data(0x13,temp);
calendar.week=temp;
calendar.week=BCD2HEX(calendar.week);
// I2C2_ByteWrite(0x0e,0x20);
// calendar.temper_H=I2C2_ByteRead(0x11);
// calendar.temper_L=(I2C2_ByteRead(0x12)>>6)*25;
}
下面是I2C的驅(qū)動(dòng)程序
#include "i2c.h"
#define RX8010_Write_Address 0x64
#define RX8010_Read_Address 0x65
static void I2C_Delay(void)
{
// uint8_t i;
/*
可用邏輯分析儀測(cè)量I2C通訊時(shí)的頻率
工作條件:CPU主頻168MHz ,MDK編譯環(huán)境,1級(jí)優(yōu)化
經(jīng)測(cè)試,循環(huán)次數(shù)為20~250時(shí)都能通訊正常
*/
delay_us(2);
// for (i = 0; i < 40; i++);
}
//初始化IIC
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_initStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
GPIO_initStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_initStructure.GPIO_OType = GPIO_OType_OD;
GPIO_initStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_initStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_initStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOH,&GPIO_initStructure);
/* 給一個(gè)停止信號(hào), 復(fù)位I2C總線上的所有設(shè)備到待機(jī)模式 */
IIC_Stop(); //總線空閑
}
//產(chǎn)生IIC起始信號(hào)
void IIC_Start(void)
{
/* 當(dāng)SCL高電平時(shí),SDA出現(xiàn)一個(gè)下跳沿表示I2C總線啟動(dòng)信號(hào) */
I2C_SDA_HIGH();
I2C_SCL_HIGH();
I2C_Delay();
I2C_SDA_LOW();
I2C_Delay();
I2C_SCL_LOW();
I2C_Delay(); //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
}
//產(chǎn)生IIC停止信號(hào)
void IIC_Stop(void)
{
I2C_SCL_LOW();
I2C_SDA_LOW();
I2C_Delay();
I2C_SCL_HIGH();//STOP:when CLK is high DATA change form low to high
I2C_Delay();
I2C_SDA_HIGH();
}
//等待應(yīng)答信號(hào)到來(lái)
//返回值:1,接收應(yīng)答失敗
// 0,接收應(yīng)答成功
uint8_t IIC_Wait_Ack(void)
{
uint8_t re;
I2C_SDA_HIGH(); //SDA設(shè)置為輸入
I2C_Delay();
I2C_SCL_HIGH();
I2C_Delay();
if(I2C_SDA_READ())
{
re = 1;
}
else
{
re = 0;
}
I2C_SCL_LOW();
I2C_Delay();
return re;
}
//產(chǎn)生一個(gè)ACK信號(hào)
void IIC_Ack(void)
{
I2C_SDA_LOW();
I2C_Delay();
I2C_SCL_HIGH();
I2C_Delay();
I2C_SCL_LOW();
I2C_Delay();
I2C_SDA_HIGH(); //CPU釋放SDA總線
}
//產(chǎn)生一個(gè)NACK信號(hào)
void IIC_NAck(void)
{
I2C_SDA_HIGH();
I2C_Delay();
I2C_SCL_HIGH();
I2C_Delay();
I2C_SCL_LOW();
I2C_Delay();;
}
//IIC發(fā)送一個(gè)字節(jié)
//返回從機(jī)有無(wú)應(yīng)答
//1,有應(yīng)答
//0,無(wú)應(yīng)答
uint8_t IIC_Send_Byte(uint8_t _ucByte)
{
int8_t i;
/* 先發(fā)送字節(jié)的高位bit7 */
for (i = 0; i < 8; i++)
{
I2C_SCL_LOW();
I2C_Delay();
if (_ucByte & 0x80)
{
I2C_SDA_HIGH();
}
else
{
I2C_SDA_LOW();
}
I2C_Delay();
I2C_SCL_HIGH();
_ucByte<<=1;
}
I2C_SCL_LOW();
I2C_Delay();
I2C_SCL_HIGH();
i=0;
while(I2C_SDA_READ())
{
if(++i>12)
{
I2C_SCL_LOW();
return 0;
}
}
I2C_SCL_LOW();
return 1;
}
//讀1個(gè)字節(jié),ack=1時(shí),發(fā)送ACK,ack=0,發(fā)送nACK
uint8_t IIC_Read_Byte(void)
{
uint8_t i;
uint8_t value;
/* 讀到第1個(gè)bit為數(shù)據(jù)的bit7 */
value = 0;
I2C_SCL_LOW();
I2C_SDA_HIGH();
for (i = 0; i < 8; i++)
{
I2C_SCL_HIGH();
I2C_Delay();
value <<= 1;
if (I2C_SDA_READ())
{
value|=1;
}
I2C_Delay();
I2C_SCL_HIGH();
I2C_Delay();
I2C_SCL_LOW();
I2C_Delay();
}
I2C_Delay();
I2C_SCL_LOW();
I2C_SDA_LOW();
return value;
}
/*
*********************************************************************************************************
* 函 數(shù) 名: i2c_CheckDevice
* 功能說(shuō)明: 檢測(cè)I2C總線設(shè)備,CPU向發(fā)送設(shè)備地址,然后讀取設(shè)備應(yīng)答來(lái)判斷該設(shè)備是否存在
* 形 參:_Address:設(shè)備的I2C總線地址
* 返 回 值: 返回值 0 表示正確, 返回1表示未探測(cè)到
*********************************************************************************************************
*/
uint8_t i2c_CheckDevice(uint8_t _Address)
{
uint8_t ucAck;
IIC_Init(); /* 配置GPIO */
IIC_Start(); /* 發(fā)送啟動(dòng)信號(hào) */
/* 發(fā)送設(shè)備地址+讀寫(xiě)控制bit(0 = w, 1 = r) bit7 先傳 */
IIC_Send_Byte(_Address | RX8010_Write_Address);
ucAck = IIC_Wait_Ack(); /* 檢測(cè)設(shè)備的ACK應(yīng)答 */
IIC_Stop(); /* 發(fā)送停止信號(hào) */
return ucAck;
}
/*
向一個(gè)地址發(fā)送內(nèi)容函數(shù)
*/
uint8_t Write_Data(u8 addr, u8 buf)
{
IIC_Start();
IIC_Send_Byte(0x64); //寫(xiě)操作指令
if(IIC_Wait_Ack()) //檢測(cè)ACK信號(hào)
{
IIC_Stop(); //發(fā)送IIC停止信號(hào)
return 1;
}
IIC_Send_Byte(addr); //寫(xiě)寄存器存儲(chǔ)地址
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(buf);
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
IIC_Stop();
return 0;
}
/*
讀一個(gè)單元的內(nèi)容,返回值: 1=操作失敗,0=操作成功
*/
uint8_t Read_Data(u8 addr,u8 buf)
{
IIC_Start();
IIC_Send_Byte(0x64); //寫(xiě)操作指令
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(addr); //發(fā)送寄存器地址
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
IIC_Start(); //Sr條件,RESTART
IIC_Send_Byte(0x65); //讀操作指令
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
buf = IIC_Read_Byte(); //讀取數(shù)據(jù)并發(fā)送ACK信號(hào)
if(IIC_Wait_Ack())
{
IIC_Stop();
return 1;
}
IIC_Stop();
return 0;
}
通過(guò)串口調(diào)試助手打印顯示出的時(shí)間在圖片上,現(xiàn)在不知道是程序哪的問(wèn)題改不對(duì)時(shí)間,希望大哥們解答一下
|
|