各位对I2C协议比较懂得朋友帮忙看下时序,如果能解决的,有偿服务亦可,可联系我XYZTZ_COM(微信号)联系我,程序如下 ,使用的是STM32F103C8T6的PB6-SCL PB7-SDA;模拟,外接上拉10K电阻,程序如下:
#define DS1307_SDA_PORT GPIOB
#define DS1307_SDA_IO GPIO_Pin_7
#define DS1307_SDA_RCC RCC_APB2Periph_GPIOB
#define DS1307_SCLK_PORT GPIOB
#define DS1307_SCLK_IO GPIO_Pin_6
#define DS1307_SCLK_RCC RCC_APB2Periph_GPIOB
#define DS1307_SDA_ON GPIO_SetBits(DS1307_SDA_PORT,DS1307_SDA_IO)
#define DS1307_SDA_OFF GPIO_ResetBits(DS1307_SDA_PORT,DS1307_SDA_IO)
#define DS1307_SCLK_ON GPIO_SetBits(DS1307_SCLK_PORT,DS1307_SCLK_IO)
#define DS1307_SCLK_OFF GPIO_ResetBits(DS1307_SCLK_PORT,DS1307_SCLK_IO)
#define READ_DS1307_SDA GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)
#define DS1307_SDA_IN() {DS1307_SDA_PORT->CRL&=0X0FFFFFFF;DS1307_SDA_PORT->CRL|=(u32)8<<28;}
#define DS1307_SDA_OUT() {DS1307_SDA_PORT->CRL&=0X0FFFFFFF;DS1307_SDA_PORT->CRL |=(u32)3<<28;}
void DS1307_Pin_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//OD
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB6,PB7¸ß
}
void IC_START(void)
{
DS1307_SDA_OUT();
DS1307_SDA_ON;
DS1307_SCLK_ON ;
delay_us(4);
DS1307_SDA_OFF;
delay_us(4);
DS1307_SCLK_OFF;
}
void IC_STOP(void)
{
DS1307_SDA_OUT();
DS1307_SCLK_OFF;
DS1307_SDA_OFF;
delay_us(4);
DS1307_SCLK_ON;
DS1307_SDA_ON;
delay_us(4);
}
u8 I2C_wait_ack(void)
{
u8 ucerrtime=0;
DS1307_SDA_OUT();
delay_us(5);
DS1307_SDA_ON;
delay_us(5);
DS1307_SDA_IN();
DS1307_SCLK_ON;
delay_us(5);
while(READ_DS1307_SDA)
{
ucerrtime++;
if(ucerrtime>250)
{
IC_STOP();
return 1;
}
}
DS1307_SCLK_OFF;
return 0;
}
void I2C_Ack(void)
{
DS1307_SCLK_OFF;
DS1307_SDA_OUT();
delay_us(20);
DS1307_SDA_OFF;
delay_us(20);
DS1307_SCLK_ON;
delay_us(20);
DS1307_SCLK_OFF;
}
void I2C_NAck(void)
{
DS1307_SCLK_OFF;
DS1307_SDA_OUT();
delay_us(20);
DS1307_SDA_ON;
delay_us(20);
DS1307_SCLK_ON;
delay_us(20);
DS1307_SCLK_OFF;
}
void I2C_write_byte(unsigned char dat)
{
unsigned char i;
DS1307_SDA_OUT();
DS1307_SCLK_OFF;
for (i=0;i<8;i++)
{
//delay_us(10);
if((dat&0x80) >> 7) //ouyang
//if(dat&0x80)
{
DS1307_SDA_ON;
}
else
{
DS1307_SDA_OFF;
}
dat<<=1;
delay_us(20);
DS1307_SCLK_ON;
delay_us(20);
DS1307_SCLK_OFF;
delay_us(20);
}
//DS1307_SCLK_OFF;
//delay_us(1);
}
unsigned char I2C_read_byte(void)
{
unsigned char i,dat=0;
DS1307_SDA_IN();
delay_us(4);
for (i=0;i<7;i++)
{
DS1307_SCLK_OFF;
delay_us(20);
DS1307_SCLK_ON;
delay_us(20);
dat <<= 1;
if(READ_DS1307_SDA)
{
//dat |= 0x01;
dat++;
}
delay_us(3);
}
//if(!aaa)
//{I2C_NAck();}
//else
//{I2C_Ack();}
return (dat);
}
unsigned char Write1307(unsigned char add, unsigned char dat)
{
unsigned char temp;
temp=dat/10;
temp<<=4;
temp=dat%10+temp;
IC_START();
I2C_write_byte(0xD0);
delay_us(10);
I2C_wait_ack();
I2C_write_byte(add);
delay_us(10);
I2C_wait_ack();
I2C_write_byte(temp);
delay_us(10);
//I2C_send_ack(1);
IC_STOP();
//delay_us(10);
return (0);
}
unsigned char Read1307(unsigned char add)
{
unsigned char temp,dat;
IC_START();
I2C_write_byte(0xD0);
delay_us(10);
I2C_wait_ack();
I2C_write_byte(add);
delay_us(10);
I2C_wait_ack();
IC_STOP();
delay_us(10);
IC_START();
I2C_write_byte(0xD1);
delay_us(10);
I2C_wait_ack();
dat=I2C_read_byte();
delay_us(10);
I2C_NAck(); //·ÇÓ¦´ð£»
IC_STOP();
temp=dat/16;
dat=dat%16;
dat=dat+temp*10;
return (dat);
}
void Read_RTC(void)
{
unsigned char i,*p;
p=rtc_address;
for(i=0;i<7;i++)
{
read_rtc_code[i]=Read1307(*p);
p++;
}
}
void Set_RTC(void)
{
unsigned char i,*p;
p=rtc_address;
for(i=0;i<7;i++)
{
Write1307(*p,set_rtc_code[i]);
p++;
}
}
void refresh(void)
{
Read_RTC();//刷新时钟
second=read_rtc_code[0];
minute=read_rtc_code[1];
hour=read_rtc_code[2];
week=read_rtc_code[3];
date=read_rtc_code[4];
month=read_rtc_code[5];
year=read_rtc_code[6];
}
|