#include "bsp_i2c_soft.h" #include "elog.h" // #include "delay.h" void IIC_Init(const IIC_SOFT_TypeDef *pSoftIIC ) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOB_CLK_ENABLE(); // 使能GPIOB时钟 //PB6 SCL PB7初始化设置 GPIO_Initure.Pin = pSoftIIC->scl_pin ; GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出 GPIO_Initure.Pull = GPIO_PULLUP; // 上拉 GPIO_Initure.Speed = GPIO_SPEED_FAST; // 快速 HAL_GPIO_Init( pSoftIIC->scl_port, &GPIO_Initure ); // SDA PB7 初始化设置 GPIO_Initure.Pin = pSoftIIC->sda_pin; HAL_GPIO_Init( pSoftIIC->sda_port, &GPIO_Initure ); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); } int IIC_READ_SDA_Pin(const IIC_SOFT_TypeDef *pSoftIIC) { return HAL_GPIO_ReadPin(pSoftIIC->sda_port,pSoftIIC->sda_pin); } int IIC_SDA_Mode_In(const IIC_SOFT_TypeDef *pSoftIIC) { // 取针脚号 pin6 的值为 2^6 // GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); pSoftIIC->sda_port->MODER&=~(3<<(pSoftIIC->sda_pin_num*2)); pSoftIIC->sda_port->MODER|=0<sda_pin_num*2; } int IIC_SDA_Mode_Out(const IIC_SOFT_TypeDef *pSoftIIC) { // GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); pSoftIIC->sda_port->MODER&=~(3<<(pSoftIIC->sda_pin_num*2)); pSoftIIC->sda_port->MODER|=1<sda_pin_num*2; } //产生IIC起始信号 void IIC_Start(const IIC_SOFT_TypeDef *pSoftIIC) { // SDA_OUT();//sda线输出 IIC_SDA_Mode_Out( pSoftIIC); //sda线输出 GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); delay_us(4); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 0); //START:when CLK is high,DATA change form high to low delay_us(4); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0);//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(const IIC_SOFT_TypeDef *pSoftIIC) { // SDA_OUT();//sda线输出 IIC_SDA_Mode_Out( pSoftIIC); //sda线输出 GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 0);//STOP:when CLK is high DATA change form low to high delay_us(4); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1);//发送I2C总线结束信号 delay_us(4); } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 int IIC_Wait_Ack(const IIC_SOFT_TypeDef *pSoftIIC) { uint8_t ucErrTime=0; // SDA_IN(); //SDA设置为输入 IIC_SDA_Mode_In( pSoftIIC); //SDA设置为输入 GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1);delay_us(1); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1);delay_us(1); while(IIC_READ_SDA_Pin(pSoftIIC)) // while( READ_SDA() ) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(pSoftIIC); return 1; } } GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0);//时钟输出0 return 0; } //产生ACK应答 void IIC_Ack(const IIC_SOFT_TypeDef *pSoftIIC) { GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); // SDA_OUT();//sda线输出 IIC_SDA_Mode_Out( pSoftIIC); //sda线输出 GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 0); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); } //不产生ACK应答 void IIC_NAck(const IIC_SOFT_TypeDef *pSoftIIC) { GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); // SDA_OUT();//sda线输出 IIC_SDA_Mode_Out( pSoftIIC); //sda线输出 GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 int IIC_Send_Byte(const IIC_SOFT_TypeDef *pSoftIIC, uint8_t txd) { uint8_t t; // SDA_OUT();//sda线输出 IIC_SDA_Mode_Out( pSoftIIC); //sda线输出 GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0);//拉低时钟开始数据传输 for(t=0;t<8;t++) { // IIC_SDA=(txd&0x80)>>7; // IIC_SDA( (txd&0x80)>>7); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, (txd&0x80)>>7 ); txd<<=1; delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); delay_us(2); } return 0; } int IIC_Read_Byte( const IIC_SOFT_TypeDef *pSoftIIC) { unsigned char i,receive=0; // SDA_IN(); //SDA设置为输入 IIC_SDA_Mode_In( pSoftIIC); //SDA设置为输入 for(i=0;i<8;i++ ) { GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); receive<<=1; if(IIC_READ_SDA_Pin(pSoftIIC))receive++; // if( READ_SDA() )receive++; delay_us(1); } return receive; } // 发送Slave_Addr 带应答, 兼容7bit 10bit int IIC_Send_Slave_Addr(const IIC_SOFT_TypeDef *pSoftIIC,uint8_t r_w) { if( pSoftIIC->slave_address_width == I2C_SW_Slave_Address_7Bit ) { log_i("salve adrr %02X %02X",pSoftIIC->addr, (pSoftIIC->addr << 1)|r_w); IIC_Send_Byte(pSoftIIC, (pSoftIIC->addr << 1) | r_w); if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; } else if( pSoftIIC->slave_address_width == I2C_SW_Slave_Address_10Bit ) { uint8_t h_addr = 0x0F00 | ((pSoftIIC->addr >> 8 & 0x03) << 2) | r_w; IIC_Send_Byte(pSoftIIC, h_addr); if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; uint8_t l_addr = pSoftIIC->addr & 0xff; IIC_Send_Byte(pSoftIIC, l_addr); if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; } return 0; } // 发送reg_addr 带应答, 兼容8bit 16bit 32bit int IIC_Send_Reg_Addr( const IIC_SOFT_TypeDef *pSoftIIC, uint32_t reg_addr ) { for(int j = 0; j < pSoftIIC->slave_reg_addr_width; j++) { uint8_t offset = (pSoftIIC->slave_reg_addr_width - 1 - j) * 8; uint8_t temp_reg_addr = (reg_addr >> offset) & 0xff; IIC_Send_Byte(pSoftIIC, temp_reg_addr); if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; } return 0; } int IIC_Send_One_Reg_Value( const IIC_SOFT_TypeDef *pSoftIIC, uint32_t reg_val ) { for(int k = 0; k < pSoftIIC->slave_reg_value_width; k++) { uint8_t offset = (pSoftIIC->slave_reg_value_width - 1 - k) * 8; i2c_send_byte(pSoftIIC, (reg_val >> offset) & 0xff); if(!i2c_wait_ack(pSoftIIC)) return false; } return 0; } int IIC_Send_Receive_One_Reg_Value( const IIC_SOFT_TypeDef *pSoftIIC, uint32_t* reg_val, uint8_t ack ) { for(int k = 0; k < pSoftIIC->slave_reg_value_width; k++) { uint8_t offset = (pSoftIIC->slave_reg_value_width - 1 - k) * 8; *reg_val |= (IIC_Read_Byte(pSoftIIC) << offset); if(ack) i2c_ack(pSoftIIC); else i2c_no_ack(pSoftIIC); } return 0; } int IIC_Write_Buf(const IIC_SOFT_TypeDef *pSoftIIC , uint32_t reg_addr, uint8_t *buf, uint8_t len) { IIC_Start(pSoftIIC); IIC_Send_Slave_Addr( pSoftIIC,I2C_WRITE ); IIC_Send_Reg_Addr( pSoftIIC, reg_addr ); for (size_t i = 0; i < len; i++) { IIC_Send_Byte(pSoftIIC,*buf); if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; *buf++; } IIC_Stop(pSoftIIC);//产生一个停止条件 // HAL_Delay( 200 ); // delay_us(6000); return 0; } // 寄存器地址 8位置 int IIC_Read_Buf(const IIC_SOFT_TypeDef *pSoftIIC, uint32_t reg_addr, uint8_t *buf, uint8_t len) { uint8_t temp=0; IIC_Start(pSoftIIC); IIC_Send_Slave_Addr( pSoftIIC,I2C_WRITE ); IIC_Send_Reg_Addr( pSoftIIC, reg_addr ); IIC_Start(pSoftIIC); IIC_Send_Slave_Addr( pSoftIIC,I2C_READ ); for(int i=0; i