#include "bsp_i2c_soft.h" #include "elog.h" // #include "delay.h" void IIC_Init(const IIC_SOFT_TypeDef *pSoftIIC ) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOB_CLK_ENABLE(); // 使能GPIOB时钟 //PB6 SCL PB7初始化设置 GPIO_Initure.Pin = pSoftIIC->scl_pin ; GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出 GPIO_Initure.Pull = GPIO_PULLUP; // 上拉 GPIO_Initure.Speed = GPIO_SPEED_FAST; // 快速 HAL_GPIO_Init( pSoftIIC->scl_port, &GPIO_Initure ); // SDA PB7 初始化设置 GPIO_Initure.Pin = pSoftIIC->sda_pin; HAL_GPIO_Init( pSoftIIC->sda_port, &GPIO_Initure ); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); } int IIC_READ_SDA_Pin(const IIC_SOFT_TypeDef *pSoftIIC) { return HAL_GPIO_ReadPin(pSoftIIC->sda_port,pSoftIIC->sda_pin); } int IIC_SDA_Mode_In(const IIC_SOFT_TypeDef *pSoftIIC) { // 取针脚号 pin6 的值为 2^6 // GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); pSoftIIC->sda_port->MODER&=~(3<<(pSoftIIC->sda_pin_num*2)); pSoftIIC->sda_port->MODER|=0<sda_pin_num*2; } int IIC_SDA_Mode_Out(const IIC_SOFT_TypeDef *pSoftIIC) { // GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); pSoftIIC->sda_port->MODER&=~(3<<(pSoftIIC->sda_pin_num*2)); pSoftIIC->sda_port->MODER|=1<sda_pin_num*2; } //产生IIC起始信号 void IIC_Start(const IIC_SOFT_TypeDef *pSoftIIC) { // SDA_OUT();//sda线输出 IIC_SDA_Mode_Out( pSoftIIC); //sda线输出 GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); delay_us(4); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 0); //START:when CLK is high,DATA change form high to low delay_us(4); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0);//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(const IIC_SOFT_TypeDef *pSoftIIC) { // SDA_OUT();//sda线输出 IIC_SDA_Mode_Out( pSoftIIC); //sda线输出 GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 0);//STOP:when CLK is high DATA change form low to high delay_us(4); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1);//发送I2C总线结束信号 delay_us(4); } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 uint8_t IIC_Wait_Ack(const IIC_SOFT_TypeDef *pSoftIIC) { uint8_t ucErrTime=0; // SDA_IN(); //SDA设置为输入 IIC_SDA_Mode_In( pSoftIIC); //SDA设置为输入 GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1);delay_us(1); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1);delay_us(1); while(IIC_READ_SDA_Pin(pSoftIIC)) // while( READ_SDA() ) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(pSoftIIC); return 1; } } GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0);//时钟输出0 return 0; } //产生ACK应答 void IIC_Ack(const IIC_SOFT_TypeDef *pSoftIIC) { GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); // SDA_OUT();//sda线输出 IIC_SDA_Mode_Out( pSoftIIC); //sda线输出 GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 0); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); } //不产生ACK应答 void IIC_NAck(const IIC_SOFT_TypeDef *pSoftIIC) { GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); // SDA_OUT();//sda线输出 IIC_SDA_Mode_Out( pSoftIIC); //sda线输出 GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void IIC_Send_Byte(const IIC_SOFT_TypeDef *pSoftIIC,uint8_t txd) { uint8_t t; // SDA_OUT();//sda线输出 IIC_SDA_Mode_Out( pSoftIIC); //sda线输出 GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0);//拉低时钟开始数据传输 for(t=0;t<8;t++) { // IIC_SDA=(txd&0x80)>>7; // IIC_SDA( (txd&0x80)>>7); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, (txd&0x80)>>7 ); txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的 GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); delay_us(2); } } uint8_t IIC_Read_Byte( const IIC_SOFT_TypeDef *pSoftIIC) { unsigned char i,receive=0; // SDA_IN(); //SDA设置为输入 IIC_SDA_Mode_In( pSoftIIC); //SDA设置为输入 for(i=0;i<8;i++ ) { GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); receive<<=1; if(IIC_READ_SDA_Pin(pSoftIIC))receive++; // if( READ_SDA() )receive++; delay_us(1); } return receive; } uint8_t IIC_Write_Test(const IIC_SOFT_TypeDef *pSoftIIC , uint8_t reg_addr, uint8_t *buf, uint8_t len) { IIC_Start(pSoftIIC); IIC_Send_Byte(pSoftIIC,pSoftIIC->addr & 0xFE); if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; IIC_Send_Byte(pSoftIIC,reg_addr); if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; IIC_Send_Byte(pSoftIIC,*buf); if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; IIC_Stop(pSoftIIC);//产生一个停止条件 // HAL_Delay( 200 ); // delay_us(6000); return 0; } // 寄存器地址 8位置 uint8_t IIC_Read_Test(const IIC_SOFT_TypeDef *pSoftIIC, uint8_t reg_addr, uint8_t *buf, uint8_t len) { uint8_t temp=0; IIC_Start(pSoftIIC); IIC_Send_Byte(pSoftIIC,pSoftIIC->addr & 0xFE); if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; IIC_Send_Byte(pSoftIIC,reg_addr); if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; IIC_Start(pSoftIIC); IIC_Send_Byte(pSoftIIC,pSoftIIC->addr |0x01); //进入接收模式 if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; for(int i=0; i