#include "bsp_i2c.h" #ifdef USE_I2C #include "bsp_pin.h" uint8_t D[4] = {0}; //IIC初始化 void IIC_Init(void) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB时钟 //PB6,7初始化设置 GPIO_Initure.Pin=GPIO_PIN_6|GPIO_PIN_7; GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 HAL_GPIO_Init(GPIOB,&GPIO_Initure); IIC_SDA(1); IIC_SCL(1); } //产生IIC起始信号 void IIC_Start(void) { SDA_OUT(); //sda线输出 IIC_SDA(1); IIC_SCL(1); delay_us(4); IIC_SDA(0);//START:when CLK is high,DATA change form high to low delay_us(4); IIC_SCL(0);//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(void) { SDA_OUT();//sda线输出 IIC_SCL(0); IIC_SDA(0);//STOP:when CLK is high DATA change form low to high delay_us(4); IIC_SCL(1); IIC_SDA(1);//发送I2C总线结束信号 delay_us(4); } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 uint8_t IIC_Wait_Ack(void) { uint8_t ucErrTime=0; SDA_IN(); //SDA设置为输入 IIC_SDA(1);delay_us(1); IIC_SCL(1);delay_us(1); while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { 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(uint8_t ack) { uint8_t 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; } uint8_t PCF8591_ADC_Input(uint8_t WriteAddr, uint8_t Channel) { uint8_t temp = 0; IIC_Start(); IIC_Send_Byte(WriteAddr); IIC_Wait_Ack(); IIC_Send_Byte(Channel); IIC_Wait_Ack(); IIC_Stop(); IIC_Start(); IIC_Send_Byte(WriteAddr | 0x01); IIC_Wait_Ack(); temp = IIC_Read_Byte(0); IIC_Stop(); return temp; } void IIC_TEST(void) { D[0] = PCF8591_ADC_Input(PCF8591,0x40); D[1] = PCF8591_ADC_Input(PCF8591,0x41); D[2] = PCF8591_ADC_Input(PCF8591,0x42); D[3] = PCF8591_ADC_Input(PCF8591,0x43); printf("%d\t%d\t%d\t%d\r\n", D[0], D[1], D[2], D[3]); } #endif