Meine Erfahrung in der Programmierung von MCU ist nur Arduino (auch STM32F103 über Arduino). Ich habe jetzt begonnen, den STM32CUBEIDE und einen ST-Link V2 zu verwenden, um meinen STM32f103 zu programmieren.
Ich habe die Funktionen ausprobiert:
HAL_I2C_IsDeviceReady
HAL_I2C_Master_Transmit
HAL_I2C_Master_Receive
HAL_I2C_Mem_Read
und der Rückgabewert von 'HAL_StatusTypeDef' ist immer '1' beim ersten Aufruf und '2' bei den folgenden Aufrufen (einer der oben aufgeführten Funktionen).
1 bedeutet ERROR und 2 bedeutet BUSY. 3 würde TIMEOUT bedeuten und 0 würde OK bedeuten, soweit ich weiß.
Meine Fragen sind: Selbst wenn ich die I2C-Adresse ändere, ist die Rückgabe beim ersten Aufruf immer noch 1 (ERROR) und niemals 3 (TIMEOUT). Warum?
Laut diesem: https://os.mbed.com/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/stm32l4xx__hal__i2c_8c_source.html#l02221
HAL_I2C_IsDeviceReady
sollte nicht einmal 1 zurückgeben, nur 0 und 3 ...
Kann mir jemand sagen was ich falsch mache? Ich richte die Pins in STM32Cube (PB6 und PB7) richtig ein:
void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(i2cHandle->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**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_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* I2C1 clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
Und die initialize-Funktion aufgerufen (so wie die IDE im Code-Setup für mich vorbereitet hat):
/* USER CODE BEGIN 0 */
HAL_StatusTypeDef ret;
unsigned char buf[2];
uint16_t val;
int16_t valt;
float temp_c;
float RoomTemp_Offset = 0;
float Temp_Sensitivity = 321;
/* USER CODE END 0 */
int main(void)
{
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
DWT_Delay_Init();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
ret = HAL_I2C_IsDeviceReady(&hi2c1, MPU9250_ADDR, 10, 100);
printf("Is Ready: %d \n", ret);
/* USER CODE END 2 */
/* Infinite loop */
while (1)
{
// Tell MPU9250 that we want to read from the temperature register
val = read_register(0x41);
valt = ((int16_t)val << 4) | (val >> 4);
temp_c = ((valt - RoomTemp_Offset)/Temp_Sensitivity) + 21;
printf("reading...\n");
printf("%.6f \n", temp_c);
}
}
und die read_register
Funktion ist hier definiert:
uint16_t read_register(uint16_t register_pointer)
{
HAL_StatusTypeDef status = HAL_OK;
uint16_t return_value = 0;
status = HAL_I2C_Mem_Read(&hi2c1, MPU9250_ADDR, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT, &return_value, 2, 100);
printf("read HAL_RET: %d \n", status);
/* Check the communication status */
if(status != HAL_OK)
{
Error_Handler();
}
return return_value;
}
und die Gesamtausgabe des Skripts ower SWO:
Is Ready: 1
read HAL_RET: 2
reading...
read HAL_RET: 2
reading...
read HAL_RET: 2
reading...
read HAL_RET: 2
Okay, danke Brhans für deinen Kommentar. Ich dachte, ich hätte mich darum gekümmert, aber die Taktlinie wurde auf 3v3 hochgezogen, jetzt funktioniert es. Vielen Dank!
Auch diese Zeile habe ich geändert
valt = ((int16_t)val << 4) | (val >> 4);
Zu
valt = ((int16_t)buf[0] << 8) | (buf[1]);
brhans