不含stm32 底层的代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MyStm32Code/bsp/Src/bsp_i2c_soft.c

219 lines
6.6 KiB

2 years ago
#include "bsp_i2c_soft.h"
2 years ago
#include "elog.h"
// #include "delay.h"
2 years ago
2 years ago
void IIC_Init(const IIC_SOFT_TypeDef *pSoftIIC )
2 years ago
{
2 years ago
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);
2 years ago
}
2 years ago
int IIC_READ_SDA_Pin(const IIC_SOFT_TypeDef *pSoftIIC)
2 years ago
{
2 years ago
return HAL_GPIO_ReadPin(pSoftIIC->sda_port,pSoftIIC->sda_pin);
2 years ago
}
2 years ago
int IIC_SDA_Mode_In(const IIC_SOFT_TypeDef *pSoftIIC)
2 years ago
{
2 years ago
// 取针脚号 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<<pSoftIIC->sda_pin_num*2;
2 years ago
}
2 years ago
int IIC_SDA_Mode_Out(const IIC_SOFT_TypeDef *pSoftIIC)
2 years ago
{
2 years ago
// 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<<pSoftIIC->sda_pin_num*2;
2 years ago
}
2 years ago
//产生IIC起始信号
void IIC_Start(const IIC_SOFT_TypeDef *pSoftIIC)
2 years ago
{
2 years ago
// 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)
2 years ago
{
2 years ago
// 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);
2 years ago
}
2 years ago
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
uint8_t IIC_Wait_Ack(const IIC_SOFT_TypeDef *pSoftIIC)
2 years ago
{
2 years ago
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() )
2 years ago
{
2 years ago
ucErrTime++;
if(ucErrTime>250)
2 years ago
{
2 years ago
IIC_Stop(pSoftIIC);
return 1;
2 years ago
}
}
2 years ago
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);
2 years ago
2 years ago
// 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)
2 years ago
{
2 years ago
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;
2 years ago
2 years ago
// SDA_IN(); //SDA设置为输入
IIC_SDA_Mode_In( pSoftIIC); //SDA设置为输入
for(i=0;i<8;i++ )
2 years ago
{
2 years ago
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;
2 years ago
}
2 years ago
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;};
2 years ago
2 years ago
IIC_Send_Byte(pSoftIIC,reg_addr);
if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;};
2 years ago
2 years ago
IIC_Send_Byte(pSoftIIC,*buf);
if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;};
2 years ago
2 years ago
IIC_Stop(pSoftIIC);//产生一个停止条件
// HAL_Delay( 200 );
// delay_us(6000);
return 0;
}
2 years ago
2 years ago
// 寄存器地址 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;};
2 years ago
2 years ago
IIC_Send_Byte(pSoftIIC,reg_addr);
if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;};
2 years ago
2 years ago
IIC_Start(pSoftIIC);
IIC_Send_Byte(pSoftIIC,pSoftIIC->addr |0x01); //进入接收模式
if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;};
2 years ago
2 years ago
for(int i=0; i<len-1; i++)
{
*buf=IIC_Read_Byte(pSoftIIC);
IIC_Ack(pSoftIIC); // 应答
buf++;
}
*buf = IIC_Read_Byte(pSoftIIC);// 读非应答
IIC_NAck(pSoftIIC);
// if(IIC_Wait_Ack()) { IIC_Stop(); return -1;};
2 years ago
2 years ago
IIC_Stop(pSoftIIC);
return 0;
}
2 years ago