#include "bsp_i2c_soft.h" uint32_t delay1us; /** * @brief: 1us延时 * @param {uint32_t} delay_1us * @return {*} */ // void delay_1us(uint32_t delay_1us) // { // HAL_TIM_Base_Start_IT( &htim3 ); // delay1us = delay_1us; // while (delay1us); // HAL_TIM_Base_Stop_IT( &htim3 ); // } void delay_1us(uint32_t delay_1us) { uint16_t cnt = 0; while(delay_1us--) { for(cnt=168/5; cnt>0; cnt--); // TODO 168 } } // static void delay_us(uint32_t u_sec) // { // uint16_t cnt = 0; // while(u_sec--) // { // for(cnt=168/5; cnt>0; cnt--); // } // } /** * @brief: IIC延时时间 * @return {*} */ void analog_i2c_delay(void) { delay_1us(2); } /** * @brief: 软件模拟I2C初始化 * @return {*} */ void bsp_analog_i2c_init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); /*Configure GPIO pins : PD6 SCL */ GPIO_InitStruct.Pin = SCL_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(SCL_PORT, &GPIO_InitStruct); /*Configure GPIO pins : PC1 SDA */ GPIO_InitStruct.Pin = SDA_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(SDA_PORT, &GPIO_InitStruct); bsp_analog_i2c_stop(); } /** * @brief: I2C 开始,SCL为高电平的时候SDA产生一个下降沿信号 * @return {*} */ void bsp_analog_i2c_start(void) { /* _____ *SDA \_____________ * __________ *SCL \________ */ i2c_sda_high(); i2c_scl_high(); analog_i2c_delay(); i2c_sda_low(); analog_i2c_delay(); i2c_scl_low(); analog_i2c_delay(); } /** * @brief: I2C 停止,SCL为高电平的时候SDA产生一个上升沿信号 * @return {*} */ void bsp_analog_i2c_stop(void) { /* _______ *SDA __________/ * ____________ *SCL _____/ */ i2c_sda_low(); i2c_scl_high(); analog_i2c_delay(); i2c_sda_high(); analog_i2c_delay(); } /** * @brief: I2C 等待响应 * @return {*} */ uint8_t bsp_analog_i2c_wait_ack(void) { uint32_t timeout = 0; i2c_sda_high(); SDA_IN(); analog_i2c_delay(); i2c_scl_high(); analog_i2c_delay(); while(i2c_read_sda()) { timeout++; if(timeout > 2000) { return 1; } } i2c_scl_low(); analog_i2c_delay(); return 0; } /** * @brief: I2C 响应 * @return {*} */ void bsp_analog_i2c_ack(void) { /* ____ *SCL ______/ \______ * ____ _____ *SDA \_______/ */ i2c_sda_low(); analog_i2c_delay(); i2c_scl_high(); analog_i2c_delay(); i2c_scl_low(); analog_i2c_delay(); i2c_sda_high(); } /** * @brief: I2C 不响应 * @return {*} */ void bsp_analog_i2c_nack(void) { /* ____ *SCL ______/ \______ * __________________ *SDA */ i2c_sda_high(); analog_i2c_delay(); i2c_scl_high(); analog_i2c_delay(); i2c_scl_low(); analog_i2c_delay(); } /** * @brief: I2C 发送一个字节数据 * @param {uint8_t} data * @return {*} */ void bsp_analog_i2c_send_byte(uint8_t data) { uint8_t i; SDA_OUT(); for(i = 0; i < 8; i++) { if(data & 0x80) { i2c_sda_high(); } else { i2c_sda_low(); } analog_i2c_delay(); i2c_scl_high(); analog_i2c_delay(); i2c_scl_low(); if(i == 7) { i2c_sda_high(); } data <<= 1; analog_i2c_delay(); } } /** * @brief: I2C 读一个字节数据 * @return {*} */ uint8_t bsp_analog_i2c_read_byte(void) { uint8_t i, data = 0; i2c_sda_high(); SDA_IN(); for(i = 0; i < 8; i++ ) { data <<= 1; i2c_scl_high(); analog_i2c_delay(); if(i2c_read_sda()) { data++; } i2c_scl_low(); analog_i2c_delay(); } return data; } uint8_t bsp_i2c_test_write( uint8_t slave_addr, uint8_t reg_addr, uint8_t *buf, uint8_t len) { bsp_analog_i2c_start(); //发送器件地址+写命令 bsp_analog_i2c_send_byte(slave_addr & 0xFE); if(bsp_analog_i2c_wait_ack()) //等待应答 { bsp_analog_i2c_stop(); return -1; } //发送写(起始)寄存器地址 bsp_analog_i2c_send_byte(reg_addr); if(bsp_analog_i2c_wait_ack()) //等待应答 { bsp_analog_i2c_stop(); return -1; } //发送写数据 for(int i=0; i250) // { // IIC_Stop(); // return 1; // } // } // IIC_SCL=0;//时钟输出0 // return 0; // } // //产生ACK应答 // void IIC_Ack(void) // { // IIC_SCL=0; // SDA_OUT(); // IIC_SDA=0; // delay_us(2); // IIC_SCL=1; // delay_us(2); // IIC_SCL=0; // } // //不产生ACK应答 // void IIC_NAck(void) // { // IIC_SCL=0; // SDA_OUT(); // IIC_SDA=1; // delay_us(2); // IIC_SCL=1; // delay_us(2); // IIC_SCL=0; // } // //IIC发送一个字节 // //返回从机有无应答 // //1,有应答 // //0,无应答 // void IIC_Send_Byte(uint8_t txd) // { // uint8_t t; // SDA_OUT(); // IIC_SCL=0;//拉低时钟开始数据传输 // for(t=0;t<8;t++) // { // IIC_SDA=(txd&0x80)>>7; // txd<<=1; // delay_us(2); //对TEA5767这三个延时都是必须的 // IIC_SCL=1; // delay_us(2); // IIC_SCL=0; // delay_us(2); // } // } // //读1个字节,ack=1时,发送ACK,ack=0,发送nACK // uint8_t IIC_Read_Byte(unsigned char ack) // { // unsigned char i,receive=0; // SDA_IN();//SDA设置为输入 // for(i=0;i<8;i++ ) // { // IIC_SCL=0; // delay_us(2); // IIC_SCL=1; // receive<<=1; // if(READ_SDA)receive++; // delay_us(1); // } // if (!ack) // IIC_NAck();//发送nACK // else // IIC_Ack(); //发送ACK // return receive; // } // 兼容软硬i2c // /* // * 函数功能:I2C1写寄存器,这是提供给上层的接口 // * 输入参数:slave_addr:从机地址 // * reg_addr:寄存器地址 // * len:写入的长度 // * data_ptr:指向要写入的数据 // * 返回值 :正常为0,不正常为非0 // * 说明 :无 // */ // int Sensors_I2C1_WriteRegister(unsigned char slave_addr, unsigned char reg_addr, unsigned short len, unsigned char *data_ptr) // { // #ifdef HARDWARE_I2C //硬件I2C // HAL_StatusTypeDef status = HAL_OK; // status = HAL_I2C_Mem_Write(&hi2c1, slave_addr, reg_addr, I2C_MEMADD_SIZE_8BIT, data_ptr, len, I2Cx_FLAG_TIMEOUT); // //检查通讯状态 // if(status != HAL_OK) // { // //总线出错处理 // I2C1_Error(); // } // while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY) // { // } // //检查SENSOR是否就绪进行下一次读写操作 // while (HAL_I2C_IsDeviceReady(&hi2c1, slave_addr, I2Cx_FLAG_TIMEOUT, I2Cx_FLAG_TIMEOUT) == HAL_TIMEOUT); // //等待传输结束 // while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY) // { // } // return status; // #else //软件I2C1 // //发送起始位 // IIC1_Start(); // //发送器件地址+写命令 // IIC1_Write_Byte(slave_addr & 0xFE); // if(IIC1_Wait_Ack()) //等待应答 // { // IIC1_Stop(); // return -1; // } // //发送写(起始)寄存器地址 // IIC1_Write_Byte(reg_addr); // if(IIC1_Wait_Ack()) //等待应答 // { // IIC1_Stop(); // return -1; // } // //发送写数据 // for(int i=0; i