|
LVGL应用的一大亮点就是极大简化了MCU存储和处理图片数据的难度,有专门一个结构体叫lv_image_dsc_t负责记录保存图片的RAW数据、长宽参数、占用空间和颜色格式,并且有专门的在线和离线工具负责生成lv_image_dsc_t,LVGL应用调用img或者img_btn控件时,直接指定lv_image_dsc_t结构体对象即可完成图像的填充,非常方便,本帖就使用MPU6050模块读取XY方向倾角数据,实现一个简单有趣的图片动画,并实现一个图片按钮(img_btn),按下和抬起分别显示两张图片。 MPU6050模块接在另一组模拟I2C接口上(PD11和PD12),与之前的BME680模块错开: #define FAKE_I2C_SCL_PD11_GPIO_PORT GPIOD #define FAKE_I2C_SCL_PD11_GPIO_PIN GPIO_PIN_11 #define FAKE_I2C_SCL_PD11_GPIO_CLK_ENABLE __HAL_RCC_GPIOD_CLK_ENABLE(); #define FAKE_I2C_SCL_PD11_H HAL_GPIO_WritePin(FAKE_I2C_SCL_PD11_GPIO_PORT , FAKE_I2C_SCL_PD11_GPIO_PIN , GPIO_PIN_SET); #define FAKE_I2C_SCL_PD11_L HAL_GPIO_WritePin(FAKE_I2C_SCL_PD11_GPIO_PORT , FAKE_I2C_SCL_PD11_GPIO_PIN , GPIO_PIN_RESET); #define FAKE_I2C_SDA_PD12_GPIO_PORT GPIOD #define FAKE_I2C_SDA_PD12_GPIO_PIN GPIO_PIN_12 #define FAKE_I2C_SDA_PD12_GPIO_CLK_ENABLE __HAL_RCC_GPIOD_CLK_ENABLE(); #define FAKE_I2C_SDA_PD12_H HAL_GPIO_WritePin(FAKE_I2C_SDA_PD12_GPIO_PORT , FAKE_I2C_SDA_PD12_GPIO_PIN , GPIO_PIN_SET); #define FAKE_I2C_SDA_PD12_L HAL_GPIO_WritePin(FAKE_I2C_SDA_PD12_GPIO_PORT , FAKE_I2C_SDA_PD12_GPIO_PIN , GPIO_PIN_RESET); #define IIC_READ_SDA_PD12 HAL_GPIO_ReadPin(FAKE_I2C_SDA_PD12_GPIO_PORT , FAKE_I2C_SDA_PD12_GPIO_PIN) 具体模拟I2C读写方式和BME680模块基本一致,只修改MPU6050初始化函数和倾角数据读写函数即可: uint8_t MPU6050_Init() { uint8_t data; uint8_t mpu9250_id; data = 0x07; MPU_Write_Reg(MPU6050_ADDR , MPU_SAMPLE_RATE_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_SAMPLE_RATE_REG); printf("MPU_SAMPLE_RATE_REG = 0x%x.\n" , data); data = 0x01; MPU_Write_Reg(MPU6050_ADDR , MPU_PWR_MGMT1_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_PWR_MGMT1_REG); printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); data = 0; MPU_Write_Reg(MPU6050_ADDR , MPU_CFG_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_CFG_REG); printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); data = 0x18; MPU_Write_Reg(MPU6050_ADDR , MPU_GYRO_CFG_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_GYRO_CFG_REG); printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); data = 0x01; MPU_Write_Reg(MPU6050_ADDR , MPU_INT_EN_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_INT_EN_REG); printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); data = 0; MPU_Write_Reg(MPU6050_ADDR , MPU_PWR_MGMT2_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_PWR_MGMT2_REG); printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); return mpu9250_id; } 初始化需要用作演示动画的img控件:
img_anim = lv_image_create(tile_3); lv_image_set_src(img_anim , &img_st_logo); lv_obj_align(img_anim , LV_ALIGN_TOP_LEFT , 100 , 100); 读取MPU6050数据并修改图片位置: static void my_timer1(lv_timer_t * timer) { 。。。 MPU_Read_Regs(MPU6050_ADDR , ACCEL_XOUT_H , mpu9250_read_data , 2); acc_x = mpu9250_read_data[0] << 8 | mpu9250_read_data[1]; MPU_Read_Regs(MPU6050_ADDR , ACCEL_YOUT_H , mpu9250_read_data + 2 , 2); acc_y = mpu9250_read_data[2] << 8 | mpu9250_read_data[3]; printf("acc_x = %d acc_y = %d %d.\n" , acc_x , acc_y); acc_x = - acc_x; acc_x_index = acc_x / 100; if(acc_x_index <= -80) acc_x_index = -80; else if(acc_x_index >= 80) acc_x_index = 80; acc_y_index = acc_y / 80; if(acc_y_index <= -195) acc_y_index = -195; else if(acc_y_index >= 195) acc_y_index = 195; lv_obj_align(img_anim , LV_ALIGN_CENTER , acc_x_index , acc_y_index); 。。。 } 然后是添加img_btn在第四页(tile_4)并设置按下和释放的图像数据:
imgbtn_st = lv_imagebutton_create(tile_4); lv_imagebutton_set_src(imgbtn_st , LV_IMAGEBUTTON_STATE_RELEASED , NULL , &img_st_poster1 , NULL); lv_imagebutton_set_src(imgbtn_st , LV_IMAGEBUTTON_STATE_PRESSED , NULL , &img_st_poster2 , NULL); lv_obj_align(imgbtn_st , LV_ALIGN_TOP_LEFT , 0 , 0); 演示效果: |
STM32L562DK探索板——建立演示菜单
STM32L562DK探索板——字符显示功能的剖析
【福利三:逢7发帖赢大礼】使用arc弧形拉条控件控制PWM舵机及使用SPI3接口操作NRF24L01模块进行无线通信
1-趋势痛点篇:嵌入式 GUI 爆发,传统外挂存储架构的多重工程瓶颈
告别外置存储!大容量内存单芯片MCU,重塑新一代嵌入式GUI
STM32L562DK探索板——继续测试Audio
请教下STM32N6570 怎么把分辨率改成320x240并可以全屏显示
STM32L562DK探索板——初试显示汉字
【福利三:逢7发帖赢大礼】调试nucleo-WBA65RI工程测试样板的一些心得
【福利三:逢7发帖赢大礼】lv_timer和BME680实现温度、湿度、气压数据读取
微信公众号
手机版