最开始将函数从51单片机移植过来,如何整都读取出来的数据是65,不是实时时钟数据,查了下手册,发现必须4.5V-5.5V供电才可以,没有办法,跳线解决,但SCL与SDA采用3.3V+10K电阻上拉倒没有问题;
读取函数设置如下(PB12 PB13):
//初始化IIC
void IIC_Init(void)
{?? ??? ??? ??? ??? ? ? ??
?? ?GPIO_InitTypeDef GPIO_InitStructure;
?? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );?? ?
?? ? ??
?? ?GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;
?? ?GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;??
?? ?GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
?? ?GPIO_Init(GPIOB, &GPIO_InitStructure);
?? ?GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13);??
}
?
//IO方向设置;
#define IIC_SDA_PORT ? ?GPIOB
#define IIC_SDA_IO ? ?? ??? ?GPIO_Pin_13
#define IIC_SDA_RCC ? ?? ?RCC_APB2Periph_GPIOB
#define SDA_IN() ?{IIC_SDA_PORT->CRH&=0XFF0FFFFF;IIC_SDA_PORT->CRH|=0x00800000;}? ??
#define SDA_OUT() {IIC_SDA_PORT->CRH&=0XFF0FFFFF;IIC_SDA_PORT->CRH|=0x00300000;}
#define IIC_SCL_PORT ? ?GPIOB
#define IIC_SCL_IO ? ?? ??? ?GPIO_Pin_12
#define IIC_SCL_RCC ? ?? ?RCC_APB2Periph_GPIOB
#define IIC_SCL_PORT ? ?GPIOB
#define IIC_SCL_IO ? ?? ??? ?GPIO_Pin_12
#define IIC_SCL_RCC ? ?? ?RCC_APB2Periph_GPIOB
?
//2úéúIIC?eê?D?o?
void IIC_Start(void)
{
?? ?SDA_OUT(); ? ? //sda??ê?3?
?? ?IIC_SDA=1;?? ? ??? ? ?
?? ?IIC_SCL=1;
?? ?delay_us(8);
??? ?IIC_SDA=0;//START:when CLK is high,DATA change form high to low?
?? ?delay_us(8);
?? ?IIC_SCL=0;
}?? ? ?
void IIC_Stop(void)
{
?? ?SDA_OUT();
?? ?IIC_SCL=0;
?? ?IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
??? ?delay_us(8);
?? ?IIC_SCL=1;?
?? ?IIC_SDA=1;
?? ?delay_us(8);?? ??? ??? ??? ??? ??? ??? ? ? ?? ?
}
u8 IIC_Wait_Ack(void)
{
?? ?u8 ucErrTime=0;
?? ?SDA_IN();? ? ??
?? ?IIC_SDA=1;delay_us(4);?? ? ??
?? ?IIC_SCL=1;delay_us(4);?? ??
?? ?while(READ_SDA)
?? ?{
?? ??? ?ucErrTime++;
?? ??? ?if(ucErrTime>250)
?? ??? ?{
?? ??? ??? ?IIC_Stop();
?? ??? ??? ?return 1;
?? ??? ?}
?? ?}
?? ?IIC_SCL=0;//ê±?óê?3?0 ?? ? ??
?? ?return 0; ?
}?
//2úéúACKó|′e
void IIC_Ack(void)
{
?? ?IIC_SCL=0;
?? ?SDA_OUT();
?? ?IIC_SDA=0;
?? ?delay_us(8);
?? ?IIC_SCL=1;
?? ?delay_us(8);
?? ?IIC_SCL=0;
}
//2?2úéúACKó|′e?? ??? ? ? ?
void IIC_NAck(void)
{
?? ?IIC_SCL=0;
?? ?SDA_OUT();
?? ?IIC_SDA=1;
?? ?delay_us(4);
?? ?IIC_SCL=1;
?? ?delay_us(4);
?? ?IIC_SCL=0;
}?? ??? ??? ??? ??? ? ?? ??? ??? ??? ? ? ??
//IIC·¢?íò???×??ú
//·μ??′ó?úóD?Tó|′e
//1£?óDó|′e
//0£??Tó|′e?? ??? ??? ? ?
void IIC_Send_Byte(u8 txd)
{ ? ? ? ? ? ? ? ? ? ? ? ?
? ? u8 t; ??
?? ?SDA_OUT(); ?? ? ? ?
? ? IIC_SCL=0;//à-μíê±?ó?aê?êy?Y′?ê?
? ? for(t=0;t<8;t++)
? ? { ? ? ? ? ? ? ?
? ? ? ? //IIC_SDA=(txd&0x80)>>7;
?? ??? ?if((txd&0x80)>>7)
?? ??? ??? ?IIC_SDA=1;
?? ??? ?else
?? ??? ??? ?IIC_SDA=0;
?? ??? ?txd<<=1; ?? ? ?
?? ??? ?delay_us(6); ? //??TEA5767?aèy???óê±??ê?±?D?μ?
?? ??? ?IIC_SCL=1;
?? ??? ?delay_us(4);?
?? ??? ?IIC_SCL=0;?? ?
?? ??? ?delay_us(4);
? ? }?? ??
} ?? ? ? ?
//?á1??×??ú£?ack=1ê±£?·¢?íACK£?ack=0£?·¢?ínACK ??
u8 IIC_Read_Byte(unsigned char ack)
{
?? ?unsigned char i,receive=0;
?? ?SDA_IN();//SDAéè???aê?è?
? ? for(i=0;i<8;i++ )
?? ?{
? ? ? ? IIC_SCL=0;?
? ? ? ? delay_us(4);
?? ??? ?IIC_SCL=1;
? ? ? ? receive<<=1;
? ? ? ? if(READ_SDA)receive++; ??
?? ??? ?delay_us(2);?
? ? }?? ??? ??? ??? ??? ??
? ? if (!ack)
? ? ? ? IIC_NAck();//·¢?ínACK
? ? else
? ? ? ? IIC_Ack(); //·¢?íACK ??
? ? return receive;
}
unsigned char Write1307(unsigned char add,unsigned char dat)//D′ò?×??úμ???ó|μ??·è¥
{
? unsigned char temp;
? temp=dat/10;?
? temp<<=4;
? temp=dat%10+temp;
? IIC_Start();
? IIC_Send_Byte(0xD0); ? ??
? IIC_Wait_Ack();
? IIC_Send_Byte(add); ??
? IIC_Wait_Ack(); ? ?
? IIC_Send_Byte(temp); ? ??
? IIC_Stop(); ?
? return (0);
}
unsigned char Read1307(unsigned char add)
{
? unsigned char temp;
? unsigned char dat;
? IIC_Start();
? IIC_Send_Byte(0xD0);
? IIC_Wait_Ack();
? IIC_Send_Byte( add);
? IIC_Wait_Ack();
? IIC_Stop();?
? IIC_Start();
? IIC_Send_Byte(0xD1);
? IIC_Wait_Ack();?
? dat=IIC_Read_Byte(add);?
? IIC_NAck();
? IIC_Stop();
? temp=dat/16;
? dat=dat%16;
? dat=dat+temp*10;
? return(dat);
}
void NOW_RTC_TIME(void)
{
?? ??? ?second=Read1307(0x00);
?? ??? ?minute=Read1307(0x01);
?? ??? ?hour=Read1307(0x02);
?? ??? ?week=Read1307(0x03);
?? ??? ?date=Read1307(0x04);
?? ??? ?month=Read1307(0x05);
?? ??? ?year=Read1307(0x06);?? ?
}
经过把电压调整至5V之后,问题解决,如果首次使用,还必须读取秒的值看是否是second&0X80,然后设置一次时钟即可;
?? ? Write1307(0x00,0x01); //设置秒
?? ? Write1307(0x01,32);
?? ? Write1307(0x02,0x03);
?? ? Write1307(0x03,0x00);
?? ? Write1307(0x04,0x0B);
?? ? Write1307(0x05,0x04);
?? ? Write1307(0x06,0x14);//设置年
至此OL了,技术使人快乐,分享点滴,共同进步~Q~Q~417179642