ch32v307 I2C讀取卡死

使用ch32v307的i2c會一直卡在while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));這里。

參考ch32v203使用IIC,一直卡在I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED這步驟 - 沁恒微電子社區(qū) (wch.cn)里的方式也沒有解決。


I2C初始化代碼為:

void?i2c1_init(u32?bound,?u16?address)
{
????GPIO_InitTypeDef?GPIO_InitStructure={0};
????I2C_InitTypeDef?I2C_InitTSturcture={0};

????//RCC_APB2PeriphClockCmd(?RCC_APB2Periph_GPIOB?|?RCC_APB2Periph_AFIO,?ENABLE?);
????RCC_APB2PeriphClockCmd(?RCC_APB2Periph_GPIOB,?ENABLE?);
????RCC_APB2PeriphClockCmd(?RCC_APB2Periph_AFIO,?ENABLE?);
????RCC_APB1PeriphClockCmd(?RCC_APB1Periph_I2C1,?ENABLE?);

????I2C_DeInit(I2C1);
????GPIO_PinRemapConfig(GPIO_Remap_I2C1,?ENABLE);

????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_8;
????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AF_OD;
????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;
????GPIO_Init(?GPIOB,?&GPIO_InitStructure?);

????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_9;
????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AF_OD;
????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;
????GPIO_Init(?GPIOB,?&GPIO_InitStructure?);

????I2C_InitTSturcture.I2C_ClockSpeed?=?bound;
????I2C_InitTSturcture.I2C_Mode?=?I2C_Mode_I2C;
????I2C_InitTSturcture.I2C_DutyCycle?=?I2C_DutyCycle_2;//I2C_DutyCycle_16_9;//
????I2C_InitTSturcture.I2C_OwnAddress1?=?address;
????I2C_InitTSturcture.I2C_Ack?=?I2C_Ack_Enable;
????I2C_InitTSturcture.I2C_AcknowledgedAddress?=?I2C_AcknowledgedAddress_7bit;
????I2C_Init(?I2C1,?&I2C_InitTSturcture?);

????I2C_Cmd(?I2C1,?ENABLE?);

????I2C_AcknowledgeConfig(?I2C1,?ENABLE?);
}


i2c1_init(100000,?CH32_I2C_ADDR);


讀取代碼為:

uint8_t?I2C_RegRead(I2C_TypeDef*?I2Cx,?uint8_t?deviceAddr,?uint8_t?data)
{
????uint8_t?value;
????if?(NULL?==?I2Cx)?return?-1;

????printf("[lbc_info]?%04d?%s?1\r\n",?__LINE__,?__func__);

????while(I2C_GetFlagStatus(I2Cx,?I2C_FLAG_BUSY)?!=?RESET);
????I2C_GenerateSTART(I2Cx,?ENABLE);

????printf("[lbc_info]?%04d?%s?2\r\n",?__LINE__,?__func__);

????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_MODE_SELECT));
????I2C_Send7bitAddress(I2Cx,??deviceAddr,?I2C_Direction_Transmitter);

????printf("[lbc_info]?%04d?%s?3\r\n",?__LINE__,?__func__);
????Delay_Ms(10);

????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

????printf("[lbc_info]?%04d?%s?4\r\n",?__LINE__,?__func__);

????I2C_SendData(I2Cx,?data);
????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_BYTE_TRANSMITTED));

????printf("[lbc_info]?%04d?%s?5\r\n",?__LINE__,?__func__);

????I2C_GenerateSTART(I2Cx,?ENABLE);

????printf("[lbc_info]?%04d?%s?6\r\n",?__LINE__,?__func__);

????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_MODE_SELECT));
????I2C_Send7bitAddress(I2Cx,?deviceAddr,?I2C_Direction_Receiver);

????printf("[lbc_info]?%04d?%s?7\r\n",?__LINE__,?__func__);

????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
????printf("[lbc_info]?%04d?%s?8\r\n",?__LINE__,?__func__);
????while(I2C_GetFlagStatus(I2C1,?I2C_FLAG_RXNE)?==??RESET?);
????printf("[lbc_info]?%04d?%s?9\r\n",?__LINE__,?__func__);
????I2C_AcknowledgeConfig(I2Cx,?DISABLE);

????value?=?I2C_ReceiveData(I2Cx);
????I2C_GenerateSTOP(I2Cx,?ENABLE);

????return?value;
}


uint16_t?tmp116_read_id(void)
{
????uint16_t?temp;

????temp?=?I2C_RegRead(I2C1,?TMP116_R_ADDR,?TMP116_DEVICE_ID_ADDR);
????printf("[lbc_info]?tmp116?device?id:0x%X.\r\n",?temp);

????return?temp;
}


問題已解決,非ch32造成。


i2c連續(xù)讀取兩個字節(jié)需要怎么處理,嘗試了兩種方式均會導致卡死

uint16_t?I2C_RegRead16(I2C_TypeDef*?I2Cx,?uint8_t?deviceAddr,?uint8_t?data)
{
????uint16_t?value?=?0;
????if?(NULL?==?I2Cx)?return?0;

????printf("[lbc_info]?%s?%d?1\r\n",?__func__,?__LINE__);

????while(?I2C_GetFlagStatus(?I2Cx,?I2C_FLAG_BUSY?)?!=?RESET?);
????I2C_GenerateSTART(I2Cx,?ENABLE);

????printf("[lbc_info]?%s?%d?2\r\n",?__func__,?__LINE__);

????while(?!I2C_CheckEvent(?I2Cx,?I2C_EVENT_MASTER_MODE_SELECT?)?);
????I2C_Send7bitAddress(?I2Cx,?deviceAddr,?I2C_Direction_Transmitter?);

????printf("[lbc_info]?%s?%d?3\r\n",?__func__,?__LINE__);

????while(?!I2C_CheckEvent(?I2Cx,?I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED?)?);

????printf("[lbc_info]?%s?%d?4\r\n",?__func__,?__LINE__);

????I2C_SendData(I2Cx,?data);???????????????????????????????????????????????????//SEND?REG
????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_BYTE_TRANSMITTED));????????????//SEND?REG

????printf("[lbc_info]?%s?%d?5\r\n",?__func__,?__LINE__);

????I2C_GenerateSTART(I2Cx,?ENABLE);????????????????????????????????????????????//REPEATED?START
????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_MODE_SELECT));?????????????????//REPEATED?START

????printf("[lbc_info]?%s?%d?6\r\n",?__func__,?__LINE__);

????I2C_Send7bitAddress(I2Cx,?deviceAddr,?I2C_Direction_Receiver);??????????????//SEND?ADDR?R
????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));??????//SEND?ADDR?R

????printf("[lbc_info]?%s?%d?7\r\n",?__func__,?__LINE__);

#if?0
????I2C_AcknowledgeConfig(I2Cx,?DISABLE);???????????????????????????????????//ACK=0

????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_BYTE_RECEIVED));?/*?EV7?*/?????//WAIT?READ
????value?=?(uint16_t)I2C_ReceiveData(I2Cx)?<<?8;???????????????????????????????//READ?DATA

????printf("[lbc_info]?%s?%d?8\r\n",?__func__,?__LINE__);

????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_BYTE_RECEIVED));?/*?EV7?*/?????//WAIT?READ
????value?|=?(uint16_t)I2C_ReceiveData(I2Cx);???????????????????????????????????//READ?DATA

????printf("[lbc_info]?%s?%d?9\r\n",?__func__,?__LINE__);

????I2C_GenerateSTOP(I2Cx,?ENABLE);?????????????????????????????????????????????//STOP
#endif
#if?1
????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_BYTE_RECEIVED));?/*?EV7?*/?????//WAIT?READ
????value?=?(uint16_t)I2C_ReceiveData(I2Cx)?<<?8;???????????????????????????????//READ?DATA

????printf("[lbc_info]?%s?%d?8\r\n",?__func__,?__LINE__);

????I2C_AcknowledgeConfig(I2Cx,?DISABLE);???????????????????????????????????//ACK=0
????I2C_GenerateSTOP(I2Cx,?ENABLE);?????????????????????????????????????????????//STOP

????printf("[lbc_info]?%s?%d?9\r\n",?__func__,?__LINE__);

????while(!I2C_CheckEvent(I2Cx,?I2C_EVENT_MASTER_BYTE_RECEIVED));?/*?EV7?*/?????//WAIT?READ
????value?|=?(uint16_t)I2C_ReceiveData(I2Cx);???????????????????????????????????//READ?DATA
#endif

????return?value;
}



您好,可以參考一下EVT IIC讀寫EEPROM例程中讀取多個數據的寫法,讀寫的過程中不建議加這么多打印。后續(xù)若有問題,可郵箱(lzs@wch.cn)溝通。


可以試下這個封裝過的I2C庫:https://github.com/WuxiProject-offical/CH32X035-HelperLibrary/tree/main/I2C/Master

這個庫是適配X035系列的,但應該可以稍微改下或者參考這個狀態(tài)機的實現方法。


樓上推薦的庫做的不錯。

健壯的I2C是要有超時機制,避免總線鎖死的。這很重要,不是調試的時候OK就沒問題的。


只有登錄才能回復,可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频