×
单片机 > 单片机程序设计 > 详情

PIC单片机-普通IO口模拟I2C总线对24C02进行读写操作

发布时间:2020-06-08 发布时间:
|

使用PIC单片机的普通IO口模拟I2C总线,对24C02进行读写操作。其中,总线定义为:


#define       IIC_SCLK     RC3      //24C02时钟线

#define      IIC_SDAT     RC4      //24C02数据线

将跳线帽P11短接至24C02方向,将跳线帽P6段接至IIC方向。


I2C 总线协议规定任何将数据传送到总线的器件作为发送器,任何从总线接收数据的器件为接收器,数据传送是由产生串行时钟和所有起始停止信号的主器件控制的,主器件和从器件都可以作为发送器或接收器。


I2C 总线协议定义如下:


1、只有在总线空闲时才允许启动数据传送


2、在数据传送过程中当时钟线为高电平时数据线必须保持稳定状态不允许有跳变时钟线为高电平时数据线的任何电平变化将被看作总线的起始或停止信号


起始信号:时钟线保持高电平期间数据线电平从高到低的跳变作为I2C 总线的起始信号。

停止信号:时钟线保持高电平期间数据线电平从低到高的跳变作为I2C 总线的停止信号。

#include

 

#define uint8 unsigned char

#define uint16 unsigned int

 

__CONFIG(FOSC_HS &WDTE_OFF &BOREN_OFF &PWRTE_OFF &LVP_OFF); //设置配置位

//WDTE_OFF:disable watchdog timer       看门狗禁止

//LVP_OFF:low voltage programming disabled  低电压编程禁止

//FOSC_HS:high speed crystal/resonator  4M以上晶振选择HS高速

//PWRTDIS:disable power up timer

//BOREN_OFF:disable brown out reset

 

/********************定义数据线************************************************/

 

#define     IIC_SCLK    RC3     //24C02时钟线

#define     IIC_SDAT    RC4     //24C02数据线

 

/********************定义全局变量**********************************************/

const uint8 disp[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; //0~9共阳数码管段码表

uint8 init[8] = {0x59, 0x43, 0x21, 0x11, 0x03, 0x03, 0x09, 0x00};           //EEPROM写初始值数组

uint8 recive[8];    //读EEPROM数据存放数组

 

/********************函数声明**************************************************/

 

void IIC_WriteACK(void);            //返回应答信号

void IIC_Stop(void);                //停止信号

void IIC_Writenoack(void);          //无应答信号

void IIC_Start(void);               //启动信号

void DelayUS(uint8 delay);          //微妙延时

void DelayMS(uint16 delay);         //毫秒延时

uint8 IIC_ReadByte(void);           //IIC读8位字节数据

uint8 IIC_WriteByte(uint8 data);    //IIC写8位字节数据

void Display(uint8 chosebit, uint8 data);

void IIC_Read_Mulit_Data(uint8 commond, uint8 address, uint8 *addrpoint, uint8 bytenum);

void IIC_Write_Mulit_Data(uint8 commond, uint8 reg_addr, uint8 *mdatapointer, uint8 bytenum);

 

/*******************************************************************************

* 函 数 名: DelayUS(uint8 delay)

* 函数功能: 微秒延时    for 20MHZ

* 入口参数: delay

* 返    回: 无

*******************************************************************************/

 

void DelayUS(uint8 delay)

{

    while(--delay);

}

 

/*******************************************************************************

* 函 数 名: DelayMS(uint16 delay)

* 函数功能: 毫秒延时    for20MHZ

* 入口参数: delay

* 返    回: 无

*******************************************************************************/

 

void DelayMS(uint16 delay)

{

    uint16 i;

    for(; delay > 0; delay--)

        for(i = 0; i < 453; i++);

}

 

/******************************************************************************

* 函 数 名: IIC_WriteACK(void)

* 函数功能: 从机接收数据正常时,向主机发送应答信号

* 入口参数: 无

* 返    回: 无

*******************************************************************************/

 

void IIC_WriteACK(void)

{

    IIC_SDAT = 0;           //拉低数据线,给主机发送一个低电平

    IIC_SCLK = 1;           //时钟有效,发送数据

    IIC_SCLK = 0;

    //    IIC_SDAT = 1;

}

 

/******************************************************************************

* 函 数 名: IIC_Writenoack(void)

* 函数功能: 从机接收数据结束时,向主机发送无应答信号

* 入口参数: 无

* 返    回: 无

*******************************************************************************/

 

void IIC_Writenoack(void)

{

    IIC_SCLK = 0;

    IIC_SDAT = 1;         //发送高电平,表示无应答

    IIC_SCLK = 1;         //时钟有效

    IIC_SCLK = 0;

}

 

/******************************************************************************

* 函 数 名: IIC_Start(void)

* 函数功能: 启动EEPROM读写操作

* 入口参数: 无

* 返    回: 无

*******************************************************************************/

 

void IIC_Start(void)

{

    IIC_SDAT = 1;         //数据线置位

    IIC_SCLK = 1;         //时钟有效

    IIC_SDAT = 0;         //数据线复位,在时钟有效期间,数据线产生一个下降沿表示启动EEPROM读写操作

    IIC_SCLK = 0;         //时钟无效

}

 

/******************************************************************************

* 函 数 名: IIC_Stop(void)

* 函数功能: 停止对EEPROM读写操作

* 入口参数: 无

* 返    回: 无

*******************************************************************************/

 

void IIC_Stop(void)

{

    IIC_SDAT = 0;         //数据线复位

    IIC_SCLK = 1;         //时钟有效

    IIC_SDAT = 1;         //数据线复位

    IIC_SCLK = 0;         //数据线置位,在时钟有效期间,数据线产生一个上升沿表示停止EEPROM读写操作

}

 

/******************************************************************************

* 函 数 名: IIC_WriteByte(uint8 wdata)

* 函数功能: 进行8位字节数据写操作

* 入口参数: wdata待写数据

* 返    回: status:0:成功 1:失败

*******************************************************************************/

uint8 IIC_WriteByte(uint8 wdata)

{

    uint8 i, status;

    IIC_SCLK = 0;                   //时钟无效

    for(i = 0; i < 8; i++)              //写8位字节数据

    {

        if((wdata & 0x80) == 0x80)  //读最高位数据

        {

            IIC_SDAT = 1;

        }

        else

        {

            IIC_SDAT = 0;

        }

        IIC_SCLK = 1;           //时钟有效

        wdata <<= 1;            //数据左移一位

        NOP();

        IIC_SCLK = 0;

    }

 

    TRISC4 = 1;         //数据线设置为输入模式

    IIC_SDAT = 1;       //拉高数据线

    NOP();

    IIC_SCLK = 1;       //时钟有效

    NOP();

    if(IIC_SDAT)        //第九个时钟数据为1,则写失败成功,IIC器件没有应答

    {

        status = 1;

    }

    else

    {

        status = 0;

    }

    IIC_SCLK = 0;

    TRISC4 = 0;         //数据线设置回输出模式

    return status;      //返回写成功与否状态

}

 

/******************************************************************************

* 函 数 名: IIC_WriteData(uint8 commond,uint8 reg_addr,*mdatapointer,uint8 bytenum)

* 函数功能: 写多字节数据

* 入口参数: commond:读写指令,reg_addr写操作地址,mdata待写数据,bytenum字节数

* 返    回: 无

*******************************************************************************/

void IIC_Write_Mulit_Data(uint8 commond, uint8 reg_addr, uint8 *mdatapointer, uint8 bytenum)

{

    uint8 i, status;

    IIC_Start();    //启动IIC

    status = IIC_WriteByte(commond);    //写器件地址

    if(!status)

    {

        status = IIC_WriteByte(reg_addr);   //写寄存器地址

    }

    for(i = 0; i < bytenum; i++)

    {

        if(!status)

        {

            status = IIC_WriteByte(*(mdatapointer + i));        //写数据

        }

    }

    IIC_Stop();     //结束IIC

}

 

/******************************************************************************

* 函


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
stm32 总线矩阵介绍