软件 I2C 搞定了. 继续搞案子。
没事换换换,STM32F103C8 换 C6. 给自己找事!
Header File <SoftIIC.h>
/********************************************************
* IIC Lib.
* STM32F103 Clock @72MHz
* I2C Speed <= 100KHz
*
* By Jason Lu. 2022/07/26
*********************************************************/
#ifndef __SOFTIIC_H_
#define __SOFTIIC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <brd.h>
/* IIC */
typedef enum { ACK=0, NACK=!ACK } Acknowledge_TypeDef;
#define I2C_ERROR_NONE 0x00000000U /*!< No error */
#define I2C_ERROR_BERR 0x00000001U /*!< BERR error */
#define I2C_ERROR_AF 0x00000004U /*!< AF error */
#define I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */
#define I2C_ERROR_BUSBUSY 0x00000080U /*!< BUS BUSY */
#ifdef PCB_B0
// I2C1
#define hwSCL (1U << 6)
#define portSetSCL() GPIOB->BSRR = hwSCL
#define portResetSCL() GPIOB->BRR = hwSCL
#define hwSDA ( 1U << 7 )
#define portSetSDA() GPIOB->BSRR = hwSDA
#define portResetSDA() GPIOB->BRR = hwSDA
#define portGetSDA() (0 != (GPIOB->IDR & hwSDA))
#else
// I2C2
#define hwSCL (1U << 10)
#define portSetSCL() GPIOB->BSRR = hwSCL
#define portResetSCL() GPIOB->BRR = hwSCL
#define hwSDA ( 1U << 11 )
#define portSetSDA() GPIOB->BSRR = hwSDA
#define portResetSDA() GPIOB->BRR = hwSDA
#define portGetSDA() (0 != (GPIOB->IDR & hwSDA))
#endif
#define IsBusFree() ((GPIOB->IDR & (uint32_t)hwSCL)&& (GPIOB->IDR & (uint32_t)hwSDA))
void IICAck(uint8_t bAck);
#define IIC_ACK() IICAck(0)
#define IIC_NACK() IICAck(1)
void IICStart(void);
void IICStop(void) ;
uint8_t IICWrite8Bits(uint8_t ucI2cdata);
void IICRead8Bits(unsigned char* pData);
uint32_t SoftIICRead(uint8_t Dev, uint8_t ucAddr, uint8_t ucLen, uint8_t* pBuf);
uint32_t SoftIICWrite(uint8_t Dev, uint8_t ucAddr, uint8_t ucLen, uint8_t* pBuf);
#ifdef __cplusplus
}
#endif
#endif
Dumy 延时 Delay2us(void) @72MHz.
因為 DelayXus(2) , 跑起來要 5us.
void Delay2us(void)
{
uint32_t i;
for(i=0; i<24; i++){ };
}
Clock stretch :
有篇文章说这 Clock Stretch, 我是不怎认同。
这SCL信号被 Slave 拉低, 势必在 ACK时的 Clock Cycle中, 这部分是 Slave Device需符合规范, 软件为啥要扛锅去做 de-glitch? De-bounce?
依规范在下一个 Clock High前去确认 SCL就好了, 不是吗?
SCL = Low -> Clock stretched -> Waiting for Release
SCL = high -> Normal I2C
不然就跟写AT24C系列一样, 等个固定时间就好了, 硬件软了, 别老是为难软件。 都被逼到用软件写I2C了, 还BB啥。
PS:
Timeout 目前没用上, 等加了 Clock stretch 再上。
Source Files
版权声明:本文为weixin_44679008原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。