记录
i2c程序
[code]#include "iic.h"#include "port.h"#include "sys.h"/*IIC应用配置*/const iic_handle item_i2c[iic_even_num] ={ {GPIOB, GPIOB, GPIO_PIN_7, GPIO_PIN_6},};/** * @brief: 设置SDA引脚输出电平 * @param[in] orgn: IIC句柄指针 * @param[in] level: 输出电平(0:低电平,1:高电平) * @param[out] None * @retval: None */void iic_sda_out(const iic_handle *orgn, uint8_t level){ if (level) { gpio_set(orgn->iic_SDA, orgn->iic_SDA_PIN); } else { gpio_reset(orgn->iic_SDA, orgn->iic_SDA_PIN); }}/** * @brief: 读取SDA引脚输入电平 * @param[in] orgn: IIC句柄指针 * @param[out] None * @retval: SDA引脚电平(0:低电平,1:高电平) */uint8_t iic_sda_in(const iic_handle *orgn){ if (1 == gpio_read(orgn->iic_SDA, orgn->iic_SDA_PIN)) { return 1; } else { return 0; }}/** * @brief: 设置SCL引脚输出电平 * @param[in] orgn: IIC句柄指针 * @param[in] level: 输出电平(0:低电平,1:高电平) * @param[out] None * @retval: None */void iic_scl_out(const iic_handle *orgn, uint8_t level){ if (level) { gpio_set(orgn->iic_SCL, orgn->iic_SCL_PIN); } else { gpio_reset(orgn->iic_SCL, orgn->iic_SCL_PIN); }}/** * @brief: 产生IIC起始信号 * @param[in] orgn: IIC句柄指针 * @param[out] None * @retval: None */void iic_start(const iic_handle *orgn){ /*SCL高电平时,SDA由高电平到低电平*/ /*拉高SDA防止使用前已经是低电平*/ iic_sda_out(orgn, 1); delay_us(2); iic_scl_out(orgn, 1); delay_us(1); /*拉低SDA*/ iic_sda_out(orgn, 0); delay_us(1); /*拉低SCL准备数据 */ iic_scl_out(orgn, 0); delay_us(1);}/** * @brief: 产生IIC停止信号 * @param[in] orgn: IIC句柄指针 * @param[out] None * @retval: None */void iic_stop(const iic_handle *orgn){ /*SCL高电平时,SDA由低电平到高电平*/ /*改变SDA时保证SCL低电平*/ iic_scl_out(orgn, 0); delay_us(1); delay_us(1); /*拉低数据线 */ iic_sda_out(orgn, 0); delay_us(1); /*拉高SCL后再拉高SDA*/ iic_scl_out(orgn, 1); delay_us(1); iic_sda_out(orgn, 1); delay_us(1);}/** * @brief: 产生IIC应答信号 * @param[in] orgn: IIC句柄指针 * @param[out] None * @retval: None */void iic_ack(const iic_handle *orgn){ /*在SCL高电平时读取SDA电压*/ /*准备SDA数据低电平应答*/ iic_sda_out(orgn, 0); delay_us(1); iic_scl_out(orgn, 1); delay_us(1); iic_scl_out(orgn, 0); delay_us(1);}/** * @brief: 产生IIC非应答信号 * @param[in] orgn: IIC句柄指针 * @param[out] None * @retval: None */void iic_nack(const iic_handle *orgn){ /*在SCL高电平时读取SDA电压*/ /*准备SDA数据高电平不应答*/ iic_sda_out(orgn, 1); delay_us(1); iic_scl_out(orgn, 1); delay_us(1); iic_scl_out(orgn, 0); delay_us(1);}/** * @brief: 接收IIC应答信号 * @param[in] orgn: IIC句柄指针 * @param[out] None * @retval: 应答状态(0:应答成功,1:无应答) */uint8_t iic_rxack(const iic_handle *orgn){ /*接收应答*/ uint8_t i = 5; /*主机释放SDA由从机控制*/ iic_gpio_INinit(orgn); /*发送第九个时钟信号读取从机应答*/ iic_scl_out(orgn, 1); delay_us(1); delay_us(1); while (iic_sda_in(orgn)) { /*读5次防止干扰*/ i--; delay_us(1); if (0 == i) { /*无应答停止IIC总线*/ iic_gpio_outinit(orgn); iic_stop(orgn); return 1; /*非应答*/ } } /*没有发送不应答,SDA重新配置输出以参与下次发送*/ iic_gpio_outinit(orgn); iic_scl_out(orgn, 0); delay_us(1); delay_us(1); return 0; /*应答*/}/** * @brief: IIC发送一个字节数据 * @param[in] orgn: IIC句柄指针 * @param[in] data: 要发送的数据字节 * @param[out] None * @retval: None */void icc_sendbyte(const iic_handle *orgn, uint8_t data){ uint8_t i = 8; while (i--) { /*发送数据在时钟低电平时准备数据*/ iic_scl_out(orgn, 0); delay_us(1); delay_us(1); /*对比最高位*/ iic_sda_out(orgn, data & 0x80); delay_us(1); /*左移 */ data = data |