STM32L4 I2C LED 驱动器
STM32L4 I2C LED Driver
我正在尝试使用 IS31FL3236A LED 驱动器来控制 LED,来自 LUMISSIL Microsystem 与 I2C 通信。
我用的是STM32的HAL通讯协议,我可以点亮所有的LED,但是我不明白为什么我不能一个一个地控制LED或者选择LED的亮度。
这是我的代码。
IS31FL3236A.h配置所有通道地址和设备地址
#define Single 0
#define RGB 1
#define Addr_GND 0x78 // P7 datasheet 0x78 = 1111000 en bit (addr 1)
#define PWM 0x04
#define All_EN 0x4A
#define IS3236_REG_PWM_OUT1 0x01 //LED PWM
#define IS3236_REG_PWM_OUT2 0x02
#define IS3236_REG_PWM_OUT3 0x03
#define IS3236_REG_PWM_OUT4 0x04
#define IS3236_REG_PWM_OUT5 0x05
#define IS3236_REG_PWM_OUT6 0x06
#define IS3236_REG_PWM_OUT7 0x07
#define IS3236_REG_PWM_OUT8 0x08
#define IS3236_REG_PWM_OUT9 0x09
#define IS3236_REG_PWM_OUT10 0x0A
#define IS3236_REG_PWM_OUT11 0x0B
#define IS3236_REG_PWM_OUT12 0x0C
#define IS3236_REG_PWM_OUT13 0x0D
#define IS3236_REG_PWM_OUT14 0x0E
#define IS3236_REG_PWM_OUT15 0x0F
#define IS3236_REG_PWM_OUT16 0x10
#define IS3236_REG_PWM_OUT17 0x11
#define IS3236_REG_PWM_OUT18 0x12
#define IS3236_REG_PWM_OUT19 0x13
#define IS3236_REG_PWM_OUT20 0x14
#define IS3236_REG_PWM_OUT21 0x15
#define IS3236_REG_PWM_OUT22 0x16
#define IS3236_REG_PWM_OUT23 0x17
#define IS3236_REG_PWM_OUT24 0x18
#define IS3236_REG_PWM_OUT25 0x19
#define IS3236_REG_PWM_OUT26 0x1A
#define IS3236_REG_PWM_OUT27 0x1B
#define IS3236_REG_PWM_OUT28 0x1C
#define IS3236_REG_PWM_OUT29 0x1D
#define IS3236_REG_PWM_OUT30 0x1E
#define IS3236_REG_PWM_OUT31 0x1F
#define IS3236_REG_PWM_OUT32 0x20
#define IS3236_REG_PWM_OUT33 0x21
#define IS3236_REG_PWM_OUT34 0x22
#define IS3236_REG_PWM_OUT35 0x23
#define IS3236_REG_PWM_OUT36 0x24
#define IS3236_REG_CTRL_OUT1 0x26 //LED ONOFF
#define IS3236_REG_CTRL_OUT2 0x27
#define IS3236_REG_CTRL_OUT3 0x28
#define IS3236_REG_CTRL_OUT4 0x29
#define IS3236_REG_CTRL_OUT5 0x2A
#define IS3236_REG_CTRL_OUT6 0x2B
#define IS3236_REG_CTRL_OUT7 0x2C
#define IS3236_REG_CTRL_OUT8 0x2D
#define IS3236_REG_CTRL_OUT9 0x2E
#define IS3236_REG_CTRL_OUT10 0x2F
#define IS3236_REG_CTRL_OUT11 0x30
#define IS3236_REG_CTRL_OUT12 0x31
#define IS3236_REG_CTRL_OUT13 0x32
#define IS3236_REG_CTRL_OUT14 0x33
#define IS3236_REG_CTRL_OUT15 0x34
#define IS3236_REG_CTRL_OUT16 0x35
#define IS3236_REG_CTRL_OUT17 0x36
#define IS3236_REG_CTRL_OUT18 0x37
#define IS3236_REG_CTRL_OUT19 0x38
#define IS3236_REG_CTRL_OUT20 0x39
#define IS3236_REG_CTRL_OUT21 0x3A
#define IS3236_REG_CTRL_OUT22 0x3B
#define IS3236_REG_CTRL_OUT23 0x3C
#define IS3236_REG_CTRL_OUT24 0x3D
#define IS3236_REG_CTRL_OUT25 0x3E
#define IS3236_REG_CTRL_OUT26 0x3F
#define IS3236_REG_CTRL_OUT27 0x40
#define IS3236_REG_CTRL_OUT28 0x41
#define IS3236_REG_CTRL_OUT29 0x42
#define IS3236_REG_CTRL_OUT30 0x43
#define IS3236_REG_CTRL_OUT31 0x44
#define IS3236_REG_CTRL_OUT32 0x45
#define IS3236_REG_CTRL_OUT33 0x46
#define IS3236_REG_CTRL_OUT34 0x47
#define IS3236_REG_CTRL_OUT35 0x48
#define IS3236_REG_CTRL_OUT36 0x49
#define Imax 0x11
#define update 0x25
#define freq 0x4B
#define mode 0x01
main.c 打开所有 LED
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
//I2C_GPIO_Init();
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART2_UART_Init();
MX_TIM1_Init();
/* USER CODE BEGIN 2 */
//I2C_GPIO_Init();
IS31FL3236A_Init();
static const uint16_t LED19 = 0x13;
static const uint16_t LED19PWM = 0x38;
static const uint16_t deviceAddr = 0x78;
static const uint16_t Update = 0x25;
static const uint16_t Freq = 0x4B;
static const uint16_t intensityPWM = 0x02;
static const uint16_t CurrentMax = 0x00;
static const uint16_t Mode = 0x01;
uint8_t pwm[bufSize];
uint8_t current[bufSize];
uint8_t mode1[bufSize];
pwm[0] = 0x7B;
current[0] = 0x00;
mode1[0] = 0x01;
uint8_t i=0;
/*for(i=0;i<=0x49;i++){
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, i, I2C_MEMADD_SIZE_16BIT, (uint8_t*)PWM, 1, HAL_MAX_DELAY);
}
for(i=0;i<=0x24;i++){
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, i, sizeof(i), (uint8_t*)Imax, sizeof(Imax), 10);
}*/
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, LED19PWM, I2C_MEMADD_SIZE_8BIT, pwm, bufSize, 10);
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, LED19, I2C_MEMADD_SIZE_8BIT, current, bufSize, 10);
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, Freq, I2C_MEMADD_SIZE_8BIT, current, bufSize, 10);
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, Mode, I2C_MEMADD_SIZE_8BIT, current, bufSize, 10);
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, Update, I2C_MEMADD_SIZE_8BIT, mode1, bufSize, 10);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/*uint8_t i=0;
for(i=0;i<=0x49;i++){
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, i, sizeof(i), (uint8_t*)PWM, sizeof(PWM), 10);
}
for(i=0;i<=0x24;i++){
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, i, sizeof(i), (uint8_t*)Imax, sizeof(Imax), 10);
}
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, freq, sizeof(freq), (uint8_t*)Imax, sizeof(Imax), 10);
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, mode, sizeof(mode), (uint8_t*)Imax, sizeof(Imax), 10);
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, RESET, sizeof(RESET), (uint8_t*)mode, sizeof(mode), 10);
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, update, sizeof(update), (uint8_t*)mode, sizeof(mode), 10);*/
//Swith();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
以 select LED 19 为例,我只是删除了两个 for 循环并添加了这个,但是 LED 不亮。
HAL_I2C_Mem_Write(&hi2c1, GND, IS3236_REG_PWM_OUT19, sizeof(IS3236_REG_PWM_OUT19), (uint8_t*)PWM, sizeof(PWM), 10);
HAL_I2C_Mem_Write(&hi2c1, GND, IS3236_REG_CTRL_OUT19, sizeof(IS3236_REG_CTRL_OUT19), (uint8_t*)Imax, sizeof(Imax), 10);
HAL_I2C_Mem_Write(&hi2c1, GND, update, sizeof(update), (uint8_t*)mode, sizeof(mode), 10);
I2C 配置
/**
* @brief I2C1 Initialization Function
* @param None
* @retval None
*/
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x00702991;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
stm32l4xx_hal_msp.c
/**
* @brief I2C MSP Initialization
* This function configures the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**I2C1 GPIO Configuration
PA9 ------> I2C1_SCL
PA10 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
/**
* @brief I2C MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspDeInit 0 */
/* USER CODE END I2C1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C1_CLK_DISABLE();
/**I2C1 GPIO Configuration
PA9 ------> I2C1_SCL
PA10 ------> I2C1_SDA
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_10);
/* USER CODE BEGIN I2C1_MspDeInit 1 */
/* USER CODE END I2C1_MspDeInit 1 */
}
}
这是STM32所期望的
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c,
uint16_t DevAddress,
uint16_t MemAddress,
uint16_t MemAddSize,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
这是你给的:
HAL_I2C_Mem_Write(&hi2c1, GND, IS3236_REG_PWM_OUT19, sizeof(IS3236_REG_PWM_OUT19), (uint8_t*)PWM, sizeof(PWM), 10);
HAL_I2C_Mem_Write(&hi2c1, GND, IS3236_REG_CTRL_OUT19, sizeof(IS3236_REG_CTRL_OUT19), (uint8_t*)Imax, sizeof(Imax), 10);
HAL_I2C_Mem_Write(&hi2c1, GND, update, sizeof(update), (uint8_t*)mode, sizeof(mode), 10);
- Do not take a sizeof(#define)
- 重新绑定寄存器#defines 为静态常量。或者根据需要#define MemAddSize
- Don't use a pointer to a #define
- 将您的 MemAddSize 更改为:I2C_MEMADD_SIZE_16BIT、I2C_MEMADD_SIZE_8BIT
我盲目猜测为什么系统能够打开或关闭所有 LED 并达到最大亮度是由于地址自动递增。
尝试使用 I2C_MEM_WRITE() 使用幻数和局部变量、缓冲区和指针。如果这可行,那么很可能是您在驱动程序文件中使用了#defines。
在每次调用之间检查 HAL_StatusTypeDef 的 return 类型。确保一切正常。
这里有两个stm32 i2c的例子:
------------回复1------------
不要对 Size 参数使用 I2C_MEMADD_SIZE_16BIT。您需要指定您指向的缓冲区的数量。转到本地源代码并查看有关如何使用 I2C_mem_write() 的说明。根据数据 sheet,我相信您也应该使用 I2C_MEMADD_SIZE_8BIT 而不是 16.
假设您有一个大小为 1 的缓冲区。那么您只想读取一个字节。
#define bufSize 1
uint8_t myBuf[bufSize];
myBuf[0] = someDataVal;
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, LED19, I2C_MEMADD_SIZE_8BIT, myBuf, bufSize , 10);
------------回复2------------
是否定义了bufSize?如果有,是几号?
如果您只从每个 buf 写入一个字节,则需要分配给每个 buf 的第一个索引。 pwm[0]、电流[0](不是 1)、mode1[0](不是 2)。
uint8_t pwm[bufSize];
uint8_t current[bufSize];
uint8_t mode1[bufSize];
pwm[0] = 0x7B;
current[1] = 0x00;
mode1[2] = 0x01;
------------回复3------------
// First lets discuss device address
// What is your AD pin connected to (PG 7)
// Currently you have it configured to 0x78. Bit shift it for STM32
// 0x78 << 1
uint8_t myBuf[1];
// Turn on the device by writing to register 0. Shutdown register
myBuf[0] = 0x01;
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78) << 1, 0x00, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10;
// Then lets assign the pwm to the first LED (OUT1). Register 1. Reuse prior buffer.
myBuf[0] = 0x80;
// Lets toggle LED 19
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78) << 1, 0x01, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10;
// Enable OUT1 via Control register 26
myBuf[0] = 0x01; // This would have maximum current settings (Pg. 9)
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78) << 1, 0x26, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10;
// Tell system to update the registers. Register 25
myBuf[0] = 0x00;
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78) << 1, 0x25, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10;
- 我总是鼓励您查看每个 return 的 HAL_STATUS。你能告诉我是否可以吗?
偏移量改变了设备地址,你不应该做偏移量,它的工作原理是这样的:
// First lets discuss device address
// What is your AD pin connected to (PG 7)
uint8_t myBuf[1];
// First lets turn on the device by writing to register 0. Shutdown register
myBuf[0] = 0x01;
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78), 0x00, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10);
// Then lets assign the pwm to the first LED (OUT1). Register 1. Reuse prior buffer.
myBuf[0] = 0xff;
// Lets toggle LED 19
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78), 0x13, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10);
// Enable OUT1 via Control register 26
myBuf[0] = 0x01; // This would have maximum current settings (Pg. 9)
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78), 0x38, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10);
// Tell system to update the registers. Register 25
myBuf[0] = 0x00;
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78), 0x25, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10);
感谢您的帮助@Frebreeze 现在可以使用了。
我正在尝试使用 IS31FL3236A LED 驱动器来控制 LED,来自 LUMISSIL Microsystem 与 I2C 通信。
我用的是STM32的HAL通讯协议,我可以点亮所有的LED,但是我不明白为什么我不能一个一个地控制LED或者选择LED的亮度。
这是我的代码。
IS31FL3236A.h配置所有通道地址和设备地址
#define Single 0
#define RGB 1
#define Addr_GND 0x78 // P7 datasheet 0x78 = 1111000 en bit (addr 1)
#define PWM 0x04
#define All_EN 0x4A
#define IS3236_REG_PWM_OUT1 0x01 //LED PWM
#define IS3236_REG_PWM_OUT2 0x02
#define IS3236_REG_PWM_OUT3 0x03
#define IS3236_REG_PWM_OUT4 0x04
#define IS3236_REG_PWM_OUT5 0x05
#define IS3236_REG_PWM_OUT6 0x06
#define IS3236_REG_PWM_OUT7 0x07
#define IS3236_REG_PWM_OUT8 0x08
#define IS3236_REG_PWM_OUT9 0x09
#define IS3236_REG_PWM_OUT10 0x0A
#define IS3236_REG_PWM_OUT11 0x0B
#define IS3236_REG_PWM_OUT12 0x0C
#define IS3236_REG_PWM_OUT13 0x0D
#define IS3236_REG_PWM_OUT14 0x0E
#define IS3236_REG_PWM_OUT15 0x0F
#define IS3236_REG_PWM_OUT16 0x10
#define IS3236_REG_PWM_OUT17 0x11
#define IS3236_REG_PWM_OUT18 0x12
#define IS3236_REG_PWM_OUT19 0x13
#define IS3236_REG_PWM_OUT20 0x14
#define IS3236_REG_PWM_OUT21 0x15
#define IS3236_REG_PWM_OUT22 0x16
#define IS3236_REG_PWM_OUT23 0x17
#define IS3236_REG_PWM_OUT24 0x18
#define IS3236_REG_PWM_OUT25 0x19
#define IS3236_REG_PWM_OUT26 0x1A
#define IS3236_REG_PWM_OUT27 0x1B
#define IS3236_REG_PWM_OUT28 0x1C
#define IS3236_REG_PWM_OUT29 0x1D
#define IS3236_REG_PWM_OUT30 0x1E
#define IS3236_REG_PWM_OUT31 0x1F
#define IS3236_REG_PWM_OUT32 0x20
#define IS3236_REG_PWM_OUT33 0x21
#define IS3236_REG_PWM_OUT34 0x22
#define IS3236_REG_PWM_OUT35 0x23
#define IS3236_REG_PWM_OUT36 0x24
#define IS3236_REG_CTRL_OUT1 0x26 //LED ONOFF
#define IS3236_REG_CTRL_OUT2 0x27
#define IS3236_REG_CTRL_OUT3 0x28
#define IS3236_REG_CTRL_OUT4 0x29
#define IS3236_REG_CTRL_OUT5 0x2A
#define IS3236_REG_CTRL_OUT6 0x2B
#define IS3236_REG_CTRL_OUT7 0x2C
#define IS3236_REG_CTRL_OUT8 0x2D
#define IS3236_REG_CTRL_OUT9 0x2E
#define IS3236_REG_CTRL_OUT10 0x2F
#define IS3236_REG_CTRL_OUT11 0x30
#define IS3236_REG_CTRL_OUT12 0x31
#define IS3236_REG_CTRL_OUT13 0x32
#define IS3236_REG_CTRL_OUT14 0x33
#define IS3236_REG_CTRL_OUT15 0x34
#define IS3236_REG_CTRL_OUT16 0x35
#define IS3236_REG_CTRL_OUT17 0x36
#define IS3236_REG_CTRL_OUT18 0x37
#define IS3236_REG_CTRL_OUT19 0x38
#define IS3236_REG_CTRL_OUT20 0x39
#define IS3236_REG_CTRL_OUT21 0x3A
#define IS3236_REG_CTRL_OUT22 0x3B
#define IS3236_REG_CTRL_OUT23 0x3C
#define IS3236_REG_CTRL_OUT24 0x3D
#define IS3236_REG_CTRL_OUT25 0x3E
#define IS3236_REG_CTRL_OUT26 0x3F
#define IS3236_REG_CTRL_OUT27 0x40
#define IS3236_REG_CTRL_OUT28 0x41
#define IS3236_REG_CTRL_OUT29 0x42
#define IS3236_REG_CTRL_OUT30 0x43
#define IS3236_REG_CTRL_OUT31 0x44
#define IS3236_REG_CTRL_OUT32 0x45
#define IS3236_REG_CTRL_OUT33 0x46
#define IS3236_REG_CTRL_OUT34 0x47
#define IS3236_REG_CTRL_OUT35 0x48
#define IS3236_REG_CTRL_OUT36 0x49
#define Imax 0x11
#define update 0x25
#define freq 0x4B
#define mode 0x01
main.c 打开所有 LED
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
//I2C_GPIO_Init();
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART2_UART_Init();
MX_TIM1_Init();
/* USER CODE BEGIN 2 */
//I2C_GPIO_Init();
IS31FL3236A_Init();
static const uint16_t LED19 = 0x13;
static const uint16_t LED19PWM = 0x38;
static const uint16_t deviceAddr = 0x78;
static const uint16_t Update = 0x25;
static const uint16_t Freq = 0x4B;
static const uint16_t intensityPWM = 0x02;
static const uint16_t CurrentMax = 0x00;
static const uint16_t Mode = 0x01;
uint8_t pwm[bufSize];
uint8_t current[bufSize];
uint8_t mode1[bufSize];
pwm[0] = 0x7B;
current[0] = 0x00;
mode1[0] = 0x01;
uint8_t i=0;
/*for(i=0;i<=0x49;i++){
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, i, I2C_MEMADD_SIZE_16BIT, (uint8_t*)PWM, 1, HAL_MAX_DELAY);
}
for(i=0;i<=0x24;i++){
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, i, sizeof(i), (uint8_t*)Imax, sizeof(Imax), 10);
}*/
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, LED19PWM, I2C_MEMADD_SIZE_8BIT, pwm, bufSize, 10);
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, LED19, I2C_MEMADD_SIZE_8BIT, current, bufSize, 10);
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, Freq, I2C_MEMADD_SIZE_8BIT, current, bufSize, 10);
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, Mode, I2C_MEMADD_SIZE_8BIT, current, bufSize, 10);
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, Update, I2C_MEMADD_SIZE_8BIT, mode1, bufSize, 10);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/*uint8_t i=0;
for(i=0;i<=0x49;i++){
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, i, sizeof(i), (uint8_t*)PWM, sizeof(PWM), 10);
}
for(i=0;i<=0x24;i++){
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, i, sizeof(i), (uint8_t*)Imax, sizeof(Imax), 10);
}
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, freq, sizeof(freq), (uint8_t*)Imax, sizeof(Imax), 10);
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, mode, sizeof(mode), (uint8_t*)Imax, sizeof(Imax), 10);
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, RESET, sizeof(RESET), (uint8_t*)mode, sizeof(mode), 10);
HAL_I2C_Mem_Write(&hi2c1, Addr_GND, update, sizeof(update), (uint8_t*)mode, sizeof(mode), 10);*/
//Swith();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
以 select LED 19 为例,我只是删除了两个 for 循环并添加了这个,但是 LED 不亮。
HAL_I2C_Mem_Write(&hi2c1, GND, IS3236_REG_PWM_OUT19, sizeof(IS3236_REG_PWM_OUT19), (uint8_t*)PWM, sizeof(PWM), 10);
HAL_I2C_Mem_Write(&hi2c1, GND, IS3236_REG_CTRL_OUT19, sizeof(IS3236_REG_CTRL_OUT19), (uint8_t*)Imax, sizeof(Imax), 10);
HAL_I2C_Mem_Write(&hi2c1, GND, update, sizeof(update), (uint8_t*)mode, sizeof(mode), 10);
I2C 配置
/**
* @brief I2C1 Initialization Function
* @param None
* @retval None
*/
static void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x00702991;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
stm32l4xx_hal_msp.c
/**
* @brief I2C MSP Initialization
* This function configures the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**I2C1 GPIO Configuration
PA9 ------> I2C1_SCL
PA10 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
/**
* @brief I2C MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspDeInit 0 */
/* USER CODE END I2C1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C1_CLK_DISABLE();
/**I2C1 GPIO Configuration
PA9 ------> I2C1_SCL
PA10 ------> I2C1_SDA
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_10);
/* USER CODE BEGIN I2C1_MspDeInit 1 */
/* USER CODE END I2C1_MspDeInit 1 */
}
}
这是STM32所期望的
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c,
uint16_t DevAddress,
uint16_t MemAddress,
uint16_t MemAddSize,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
这是你给的:
HAL_I2C_Mem_Write(&hi2c1, GND, IS3236_REG_PWM_OUT19, sizeof(IS3236_REG_PWM_OUT19), (uint8_t*)PWM, sizeof(PWM), 10);
HAL_I2C_Mem_Write(&hi2c1, GND, IS3236_REG_CTRL_OUT19, sizeof(IS3236_REG_CTRL_OUT19), (uint8_t*)Imax, sizeof(Imax), 10);
HAL_I2C_Mem_Write(&hi2c1, GND, update, sizeof(update), (uint8_t*)mode, sizeof(mode), 10);
- Do not take a sizeof(#define)
- 重新绑定寄存器#defines 为静态常量。或者根据需要#define MemAddSize
- Don't use a pointer to a #define
- 将您的 MemAddSize 更改为:I2C_MEMADD_SIZE_16BIT、I2C_MEMADD_SIZE_8BIT
我盲目猜测为什么系统能够打开或关闭所有 LED 并达到最大亮度是由于地址自动递增。
尝试使用 I2C_MEM_WRITE() 使用幻数和局部变量、缓冲区和指针。如果这可行,那么很可能是您在驱动程序文件中使用了#defines。
在每次调用之间检查 HAL_StatusTypeDef 的 return 类型。确保一切正常。
这里有两个stm32 i2c的例子:
------------回复1------------
不要对 Size 参数使用 I2C_MEMADD_SIZE_16BIT。您需要指定您指向的缓冲区的数量。转到本地源代码并查看有关如何使用 I2C_mem_write() 的说明。根据数据 sheet,我相信您也应该使用 I2C_MEMADD_SIZE_8BIT 而不是 16.
假设您有一个大小为 1 的缓冲区。那么您只想读取一个字节。
#define bufSize 1
uint8_t myBuf[bufSize];
myBuf[0] = someDataVal;
HAL_I2C_Mem_Write(&hi2c1, deviceAddr, LED19, I2C_MEMADD_SIZE_8BIT, myBuf, bufSize , 10);
------------回复2------------
是否定义了bufSize?如果有,是几号?
如果您只从每个 buf 写入一个字节,则需要分配给每个 buf 的第一个索引。 pwm[0]、电流[0](不是 1)、mode1[0](不是 2)。
uint8_t pwm[bufSize]; uint8_t current[bufSize]; uint8_t mode1[bufSize]; pwm[0] = 0x7B; current[1] = 0x00; mode1[2] = 0x01;
------------回复3------------
// First lets discuss device address
// What is your AD pin connected to (PG 7)
// Currently you have it configured to 0x78. Bit shift it for STM32
// 0x78 << 1
uint8_t myBuf[1];
// Turn on the device by writing to register 0. Shutdown register
myBuf[0] = 0x01;
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78) << 1, 0x00, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10;
// Then lets assign the pwm to the first LED (OUT1). Register 1. Reuse prior buffer.
myBuf[0] = 0x80;
// Lets toggle LED 19
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78) << 1, 0x01, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10;
// Enable OUT1 via Control register 26
myBuf[0] = 0x01; // This would have maximum current settings (Pg. 9)
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78) << 1, 0x26, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10;
// Tell system to update the registers. Register 25
myBuf[0] = 0x00;
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78) << 1, 0x25, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10;
- 我总是鼓励您查看每个 return 的 HAL_STATUS。你能告诉我是否可以吗?
偏移量改变了设备地址,你不应该做偏移量,它的工作原理是这样的:
// First lets discuss device address
// What is your AD pin connected to (PG 7)
uint8_t myBuf[1];
// First lets turn on the device by writing to register 0. Shutdown register
myBuf[0] = 0x01;
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78), 0x00, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10);
// Then lets assign the pwm to the first LED (OUT1). Register 1. Reuse prior buffer.
myBuf[0] = 0xff;
// Lets toggle LED 19
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78), 0x13, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10);
// Enable OUT1 via Control register 26
myBuf[0] = 0x01; // This would have maximum current settings (Pg. 9)
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78), 0x38, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10);
// Tell system to update the registers. Register 25
myBuf[0] = 0x00;
HAL_I2C_Mem_Write(&hi2c1, ((uint16_t) 0x78), 0x25, I2C_MEMADD_SIZE_8BIT, myBuf, 1, 10);
感谢您的帮助@Frebreeze 现在可以使用了。