STM Nucleo I2C 不发送所有数据
STM Nucleo I2C not sending all data
编辑:
解决方案是调低初始化块中的 I2C 时钟。虽然 STM 可以处理它,但 LCD 的数据 sheet 表明它只能处理高达 10kHz。
对于 DMA,必须在 CubeMX 软件中启用和设置一个 IRQ,以启用 DMA TX/RX 行。
我正在使用带有 freeRTOS 的 STM32 - Nucleo-F401RE 开发板。最近用了点freeRTOS,但是没真正用过I2C。
尝试使用 CubeMX 生成的 I2C 驱动程序设置一个简单的 LCD display。
到目前为止,它只发送了我请求发送的数据的一半左右。
我已经使用简单的 "show firmware" 命令对其进行了测试,并且可以正常工作。所以我可以验证 I2C 实例是否设置正确。
/* I2C1 init function */
static 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();
}
}
还设置了国际化的上拉电阻。
/* vdebugTask function */
void vdebugTask(void const * argument)
{
/* USER CODE BEGIN vdebugTask */
/* Infinite loop */
for(;;)
{
char hi[6];
hi[0] = 'h';
hi[1] = 'e';
hi[2] = 'y';
hi[3] = 'a';
hi[4] = 'h';
hi[5] = '!';
HAL_I2C_Master_Transmit_DMA(&hi2c1, (0x50), hi, 6);
vTaskDelay(10);
}
/* USER CODE END vdebugTask */
}
这是我正在尝试的代码 运行,我根本没有更改 HAL 函数。我不认为它可以比这更简单,但是这就是所有发生的事情。
我遵循了 LCD 数据 sheet 中的时序限制,CubeMX 软件没有警告或声明其 I2C 驱动程序有任何特殊要求。我的程序有问题吗?
我也试过使用同样由CubeMX创建的非DMA阻塞模式轮询传输函数
HAL_I2C_Master_Transmit(&hi2c1, (0x50), hi, 6, 1000);
这更糟,只是 continuously spams the screen with unintelligible text。
解决方案是调低初始化块中的 I2C 时钟。虽然 STM 可以处理它,但 LCD 的数据 sheet 表明它只能处理高达 10kHz 的频率。
对于 DMA,必须在 CubeMX 软件中启用和设置一个 IRQ,这将启用 DMA TX/RX 行。
请注意,时钟仍必须遵守硬件限制。我假设比数据 sheet 中规定的最大值少大约 20% 就足够了。对于我的 LCD,这意味着我将使用 80kHz。
首先进入配置:
然后单击 DMA 以设置 DMA 请求。我只选择了 TX,因为我不关心来自 LCD 的 RX DMA。
编辑:
解决方案是调低初始化块中的 I2C 时钟。虽然 STM 可以处理它,但 LCD 的数据 sheet 表明它只能处理高达 10kHz。
对于 DMA,必须在 CubeMX 软件中启用和设置一个 IRQ,以启用 DMA TX/RX 行。
我正在使用带有 freeRTOS 的 STM32 - Nucleo-F401RE 开发板。最近用了点freeRTOS,但是没真正用过I2C。
尝试使用 CubeMX 生成的 I2C 驱动程序设置一个简单的 LCD display。
到目前为止,它只发送了我请求发送的数据的一半左右。 我已经使用简单的 "show firmware" 命令对其进行了测试,并且可以正常工作。所以我可以验证 I2C 实例是否设置正确。
/* I2C1 init function */
static 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();
}
}
还设置了国际化的上拉电阻。
/* vdebugTask function */
void vdebugTask(void const * argument)
{
/* USER CODE BEGIN vdebugTask */
/* Infinite loop */
for(;;)
{
char hi[6];
hi[0] = 'h';
hi[1] = 'e';
hi[2] = 'y';
hi[3] = 'a';
hi[4] = 'h';
hi[5] = '!';
HAL_I2C_Master_Transmit_DMA(&hi2c1, (0x50), hi, 6);
vTaskDelay(10);
}
/* USER CODE END vdebugTask */
}
这是我正在尝试的代码 运行,我根本没有更改 HAL 函数。我不认为它可以比这更简单,但是这就是所有发生的事情。
我遵循了 LCD 数据 sheet 中的时序限制,CubeMX 软件没有警告或声明其 I2C 驱动程序有任何特殊要求。我的程序有问题吗?
我也试过使用同样由CubeMX创建的非DMA阻塞模式轮询传输函数
HAL_I2C_Master_Transmit(&hi2c1, (0x50), hi, 6, 1000);
这更糟,只是 continuously spams the screen with unintelligible text。
解决方案是调低初始化块中的 I2C 时钟。虽然 STM 可以处理它,但 LCD 的数据 sheet 表明它只能处理高达 10kHz 的频率。 对于 DMA,必须在 CubeMX 软件中启用和设置一个 IRQ,这将启用 DMA TX/RX 行。
请注意,时钟仍必须遵守硬件限制。我假设比数据 sheet 中规定的最大值少大约 20% 就足够了。对于我的 LCD,这意味着我将使用 80kHz。
首先进入配置:
然后单击 DMA 以设置 DMA 请求。我只选择了 TX,因为我不关心来自 LCD 的 RX DMA。