#include "main.h" //包含需要的头文件 /*-------------------------------------------------*/ /*函数名:初始化IIC接口 */ /*参 数:无 */ /*返回值:无 */ /*-------------------------------------------------*/ void iicInit(void) { GPIO_InitTypeDef GPIO_InitStruct; //定义一个设置GPIO的变量 GPIOC_RCC_ENABLE; GPIO_InitStruct.Pin = SDA_Pin; //设置SDA对应的IO口 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; //推免输出 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速 HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct); //设置 GPIO_InitStruct.Pin = SCL_Pin; //设置SCL对应的IO口 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //推免输出 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速 HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct); //设置 IIC_SCL_H; //SCL拉高 IIC_SDA_H; //SDA拉高 } /*-------------------------------------------------*/ /*函数名:IIC起始信号 */ /*参 数:无 */ /*返回值:无 */ /*-------------------------------------------------*/ void iicStart(void) { IIC_SDA_H; //SDA拉高 IIC_SCL_H; //SCL拉高 delayUs(4); //延时 IIC_SDA_L; //SCL高电平的时候,SDA由高到低,起始信号 } /*-------------------------------------------------*/ /*函数名:IIC停止信号 */ /*参 数:无 */ /*返回值:无 */ /*-------------------------------------------------*/ void iicStop(void) { IIC_SDA_L; //SDA拉低 IIC_SCL_H; //SCL拉高 delayUs(4); //延时 IIC_SDA_H; //SCL高电平的时候,SDA由低到高,发出停止信号 } /*-------------------------------------------------*/ /*函数名:等待应答 */ /*参 数:无 */ /*返回值:0:成功 1:失败 */ /*-------------------------------------------------*/ char iicWaitAck(void) { unsigned char timeout=0; //定义一个变量,用于计算超时时间 IIC_SDA_H; //SDA拉高 IIC_SCL_H; //SCL拉高 while(READ_SDA) { //等待SDA变低电平,表示应答到来,不然一直while循环,直到超时 timeout++; //超时计数+1 if(timeout>250) { //如果大于250 iicStop(); //发送停止信号 return 1; //返回1,表示失败 } delayUs(2); //延时 } IIC_SCL_L; //SCL拉低 delayUs(20); //延时 return 0; //返回0,表示成功 } /*-------------------------------------------------*/ /*函数名:发送一个字节 */ /*参 数:txd:发送的字节 */ /*返回值:无 */ /*-------------------------------------------------*/ void iicSendByte(uint8_t txd) { unsigned char t; //定义一个变量用于for循环 IIC_SCL_L; //SCL拉低,开始数据传输 for(t=0; t<8; t++) { //for循环,一位一位的发送,从最高位 位7开始 IIC_SDA_OUT(((txd&0x80)>>7)); //给SDA数据线 txd<<=1; //左移一位,准备下一次发送 delayUs(2); //延时 IIC_SCL_H; //SCL拉高 delayUs(2); //延时 IIC_SCL_L; //SCL拉低 } } /*-------------------------------------------------*/ /*函数名:读取一个字节 */ /*参 数:ack:是否发送应答 1:发 0:不发 */ /*返回值:读取的数据 */ /*-------------------------------------------------*/ unsigned char iicReadByte(uint8_t ack) { unsigned char i; //定义一个变量用于for循环 unsigned char receive; //定义一个变量用于保存接收到的数据 receive = 0; //清除receive,准备接收数据 IIC_SCL_L; //SCL拉低 delayUs(20); //延时 for(i=0; i<8; i++) { //for循环,一位一位的读取 IIC_SCL_H; //SCL拉高 delayUs(20); //延时 receive<<=1; //左移一位,准备下次的读取 if(READ_SDA)receive++; //读取数据 delayUs(20); //延时 IIC_SCL_L; //SCL拉低 delayUs(20); //延时 } if(!ack) { //不需要发送 IIC_SDA_H; //时钟脉冲的高电平期间保持稳定的高电平 IIC_SCL_H; //SCL拉高 delayUs(2); //延时 IIC_SCL_L; //SCL拉低 } else { //需要发送 IIC_SDA_L; //时钟脉冲的高电平期间保持稳定的低电平 IIC_SCL_H; //SCL拉高 delayUs(2); //延时 IIC_SCL_L; //SCL拉低 IIC_SDA_H; //SDA拉高 } return receive; }