I2C学习之 STC15F204EA---GPIO端口模拟--简单控制PCF8574AT

来源:互联网 发布:c语言中eof怎么输入 编辑:程序博客网 时间:2024/06/06 05:30


        一定要记得加4.7K左右的上拉电阻----与器件类型不同导致的地址不一样!


------------------------------------------------------i2c.h----------头文件-----------------------

#ifndef __I2C_H
#define __I2C_H

#define I2C_SCL_1()  P32=1 //SCL = 1 
#define I2C_SCL_0()  P32=0 //SCL = 0  

#define I2C_SDA_1()  P33=1 //SDA = 1 
#define I2C_SDA_0()  P33=0 //SDA = 0 

#define I2C_SDA_READ()  (P33 != 0)//读SDA口线状态 

void i2c_Start(void);
void i2c_Stop(void);
void i2c_SendByte(unsigned char _ucByte);
unsigned char i2c_ReadByte(void);
unsigned char i2c_WaitAck(void);
void i2c_Ack(void);
void i2c_NAck(void);

unsigned char I2C_PCF8574_ByteWrite(unsigned char _pWriteBuf, unsigned char _usAddress);

#endif

------------------------------------------i2c.c--------------源文件-----------------------

#include "typedef.h"       //包含一些基本头文件
#include "i2c.h"

static void i2c_Delay(void)
{
    unsigned char i;

    for (i = 0; i < 10; i++);
}
void i2c_Start(void)
{
//当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 
    I2C_SDA_1();
    I2C_SCL_1();
    i2c_Delay();
    I2C_SDA_0();
    i2c_Delay();
    I2C_SCL_0();
    i2c_Delay();
}
void i2c_Stop(void)
{
// 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 
    I2C_SDA_0();
    I2C_SCL_1();
    i2c_Delay();
    I2C_SDA_1();
}
void i2c_SendByte(unsigned char _ucByte)
{
    unsigned char i;

// 先发送字节的高位bit7  
    for (i = 0; i < 8; i++)
    {
        if (_ucByte & 0x80)
        {
            I2C_SDA_1();
        }
        else
        {
            I2C_SDA_0();
        }
        i2c_Delay();
        I2C_SCL_1();
        i2c_Delay();
        I2C_SCL_0();
        if (i == 7)
        {
            I2C_SDA_1(); // 释放总线
        }
        _ucByte <<= 1;// 左移一个bit  
        i2c_Delay();
    }
}
unsigned char i2c_ReadByte(void)
{
    unsigned char i;
    unsigned char value;

// 读到第1个bit为数据的bit7 
    value = 0;
    for (i = 0; i < 8; i++)
    {
        value <<= 1;
        I2C_SCL_1();
        i2c_Delay();
        if (I2C_SDA_READ())
        {
            value++;
        }
        I2C_SCL_0();
        i2c_Delay();
    }
    return value;
}
/*
*********************************************************************************************************
* 函 数 名: i2c_WaitAck
* 功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
* 形    参:无
* 返 回 值: 返回0表示正确应答,1表示无器件响应
*********************************************************************************************************
*/
unsigned char i2c_WaitAck(void)
{
    unsigned char re;

    I2C_SDA_1();/* CPU释放SDA总线 */
    i2c_Delay();
    I2C_SCL_1();/* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
    i2c_Delay();
    if (I2C_SDA_READ())/* CPU读取SDA口线状态 */
    {
        re = 1;
    }
    else
    {
        re = 0;
    }
    I2C_SCL_0();
    i2c_Delay();
    return re;
}
/*
*********************************************************************************************************
* 函 数 名: i2c_Ack
* 功能说明: CPU产生一个ACK信号
* 形    参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_Ack(void)
{
    I2C_SDA_0();// CPU驱动SDA = 0  
    i2c_Delay();
    I2C_SCL_1();// CPU产生1个时钟  
    i2c_Delay();
    I2C_SCL_0();
    i2c_Delay();
    I2C_SDA_1();// CPU释放SDA总线 
}
/*
*********************************************************************************************************
* 函 数 名: i2c_NAck
* 功能说明: CPU产生1个NACK信号
* 形    参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_NAck(void)
{
    I2C_SDA_1();// CPU驱动SDA = 1  
    i2c_Delay();
    I2C_SCL_1();// CPU产生1个时钟  
    i2c_Delay();
    I2C_SCL_0();
    i2c_Delay();
}
unsigned char I2C_PCF8574_ByteWrite(unsigned char _pWriteBuf, unsigned char _usAddress)
{
    unsigned char m;
    unsigned char usAddr;

    usAddr = _usAddress;
    i2c_Stop();
    for (m = 0; m < 100; m++)
    {
        i2c_Start();
        i2c_SendByte(usAddr);// 此处是写指令 
        if (i2c_WaitAck() == 0)
            break;
    }
    if (m  == 100)
    goto cmd_fail;// 器件写超时 
    i2c_SendByte(_pWriteBuf);
        if (i2c_WaitAck() != 0)
    goto cmd_fail;//器件无应答 

//命令执行成功,发送I2C总线停止信号 
    i2c_Stop();
    return 1;

cmd_fail: //命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 
    i2c_Stop();//发送I2C总线停止信号
    return 0;
}

-----------------------------------main.c----------主函数---------------------

#include "typedef.h"
#include "i2c.h"

void main(void)
{
    while(1)
    {
        I2C_PCF8574_ByteWrite(0xaa,0x72);
        i=200;
        while(i--);

        I2C_PCF8574_ByteWrite(0xf3,0x70);

        i=200;
        while(i--);
             

    }

}





0 0
原创粉丝点击