stm32通用II2驱动

stm32通用II2驱动

  1. 程序源码

    1. bsp_i2c.c
    2. bsp_i2c.h

程序源码

bsp_i2c.c

#include "bsp_i2c.h"
#include "config.h"

#define DEFAULT_ACK 1 // 修改为 0 则固定发送 NACK

void SDA_Input_Mode(iic_bus_t *bus)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin         = bus->IIC_SDA_PIN;
	GPIO_InitStructure.GPIO_Mode        = GPIO_Mode_IN_FLOATING;
	GPIO_Init(bus->IIC_SDA_PORT, &GPIO_InitStructure);
}
void SDA_Output_Mode(iic_bus_t *bus)
{
	GPIO_InitTypeDef  GPIO_InitStructure; 
	GPIO_InitStructure.GPIO_Pin = bus->IIC_SDA_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Init(bus->IIC_SDA_PORT, &GPIO_InitStructure);
}

void SDA_Output(iic_bus_t *bus, uint16_t val)
{
	GPIO_WriteBit(bus->IIC_SDA_PORT, (uint16_t)bus->IIC_SDA_PIN, (val?Bit_SET:Bit_RESET));
}

void SCL_Output(iic_bus_t *bus, uint16_t val)
{
	GPIO_WriteBit(bus->IIC_SCL_PORT, (uint16_t)bus->IIC_SCL_PIN, (val?Bit_SET:Bit_RESET));
}

uint8_t SDA_Input(iic_bus_t *bus)
{
	return (GPIO_ReadInputDataBit(bus->IIC_SDA_PORT, bus->IIC_SDA_PIN));
}

//SCL1 SDA1-SDA0 
/**
  * @brief IIC起始信号
  * @param None
  * @retval None
  */
void i2c_start(iic_bus_t *bus)
{
    SDA_Output(bus,1);
	delay_us(5);
    SCL_Output(bus,1);
	delay_us(5);
    SDA_Output(bus,0);
	delay_us(5);
    SCL_Output(bus,0);
	delay_us(5);
}
//SCL1 SDA0-SDA1
/**
  * @brief IIC结束信号
  * @param None
  * @retval None
  */
void i2c_stop(iic_bus_t *bus)
{
    SCL_Output(bus,0);
	delay_us(5);
    SDA_Output(bus,0);
	delay_us(5);
    SCL_Output(bus,1);
	delay_us(5);
    SDA_Output(bus,1);
	delay_us(5);
}

void i2c_send_ack(iic_bus_t *bus,unsigned char ack)
{
    SDA_Output_Mode(bus);
    SCL_Output(bus,0);
	SDA_Output(bus,0);
	delay_us(5);
    SDA_Output(bus,ack ? 1 : 0); // 根据 ack 的值设置 SDA
    SCL_Output(bus,1);
    delay_us(5);
    SCL_Output(bus,0);
	SDA_Output(bus,1);
}


void i2c_ack(iic_bus_t *bus)
{
    SDA_Output(bus,0);
	delay_us(1);
    SCL_Output(bus,1);
	delay_us(1);
    SCL_Output(bus,0);
	delay_us(1);
}

void i2c_noack(iic_bus_t *bus)
{
    SDA_Output(bus,1);
	delay_us(1);
    SCL_Output(bus,1);
	delay_us(1);
    SCL_Output(bus,0);
	delay_us(2);

}

unsigned char i2c_wait_ack(iic_bus_t *bus)
{
	unsigned short cErrTime = 5;
    SDA_Input_Mode(bus);
	delay_us(2);
    SCL_Output(bus,1);
    while(SDA_Input(bus))
    {
        cErrTime--;
		delay_us(5);
        if (0 == cErrTime)
        {
            SDA_Output_Mode(bus);
            i2c_stop(bus);
            //printf("I2C ACK Timeout\n"); // 增加调试信息
            return 1;
        }
    }
    SDA_Output_Mode(bus);
    SCL_Output(bus,0);
		delay_us(5);
    return 0;
}



void i2c_send_byte(iic_bus_t *bus,unsigned char cSendByte)
{
    unsigned char  i = 8;
    while (i--)
    {
        SCL_Output(bus,0);
        delay_us(2);
        SDA_Output(bus, cSendByte & 0x80);
		delay_us(1);
        cSendByte += cSendByte;
		delay_us(1);
        SCL_Output(bus,1);
		delay_us(1);
    }
    SCL_Output(bus,0);
	delay_us(2);
    //printf("I2C Send Byte: 0x%02X\n", cSendByte); // 增加调试信息
}



unsigned char i2c_receive_byte(iic_bus_t *bus)
{
    unsigned char i, byte = 0;
    SDA_Input_Mode(bus); // 设置 SDA 为输入模式
	delay_us(2);
    for (i = 0; i < 8; i++)
    {
        SCL_Output(bus,0);       // 拉低 SCL 准备读取
        delay_us(2);
        SCL_Output(bus,1);       // 拉高 SCL,采样 SDA
		delay_us(1);
        byte <<= 1;       // 左移一位
        if (SDA_Input(bus))     // 如果 SDA 为高
        {
            byte |= 0x01; // 置为 1
        }
    }
    SCL_Output(bus,0);
	SDA_Output_Mode(bus);
    return byte;
}


void iic_init(iic_bus_t *bus)
{
		/*GPIO Init*/
		GPIO_InitTypeDef  GPIO_InitStructure; 
		RCC_APB2PeriphClockCmd((uint32_t)bus->IIC_SCL_PORT, ENABLE);
		
		GPIO_InitStructure.GPIO_Pin =  bus->IIC_SCL_PIN | bus->IIC_SDA_PIN;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  
		GPIO_Init(bus->IIC_SCL_PORT, &GPIO_InitStructure);
		
		SCL_Output(bus,1);
		SDA_Output(bus,1);
}

bsp_i2c.h


#ifndef __I2C_H__
#define __I2C_H__

#include "stm32f10x.h"

typedef struct
{
	GPIO_TypeDef * IIC_SDA_PORT;
	GPIO_TypeDef * IIC_SCL_PORT;
	uint16_t IIC_SDA_PIN;
	uint16_t IIC_SCL_PIN;
	//void (*CLK_ENABLE)(void);
}iic_bus_t;

#define I2C_SCL_Port	GPIOB
#define I2C_SCL_Pin		GPIO_Pin_13

#define I2C_SDA_Port	GPIOB
#define I2C_SDA_Pin		GPIO_Pin_12

#define I2C_SCL(x)		GPIO_WriteBit(I2C_SCL_Port, I2C_SCL_Pin, (x?Bit_SET:Bit_RESET))
#define I2C_SDA(x)		GPIO_WriteBit(I2C_SDA_Port, I2C_SDA_Pin, (x?Bit_SET:Bit_RESET))
#define GETSDA()		GPIO_ReadInputDataBit(I2C_SDA_Port, I2C_SDA_Pin)


//SDA输入模式
#define SDA_IN()          {     GPIO_InitTypeDef  GPIO_InitStructure;\
                                GPIO_InitStructure.GPIO_Pin         = I2C_SDA_Pin;\
                                GPIO_InitStructure.GPIO_Mode        = GPIO_Mode_IN_FLOATING;\
                                GPIO_Init(I2C_SDA_Port, &GPIO_InitStructure);\
                          }
//SDA输出模式
#define SDA_OUT()		{	GPIO_InitTypeDef  GPIO_InitStructure; \
							GPIO_InitStructure.GPIO_Pin = I2C_SDA_Pin;\
							GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;\
							GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;\
							GPIO_Init(I2C_SDA_Port, &GPIO_InitStructure);\
						}

void i2c_start(iic_bus_t *bus);
void i2c_stop(iic_bus_t *bus);
void i2c_send_ack(iic_bus_t *bus,unsigned char ack);
void i2c_ack(iic_bus_t *bus);
void i2c_noack(iic_bus_t *bus);
unsigned char i2c_wait_ack(iic_bus_t *bus);
void i2c_send_byte(iic_bus_t *bus,unsigned char byte);
unsigned char i2c_receive_byte(iic_bus_t *bus);

void iic_init(iic_bus_t *bus);
#endif
						
						

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值