/* * iic.c * * Created on: Oct 24, 2021 * Author: wuwenfeng */ #include "iic.h" #include "gpio.h" #define iic_sda(x) HAL_GPIO_WritePin(iic_sda_GPIO_Port, iic_sda_Pin, x) #define iic_scl(x) HAL_GPIO_WritePin(iic_scl_GPIO_Port, iic_scl_Pin, x) #define read_iic_sda HAL_GPIO_ReadPin(iic_sda_GPIO_Port, iic_sda_Pin) #define IIC_SDA_SET iic_sda(1) #define IIC_SCL_SET iic_scl(1) #define IIC_SDA_CLR iic_sda(0) #define IIC_SCL_CLR iic_scl(0) #define SDA_OUT() change_io_function(iic_sda_GPIO_Port, iic_sda_Pin,0) #define SDA_IN() change_io_function(iic_sda_GPIO_Port, iic_sda_Pin,1) #define READ_SDA read_iic_sda //产生IIC起始信号 void IIC_Start(void) { SDA_OUT(); //sda线输出 IIC_SDA_SET; IIC_SCL_SET; IIC_SDA_CLR;//START:when CLK is high,DATA change form high to low IIC_SCL_CLR;//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(void) { SDA_OUT();//sda线输出 IIC_SCL_CLR; IIC_SDA_CLR;//STOP:when CLK is high DATA change form low to high IIC_SCL_SET; IIC_SDA_SET;//发送I2C总线结束信号 } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 uint8_t IIC_Wait_Ack(void) { uint8_t ucErrTime=0; SDA_IN(); //SDA设置为输入 IIC_SDA_SET; IIC_SCL_SET; while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(); return 1; } } IIC_SCL_CLR;//时钟输出0 return 0; } //产生ACK应答 void IIC_Ack(void) { IIC_SCL_CLR; SDA_OUT(); IIC_SDA_CLR; IIC_SCL_SET; IIC_SCL_CLR; } //不产生ACK应答 void IIC_NAck(void) { IIC_SCL_CLR; SDA_OUT(); IIC_SDA_SET; IIC_SCL_SET; IIC_SCL_CLR; } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void IIC_Send_Byte(uint8_t txd) { uint8_t t; SDA_OUT(); IIC_SCL_CLR;//拉低时钟开始数据传输 for(t=0;t<8;t++) { //IIC_SDA=(txd&0x80)>>7; if((txd&0x80)>>7) IIC_SDA_SET; else IIC_SDA_CLR; txd<<=1; IIC_SCL_SET; IIC_SCL_CLR; } } //读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_CLR; IIC_SCL_SET; receive<<=1; if(READ_SDA)receive++; } if (!ack) IIC_NAck();//发送nACK else IIC_Ack(); //发送ACK return receive; } void IIC_SAND_DATE(unsigned char DEVICE_ADD,unsigned char IN_DEVICE_ADD,char *DATAS,uint16_t LONG) { IIC_Start(); IIC_Send_Byte(DEVICE_ADD); if(IIC_Wait_Ack()){return;} IIC_Send_Byte(IN_DEVICE_ADD); if(IIC_Wait_Ack()){return;} for(int a=0;a