【项目15—任务20—小组18】DS3231——IIC的使用及源码实现

DS3231——IIC的使用及源码实现

一、IIC

IIC数据有效性:只有在SCL线为低时,SDA线才允许改变电平。

1、初始宏定义如下:

#define DS_SCL  BIT6       //DS_SCL = P1.6

#define DS_SDA  BIT5       //DS_SDA = P1.5

#define DS_SCL_IN           P1DIR &= ~DS_SCL

#define DS_SCL_OUT        P1DIR |= DS_SCL

#define DS_SCL_L             P1OUT &= ~DS_SCL

#define DS_SCL_H            P1OUT |= DS_SCL

#define DS_SDA_IN          P1DIR &= ~DS_SDA

#define DS_SDA_OUT       P1DIR |= DS_SDA

#define DS_SDA_L            P1OUT &= ~DS_SDA

#define DS_SDA_H           P1OUT |= DS_SDA

#define DS_SDA_BIT        P1IN & DS_SDA

#define DS_SDA_IN_H      P1REN |= DS_SDA 


二、IIC时序


【项目15—任务20—小组18】DS3231——IIC的使用及源码实现_第1张图片
IIC时序图

2.1 开始与结束



【项目15—任务20—小组18】DS3231——IIC的使用及源码实现_第2张图片

从时序图可以看出来,开始信号为SCL为高时,SDA由高变低;结束信号为SCL为低时,SDA由低变高。

函数名称:DS_Start

功    能:I2C起始数据

参    数:无

返回值  :无

voidDS_Start(void)

{

DS_SDA_OUT;          //设置IO口方向

DS_SCL_OUT;DS_SCL_H;            //SCL、SDA先拉高

Delay_us(5);         //delay应该有个最小时间要求

DS_SDA_H;

Delay_us(5);

DS_SDA_L;            //SDA拉低表明开始

Delay_us(5);

DS_SCL_L;            //SCL拉低,数据传输准备就绪

Delay_us(5);


函数名称:DS_Stop

功    能:I2C终止数据

参    数:无

返回值  :无

void DS_Stop(void)

{

DS_SDA_OUT;          //设置IO口方向

DS_SCL_OUT;

DS_SCL_L;            //先把SCL、SDA拉低,给结束信号做准备

Delay_us(5);

DS_SDA_L;

Delay_us(5);

DS_SCL_H;            //SCL拉高

Delay_us(5);

DS_SDA_H;            //当SCL为高,SDA由低变高为结束信号

Delay_us(1);

}


2.2 发送数据与读数据:


【项目15—任务20—小组18】DS3231——IIC的使用及源码实现_第3张图片

由图可知,开始信号后,应把SCL拉低,准备数据传输,SDA电平变化后,再拉高SCL,发送数据(最高位先发送),循环8次(一个字节)。

读取函数同理,只不过过程是反的,SDA是输入,主机做接收端。

函数名称:DS_Send_Byte

功    能:I2C发送数据

参    数:data

返回值  :data

void DS_Send_Byte(u8 data)

{

DS_SDA_OUT;           //设置IO口输出方向

DS_SCL_OUT;

DS_SCL_L;             //SCL为低时,允许SDA改变电平

unsigned char temp;

for(temp=0x80;temp!=0;temp>>=1) 

   { 

  if(temp&data==0)    //高位先发   

 {      DS_SDA_L;       }     

 else    {     DS_SDA_H;     }  

  Delay_us(5);    

  DS_SCL_H;     //SCL拉高发送数据 

  Delay_us(5);      

  DS_SCL_L;   

 }


函数名称:DS_Read

功    能:I2C接收数据

参    数:data

返回值  :data

unsigned char DS_Read(void)

{  

unsigned char temp;  

unsigned char data; 

 DS_SDA_IN;              //主机做接收,SDA线为输入  

DS_SDA_IN_H ;   

for(temp=0x80;temp!=0;temp>>=1)  

{   

DS_SCL_H;              //SCL拉高,保证接收数据时SDA不改变   

Delay_us(5);   

if(DS_SDA_BIT==1)    

 {    

data|=temp;           //高电平保留 

   }    

else    

{    

data&=~temp;   

}   

DS_SCL_L;              //SCL拉低,数据准备   

}   

return data;


2.3 主机应答信号与非应答信号:


【项目15—任务20—小组18】DS3231——IIC的使用及源码实现_第4张图片

主机接收完从机数据后,要发送应答或者非应答信号。

函数名称:DS_Ack

功    能:I2C发送应答信号

参    数:无

返回值  :无

void DS_Ack(void)

{

DS_SDA_OUT;    //主机为接收端   发送应答信号

DS_SCL_L;        //SCL拉低,允许SDA改变电平

DS_SDA_L;       //SDA低电平为应答

DS_SCL_H;

Delay_us(5);

DS_SCL_L;

}


函数名称:DS_NAck

功    能:I2C发送非应答信号

参    数:无

返回值  :无

void DS_NAck(void)

{

DS_SDA_OUT;   //此时,相当于主机在接收数据,是被动方

DS_SCL_L;     //SCL拉低,允许SDA改变电平

DS_SDA_H;     //SDA高电平为非应答

DS_SCL_H;

Delay_us(5);

DS_SCL_L;


2.4 主机接收从机应答信号:

从机在接收主机数据后,从机要发送一个应答信号,主机判断此应答信号为应答信号或者非应答信号,做下一步处理。

函数名称:DS_Get_Ack

功    能:I2C接收应答信号

参    数:无

返回值  :ack

uchar DS_Get_Ack(void)

{

   unsigned char ack;

   DS_SDA_IN;         //释放数据线,准备接收应答

   DS_SDA_IN_H ;      //SDA线输入上拉

   DS_SCL_H;          //SCL线拉高

   if(DS_SDA_BIT==1)

    {

    ack=0;//无应答信号

    }

   else

    {

    ack=1;//有应答信号

    }

   DS_SCL_L;

   Delay_us(5);

}


二、DS3231传输时序


由图可知,在发送开始信号后,DS3231接收的第一个字节的前7位是从机地址,即DS3231地址,第八位为读/写操作。


【项目15—任务20—小组18】DS3231——IIC的使用及源码实现_第5张图片
【项目15—任务20—小组18】DS3231——IIC的使用及源码实现_第6张图片


【项目15—任务20—小组18】DS3231——IIC的使用及源码实现_第7张图片

从DS3231的数据手册中可以看出来,DS3231的地址为1101000,所以主机操作的写地址为0XD1,读地址为0XD0。(不要写反)读寄存器指针的方式是开始信号-写器件地址-写寄存器地址-开始信号-接收数据-停止。

函数名称:DS3231_WriteByte

功    能:I2C总线给DS3231发送单字节

参    数:WriteAddrDataToWrite

返回值  :无

void DS3231_WriteByte(u8 WriteAddr,u8DataToWrite)

{

DS_Start();

DS_Send_Byte(0XD1);       //发送器件地址   

DS_Get_Ack();

DS_Send_Byte(WriteAddr);  //发送首地址

DS_Get_Ack();

DS_Send_Byte(DataToWrite);//发送数据

DS_Get_Ack();

DS_Stop();

Delay_ms(1);

}


函数名称:DS3231_ReadByte

功    能:I2C总线从DS3231接收单字节

参    数:ReadAddrDataToRead

返回值  :Data

uchar DS3231_ReadByte(u8 ReadAddr)

{

 uchar R_Data=0;

 DS_Start();

 DS_Send_Byte(0XD0);//读地址

 DS_Ack();

 DS_Send_Byte(ReadAddr);

 DS_Ack();

 DS_Start();

 DS_Send_Byte(0XD1);

 R_Data=DS_Read();

 Delay_us(5);

 DS_NAck();

 DS_Stop();

 return R_Data;

}


函数名称:Readtime

功    能:读取DS3231时间

参    数:R_tmpdate

返回值  :无

void Read_RTC()

{  unsigned char rtc_address[6]={0x00,0x01,0x02,0x04,0x05,0x06};

   unsigned char R_tmpdate[6];

   unsigned char i,*p;

    p=rtc_address;             //地址传递

   for(i=0;i<6;i++)            //分6次读取秒分时日月年

    {

     R_tmpdate[i]=DS3231_ReadByte(*p);

     p++;

    }

}



void ModifyTime(uchar yea,uchar mon,ucharda,uchar hou,uchar min,uchar sec)

{

 uchar temp=0;


 DS3231_WriteByte(0x06,temp);//修改年


 DS3231_WriteByte(0x05,temp);//修改月


 DS3231_WriteByte(0x04,temp);//修改日


 DS3231_WriteByte(0x02,temp);//修改时


 DS3231_WriteByte(0x01,temp);//修改分


 DS3231_WriteByte(0x00,temp);//修改秒

}

你可能感兴趣的:(【项目15—任务20—小组18】DS3231——IIC的使用及源码实现)