STM32软件 I2C Master (不支持Clock stretch)

软件 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版权协议,转载请附上原文出处链接和本声明。