bs_bcu_app/bsp/bsp_iic.c

195 lines
4.0 KiB
C
Raw Permalink Normal View History

2024-11-20 17:07:14 +08:00
#include "bsp_delay.h"
#include "drv_sys.h"
#include "bsp_iic.h"
/**
* @brief <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>IIC
* @param <EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void iic_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
IIC_SCL_GPIO_CLK_ENABLE(); /* SCL<43><4C><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʹ<EFBFBD><CAB9> */
IIC_SDA_GPIO_CLK_ENABLE(); /* SDA<44><41><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʹ<EFBFBD><CAB9> */
gpio_init_struct.Pin = IIC_SCL_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
gpio_init_struct.Pull = GPIO_PULLUP; /* <20><><EFBFBD><EFBFBD> */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; /* <20><><EFBFBD><EFBFBD> */
HAL_GPIO_Init(IIC_SCL_GPIO_PORT, &gpio_init_struct);/* SCL */
gpio_init_struct.Pin = IIC_SDA_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD; /* <20><>©<EFBFBD><C2A9><EFBFBD><EFBFBD> */
HAL_GPIO_Init(IIC_SDA_GPIO_PORT, &gpio_init_struct);/* SDA */
/* SDA<44><41><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD>,<2C><>©<EFBFBD><C2A9><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IO<49><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>©<EFBFBD><C2A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>(=1), Ҳ<><D2B2><EFBFBD>Զ<EFBFBD>ȡ<EFBFBD>ⲿ<EFBFBD>źŵĸߵ͵<DFB5>ƽ */
iic_stop(); /* ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸 */
}
/**
* @brief IIC<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><EFBFBD><EFBFBD>IIC<EFBFBD><EFBFBD>д<EFBFBD>ٶ<EFBFBD>
* @param <EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
static void iic_delay(void)
{
delay_us(2); /* 2us<75><73><EFBFBD><EFBFBD>ʱ, <20><>д<EFBFBD>ٶ<EFBFBD><D9B6><EFBFBD>250Khz<68><7A><EFBFBD><EFBFBD> */
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>IIC<EFBFBD><EFBFBD>ʼ<EFBFBD>ź<EFBFBD>
* @param <EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void iic_start(void)
{
IIC_SDA(1);
IIC_SCL(1);
iic_delay();
IIC_SDA(0); /* START<52>ź<EFBFBD>: <20><>SCLΪ<4C><CEAA>ʱ, SDA<44>Ӹ߱<D3B8><DFB1>ɵ<EFBFBD>, <20><>ʾ<EFBFBD><CABE>ʼ<EFBFBD>ź<EFBFBD> */
iic_delay();
IIC_SCL(0); /* ǯסI2C<32><43><EFBFBD>ߣ<EFBFBD>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
iic_delay();
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>IICֹͣ<EFBFBD>ź<EFBFBD>
* @param <EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void iic_stop(void)
{
IIC_SDA(0); /* STOP<4F>ź<EFBFBD>: <20><>SCLΪ<4C><CEAA>ʱ, SDA<44>ӵͱ<D3B5><CDB1>ɸ<EFBFBD>, <20><>ʾֹͣ<CDA3>ź<EFBFBD> */
iic_delay();
IIC_SCL(1);
iic_delay();
IIC_SDA(1); /* <20><><EFBFBD><EFBFBD>I2C<32><43><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD>ź<EFBFBD> */
iic_delay();
}
/**
* @brief <EFBFBD>ȴ<EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD>źŵ<EFBFBD><EFBFBD><EFBFBD>
* @param <EFBFBD><EFBFBD>
* @retval 1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
* 0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
*/
uint8_t iic_wait_ack(void)
{
uint8_t waittime = 0;
uint8_t rack = 0;
IIC_SDA(1); /* <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>SDA<44><41>(<28><>ʱ<EFBFBD>ⲿ<EFBFBD><E2B2BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SDA<44><41>) */
iic_delay();
IIC_SCL(1); /* SCL=1, <20><>ʱ<EFBFBD>ӻ<EFBFBD><D3BB><EFBFBD><EFBFBD>Է<EFBFBD><D4B7><EFBFBD>ACK */
iic_delay();
while (IIC_READ_SDA) /* <20>ȴ<EFBFBD>Ӧ<EFBFBD><D3A6> */
{
waittime++;
if (waittime > 250)
{
iic_stop();
rack = 1;
break;
}
}
IIC_SCL(0); /* SCL=0, <20><><EFBFBD><EFBFBD>ACK<43><4B><EFBFBD><EFBFBD> */
iic_delay();
return rack;
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ACKӦ<EFBFBD><EFBFBD>
* @param <EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void iic_ack(void)
{
IIC_SDA(0); /* SCL 0 -> 1 ʱ SDA = 0,<2C><>ʾӦ<CABE><D3A6> */
iic_delay();
IIC_SCL(1); /* <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ʱ<EFBFBD><CAB1> */
iic_delay();
IIC_SCL(0);
iic_delay();
IIC_SDA(1); /* <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>SDA<44><41> */
iic_delay();
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ACKӦ<EFBFBD><EFBFBD>
* @param <EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void iic_nack(void)
{
IIC_SDA(1); /* SCL 0 -> 1 ʱ SDA = 1,<2C><>ʾ<EFBFBD><CABE>Ӧ<EFBFBD><D3A6> */
iic_delay();
IIC_SCL(1); /* <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ʱ<EFBFBD><CAB1> */
iic_delay();
IIC_SCL(0);
iic_delay();
}
/**
* @brief IIC<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
* @param data: Ҫ<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @retval <EFBFBD><EFBFBD>
*/
void iic_send_byte(uint8_t data)
{
uint8_t t;
for (t = 0; t < 8; t++)
{
IIC_SDA((data & 0x80) >> 7); /* <20><>λ<EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD> */
iic_delay();
IIC_SCL(1);
iic_delay();
IIC_SCL(0);
data <<= 1; /* <20><><EFBFBD><EFBFBD>1λ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>η<EFBFBD><CEB7><EFBFBD> */
}
IIC_SDA(1); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>SDA<44><41> */
}
/**
* @brief IIC<EFBFBD><EFBFBD>ȡһ<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
* @param ack: ack=1ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ack; ack=0ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>nack
* @retval <EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
uint8_t iic_read_byte(uint8_t ack)
{
uint8_t i, receive = 0;
for (i = 0; i < 8; i++ ) /* <20><><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD> */
{
receive <<= 1; /* <20><>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λҪ<CEBB><D2AA><EFBFBD><EFBFBD> */
IIC_SCL(1);
iic_delay();
if (IIC_READ_SDA)
{
receive++;
}
IIC_SCL(0);
iic_delay();
}
if (!ack)
{
iic_nack(); /* <20><><EFBFBD><EFBFBD>nACK */
}
else
{
iic_ack(); /* <20><><EFBFBD><EFBFBD>ACK */
}
return receive;
}