Als Referenz: Das gleiche Problem wird dort beschrieben, aber die Lösung des Autors funktioniert bei mir nicht - I2C beschäftigt Flag seltsames Verhalten
Ich habe STM32CubeMX verwendet, um eine Projektvorlage mit Initialisierung der I2C-Peripheriegeräte zu generieren. Leider funktioniert es irgendwie seltsam: Nach HAL_I2C_MspInit(I2C1)
dem Aufruf gilt der Bus als permanent besetzt.
Wenn ich versuche mich zu bewerben
__HAL_RCC_I2C1_FORCE_RESET();
HAL_Delay(1000);
__HAL_RCC_I2C1_RELEASE_RESET();
Das behebt das Problem mit dem BUSY
Flag, verursacht jedoch ein Problem - das SB
Bit wird nicht gesetzt, nachdem START
es generiert wurde. Laut Debugger werden I2C-Register nach dem Zurücksetzen vollständig gelöscht - ich vermute, dass dies das Problem bei dieser Methode ist.
Ich habe auch einen kurzen Spannungsabfall an der SDA-Leitung während des Startvorgangs bestätigt, was wahrscheinlich die Ursache des Problems ist. Ich habe mir den von CubeMX generierten Initialisierungscode für SDA / SCL-Pins genauer angesehen:
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
Ich habe es geändert, um die Uhr vor dem HAL_GPIO_Init()
Aufruf zu aktivieren, und jetzt funktioniert meine I2C-Kommunikation (zumindest habe ich noch nichts Seltsames bemerkt).
Schließlich ist meine Frage - gibt es eine bessere Lösung dafür? CubeMX platziert den Clock-Aktivierungscode nach dem Aufruf der GPIO-Init-Methode. Ich kann bei zwei Aufrufen von bleiben __HAL_RCC_I2C1_CLK_ENABLE()
, aber das ist meiner Meinung nach ziemlich hässlich, deshalb suche ich nach einer besseren Lösung, entweder Software oder Hardware.
Das Gerät ist STM32F100RB auf der STM32VLDiscovery-Karte (mit STLink v1), falls dies von Bedeutung ist.