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.
156 lines
3.2 KiB
156 lines
3.2 KiB
#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
|
|
|