- void MyI2C_W_SCL(uint8_t BitValue);
- void MyI2C_W_SDA(uint8_t BitValue);
- uint8_t MyI2C_R_SDA(void);
- void MyI2C_Start(void);
- void MyI2C_Stop(void);
- void MyI2C_SendByte(uint8_t Byte);
- void MyI2C_SendBuffer(uint8_t *Buffer, uint32_t len);
- void MyI2C_RecvBuffer(uint8_t I2C_Slave_Addr, uint8_t AR_Addr, uint8_t *Buffer, uint32_t len);
- uint8_t MyI2C_ReceiveByte(void);
- void MyI2C_SendAck(uint8_t AckBit);
- uint8_t MyI2C_ReceiveAck(void);
-
-
-
- // 需要替换的函数
- GPIO_WriteBit(); // 引脚电平写入函数
- GPIO_ReadInputDataBit(); // 读引脚电平函数
- Delay_us(10); // 延迟函数
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] 拉高拉低SCL
- * @param {uint8_t} BitValue 0/1
- * [url=home.php?mod=space&uid=266161]@return[/url] {*}
- */
- void MyI2C_W_SCL(uint8_t BitValue)
- {
- GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);
- Delay_us(10);
- }
- /**
- * @brief : 拉高拉低SDA
- * @param {uint8_t} BitValue 0/1
- * @return {*}
- */
- void MyI2C_W_SDA(uint8_t BitValue)
- {
- GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValue);
- Delay_us(10);
- }
- /**
- * @brief : 读SDA电平
- * @return {*}
- */
- uint8_t MyI2C_R_SDA(void)
- {
- uint8_t BitValue;
- BitValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11);
- Delay_us(10);
- return BitValue;
- }
-
- void MyI2C_Init(void)
- {
- /*使能外设时钟*/
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- /*结构体配置IIC引脚*/
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- GPIO_SetBits(GPIOB, GPIO_Pin_10 | GPIO_Pin_11); // 拉高引脚电平
- }
-
- /********************************************************************************************************************************************
- 修改上面的函数就行下面的都是封装好的
- IIC通讯原则 发送起始信号 发送一个字节 接收应答标志 发送下一个字节 接收应答标志 发送停止标志
- *******************************************************************************************************************************************/
-
- /**
- * @brief 发送开始标志
- * @return {*}
- */
- void MyI2C_Start(void)
- {
- MyI2C_W_SDA(1);
- MyI2C_W_SCL(1);
- MyI2C_W_SDA(0);
- MyI2C_W_SCL(0);
- }
- /**
- * @brief 发送停止标志
- * @return {*}
- */
- void MyI2C_Stop(void)
- {
- /*SCL高电平期间SDA由低变高*/
- MyI2C_W_SDA(0);
- MyI2C_W_SCL(1);
- MyI2C_W_SDA(1);
- }
-
- /**
- * @brief 起始位后SCL为低 可以放数据在SDA上,随后拉高SCL从机读取主机发送的数据,主机在拉低SCL进入下一位的发送
- * @param {uint8_t} Byte
- * @return {*}
- */
- void MyI2C_SendByte(uint8_t Byte)
- {
- uint8_t i;
- for (i = 0; i < 8; i++)
- {
- MyI2C_W_SDA(Byte & (0x80 >> i));
- MyI2C_W_SCL(1);
- MyI2C_W_SCL(0);
- }
- }
- /**
- * @brief 发送buffer
- * @param {uint8_t} Byte
- * @return {*}
- */
- void MyI2C_SendBuffer(uint8_t *Buffer, uint32_t len)
- {
- MyI2C_Start();
- for (int i = 0; i < len; i++)
- {
- MyI2C_SendByte(Buffer[i]);
- MyI2C_ReceiveAck();
- }
- MyI2C_Stop();
- }
- /**
- * @brief : 接收指定从机寄存器地址的buffer
- * @param {uint8_t} I2C_Slave_Addr 从机地址
- * @param {uint8_t} AR_Addr 寄存器地址
- * @param {uint8_t} *Buffer 数据
- * @param {uint32_t} len 数据长度
- * @return {*}
- */
- void MyI2C_RecvBuffer(uint8_t I2C_Slave_Addr, uint8_t AR_Addr, uint8_t *Buffer, uint32_t len)
- {
-
- MyI2C_Start();
-
- MyI2C_SendByte(I2C_Slave_Addr);
- MyI2C_ReceiveAck();
- MyI2C_SendByte(AR_Addr);
- MyI2C_ReceiveAck();
-
- MyI2C_Start();
- MyI2C_SendByte(I2C_Slave_Addr | 0x01);
- MyI2C_ReceiveAck();
- for (int i = 0; i < len; i++)
- {
- Buffer[i] = MyI2C_ReceiveByte();
- if (i == len - 1)
- {
- MyI2C_SendAck(1);
- }
- else
- {
- MyI2C_SendAck(0);
- }
- }
-
- MyI2C_Stop();
- }
-
- /**
- * @brief 主机先拉高SDA是释放总线的意思,SCL此时为低 ,从机可以 放数据在SDA上,随后主机拉高SCL读取SDA的值在拉低SCL进入下一个周期
- * @param {uint8_t} Byte
- * @return {*}
- */
- uint8_t MyI2C_ReceiveByte(void)
- {
- uint8_t i, Byte = 0x00;
- MyI2C_W_SDA(1);
- for (i = 0; i < 8; i++)
- {
- MyI2C_W_SCL(1);
- if (MyI2C_R_SDA() == 1)
- {
- Byte |= (0x80 >> i);
- }
- MyI2C_W_SCL(0);
- }
- return Byte;
- }
- /**
- * @brief 发送应答位
- * @param {uint8_t} Byte 0应带继续接收,1不应答
- * @return {*}
- */
- void MyI2C_SendAck(uint8_t AckBit)
- {
- MyI2C_W_SDA(AckBit);
- MyI2C_W_SCL(1);
- MyI2C_W_SCL(0);
- }
- /**
- * @brief 发送应答位
- * @param {uint8_t} Byte 0应带继续接收,1不应答
- * @return {*}
- */
- uint8_t MyI2C_ReceiveAck(void)
- {
- uint8_t AckBit;
- MyI2C_W_SDA(1);
- MyI2C_W_SCL(1);
- AckBit = MyI2C_R_SDA();
- MyI2C_W_SCL(0);
- return AckBit;
- }
|