主要問題:
1,使用STM32F103C8T6,模擬IIC,SCL和SDA口配置為推挽輸出上拉,主要是SDA腳,每次都要輸出輸入模式重新配置,雖然也能通信,但不穩定,出錯率大;
2,后將SCL和SDA口配置為開漏輸出上拉,仍是IO模擬IIC,開漏的特點是寫1時,是使用上拉電阻將總線拉高,總線處于“釋放”狀態,其他器件2可以拉低,寫0是總線接地,總線此時是不能被其他器件拉高的,所示總線處于被寫0一方的的占用或者強制。而我的stm32無外接上拉電阻,SHT20的SCL和SDA也無外接上拉電阻,這時使用HAH庫的寫高,是無法拉高的,后將SCL和SDA腳都加了10K上拉電阻后,通信正常;
3,也可以使用STM32CubeMX配置為硬件IIC進行通信,也要外接上拉電阻,但此方法還未嘗試,發現網上說STM32F103系列的IIC使用HAH庫發送函數返回BUSY,存在BUSY鎖死問題,暫時未用。
下圖是SCL和SDA腳配置為推挽上拉輸出方式通信,的宏定義,SDA每次操作都要重新配置輸入或輸出,此方法在IIC通信中不可取:
再來說說SHT20的驅動,我使用非主機模式,默認溫度測量需要等待80幾ms,如果使用裸機,只有阻塞延遲,太浪費時間了,還是要加實時操作系統的,像FREERTOS。
如下模擬IIC讀測值代碼,也有問題,還未調通!!!
void SHT2x_MeasureHM(etSHT2xMeasureType eSHT2xMeasureType)
{ uint8_t checksum; uint16_t i = 0; uint8_t back_flag = 1; I2c_StartCondition();back_flag = I2c_WriteByte(I2C_ADR_W);if(back_flag == ACK){ sensor_warning_flag = 0;switch(eSHT2xMeasureType){ case HUMIDITY: back_flag = I2c_WriteByte(TRIG_RH_MEASUREMENT_POLL); break;case TEMP : back_flag = I2c_WriteByte(TRIG_T_MEASUREMENT_POLL); break;default: break;}if(back_flag == ACK)//-- wait until hold master is released --{I2c_StopCondition();DelayMicroSeconds(80000); //等待最大80msback_flag = I2c_WriteByte(I2C_ADR_R);while(back_flag== NACK){I2c_StopCondition();DelayMicroSeconds(80000*(++i)); //等待測量時間I2c_StartCondition();back_flag = I2c_WriteByte(I2C_ADR_R);if (i>=2) {error |= TIME_OUT_ERROR;return;}};//-- read two data bytes and one checksum byte --dat[0] = I2c_ReadByte(ACK); //高8位數據dat[1] = I2c_ReadByte(ACK); //低8位數據checksum= I2c_ReadByte(NACK); //8位校驗位數據//-- verify checksum --error = SHT2x_CheckCrc(dat,2,checksum);I2c_StopCondition();}elseerror |= ACK_ERROR;}elseerror |= ACK_ERROR;
}