GPIO模拟I2C不通

2019-07-14 13:57发布

#####################################################
i2c.h
#####################################################
#ifndef _I2C_H_
#define _I2C_H_
#include "stdbool.h"
#include "STM32f4xx_hal.h"

#define u8 uint8_t
#define u16 uint16_t

#define add_w 0x90
#define add_r 0x91
#define SDA_H GPIOB->BSRR=GPIO_PIN_8
#define SDA_L GPIOB->BSRR=(uint32_t)GPIO_PIN_8 << 16

#define SCL_H GPIOB->BSRR=GPIO_PIN_9
#define SCL_L GPIOB->BSRR=(uint32_t)GPIO_PIN_9 << 16

#define SDA_READ GPIOB->IDR& GPIO_PIN_8
#define SCL_READ GPIOB->IDR& GPIO_PIN_9

void writebyte(u8 sendbyte,u16 write_add,u8 device_add);
bool readbyte(u8* pBuffer,u8 length,u16 read_add,u8 device_add);



#######################################
i2c.c
######################################
#include "i2c.h"
void i2c_delay()
{
        u8 i = 100;
        while(i--);
}

bool i2c_start(void)
{
        SDA_H;
        SCL_H;
        i2c_delay();
        
        if(!SDA_READ)//test the sda != 0
                return false;
        
        SDA_L;
        i2c_delay();
        
        if(SDA_READ)//test the sda == 0
                return false;
        
        SCL_L;
        i2c_delay();
        return true;
}

void i2c_stop(void)
{
        //scl == 0, and sda == 0
        SCL_L;
        i2c_delay();
        SDA_L;
        i2c_delay();
        //scl = 1 , then sda = 1
        SCL_H;
        i2c_delay();
        SDA_H;
        i2c_delay();
}

void i2c_ack(void)
{
        SDA_H;
        i2c_delay();
        SCL_H;
        i2c_delay();
        SCL_L;
        i2c_delay();
        SDA_L;
        i2c_delay();
        SCL_H;
        i2c_delay();
        
}

bool i2c_waitack(void)
{
        SCL_L;
        i2c_delay();
        SDA_H;
        i2c_delay();
        SCL_H;
        i2c_delay();
        if(SDA_READ)
        {
                SCL_L;
                return false;
        }
        SCL_L;
        return true;
}

void i2c_sendbyte(u8 send)
{
        u8 i = 8;
        while(i--)
        {
                SCL_L;
                i2c_delay();
                if(send&0x80)
                        SDA_H;
                else
                        SDA_L;
                send <<= 1;
                i2c_delay();
                SCL_H;
                i2c_delay();
        }
        SCL_L;
}

u8 receivebyte(void)
{
        u8 i = 8;
        u8 receive = 0;
        SDA_H;
        while(i--)
        {
                receive<<=1;
                SCL_L;
                i2c_delay();
                SCL_H;
                i2c_delay();
                if(SDA_READ)
                {
                        receive |= 0x01;
                }
        }
        SCL_L;
        return receive;
}



void writebyte(u8 sendbyte,u16 write_add,u8 device_add)
{
        device_add = device_add | 0x00;
        i2c_start();
        i2c_sendbyte(device_add);
        i2c_delay();
        i2c_sendbyte(write_add);
        i2c_delay();
        i2c_sendbyte(sendbyte);
        i2c_delay();
        i2c_stop();
}

bool readbyte(u8* pBuffer,u8 length,u16 read_add,u8 device_add)
{
        device_add = device_add | 0x01;
        if(!i2c_start())
                return false;
        i2c_sendbyte(device_add);
        i2c_delay();
        i2c_sendbyte(read_add-1);
        i2c_delay();
        i2c_sendbyte(*pBuffer);
        i2c_delay();
        i2c_ack();
        i2c_delay();
        i2c_stop();
        return true;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
你我然后
1楼-- · 2019-07-15 00:33
用逻辑分析仪看下就明白了。
testd035
2楼-- · 2019-07-15 02:30
 精彩回答 2  元偷偷看……
kdyangcheng
3楼-- · 2019-07-15 04:14
用示波器看看
yuxiangxyz
4楼-- · 2019-07-15 08:11
SDA的 IO推动方式 ,最好用开漏型,脚上接个上拉电阻试试

一周热门 更多>