|
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模块错开:6 z7 H9 k, G$ `5 } b #define FAKE_I2C_SCL_PD11_GPIO_PORT GPIOD #define FAKE_I2C_SCL_PD11_GPIO_PIN GPIO_PIN_11- @; ^) }( d) R, g7 ]/ I #define FAKE_I2C_SCL_PD11_GPIO_CLK_ENABLE __HAL_RCC_GPIOD_CLK_ENABLE();( C( q* W" t. o$ A0 T; A - _) q k6 v) X; \ t #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); # n2 i9 \! ~+ h' C: I0 n+ ^ #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();2 _) U9 I/ b0 k0 G# f* J D4 n #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);) H5 ~' n! {9 r+ a ( M) f) y+ ^/ F6 q 8 H( g8 R5 K9 T& w9 s #define IIC_READ_SDA_PD12 HAL_GPIO_ReadPin(FAKE_I2C_SDA_PD12_GPIO_PORT , FAKE_I2C_SDA_PD12_GPIO_PIN)* w: q/ ]* w' {. g $ G" o7 Y) v. x" E# v 具体模拟I2C读写方式和BME680模块基本一致,只修改MPU6050初始化函数和倾角数据读写函数即可: $ w* D9 R: U# N* N$ S0 q: A. R uint8_t MPU6050_Init() {# j j& x% Z1 {" R9 B uint8_t data;" \# T- T- @# ~; O0 K) {# @ uint8_t mpu9250_id;4 e- b6 V1 y l0 s, _ 5 C& }& |" X' J$ v data = 0x07;, `4 [6 S0 R1 X" T MPU_Write_Reg(MPU6050_ADDR , MPU_SAMPLE_RATE_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_SAMPLE_RATE_REG);# g" W, j, i0 u" e* @6 G {& ^; R printf("MPU_SAMPLE_RATE_REG = 0x%x.\n" , data); & x5 h! J- t& q% p2 c6 K & q X; q s: l$ j% N. H# ] data = 0x01; MPU_Write_Reg(MPU6050_ADDR , MPU_PWR_MGMT1_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_PWR_MGMT1_REG);% q0 v! J6 T. }# T printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); data = 0; MPU_Write_Reg(MPU6050_ADDR , MPU_CFG_REG , data);& S6 }/ U9 c9 S- H data = MPU_Read_Reg(MPU6050_ADDR , MPU_CFG_REG); printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); 0 i; P1 {" w9 F& ?0 x # h0 Z# v% ]6 B9 g5 S data = 0x18; S( X: S" n/ H3 _ MPU_Write_Reg(MPU6050_ADDR , MPU_GYRO_CFG_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_GYRO_CFG_REG);. |5 X8 q' v/ u( n8 z6 ] printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); 7 ~1 [* o/ n- w ! _7 v' x1 o; s5 j' Y . \' [6 s+ t1 n data = 0x01; MPU_Write_Reg(MPU6050_ADDR , MPU_INT_EN_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_INT_EN_REG);) |/ L/ R$ G- G7 O- I, A D( i! d 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;) D' O, i' n5 h2 \: X4 @; m/ ? }( N1 o" a8 E/ E9 \! S 初始化需要用作演示动画的img控件:
h% @3 C/ u; l' r% l img_anim = lv_image_create(tile_3);7 E1 d' r2 i9 Q( ^ lv_image_set_src(img_anim , &img_st_logo); lv_obj_align(img_anim , LV_ALIGN_TOP_LEFT , 100 , 100);! }# d! J; Z. o 2 {3 C. `* Z" j9 Q" { 读取MPU6050数据并修改图片位置: , N0 L, g) u3 U) m% F static void my_timer1(lv_timer_t * timer)9 S/ P- }* f7 Z+ s& t0 a1 P; L { 。。。 MPU_Read_Regs(MPU6050_ADDR , ACCEL_XOUT_H , mpu9250_read_data , 2);2 j. D2 s0 P( E* c) u# q w 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];* H7 i4 ]% Z5 J! J0 q* `3 O2 ? L printf("acc_x = %d acc_y = %d %d.\n" , acc_x , acc_y); ( x. ]* p$ C+ E0 c Z; l # {# ^! e1 X5 V, t0 `. ?1 m0 k) G, s acc_x = - acc_x; acc_x_index = acc_x / 100;5 G9 D3 X2 c9 m# e- N2 D if(acc_x_index <= -80)- M- Z. }- G8 D, d acc_x_index = -80;$ H; c7 @0 Y+ N. m' B else if(acc_x_index >= 80) acc_x_index = 80; 2 @% j/ S9 C9 ~5 X" V6 x) h H: i# @ acc_y_index = acc_y / 80; if(acc_y_index <= -195)- `5 n* o0 s3 D% u4 k# T& M 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);. ]! W6 C$ p7 m; r# i O9 k# X X- d 。。。 }/ \8 `( y: x. M, S/ J" ~& d 然后是添加img_btn在第四页(tile_4)并设置按下和释放的图像数据: W( I, X1 f9 F8 O9 m. `9 J
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);4 c% a3 W) r7 P& `; M4 f( P- A* ? lv_obj_align(imgbtn_st , LV_ALIGN_TOP_LEFT , 0 , 0); g- y& v5 i0 v+ Z 演示效果: 8 I6 Y, p: U6 Q K0 R" d& z$ O1 q |
【STM32C5教程】(8)ADC 模拟量数据采集实验
【STM32C5教程】(7)TIM1 互补 PWM 输出实验
【STM32C5教程】(6)定时器 PWM 输出实验
【STM32C5教程】(5)定时器周期中断实验
【STM32C5教程】(4)GPIO 外部中断实验
【STM32C5教程】(3)GPIO 按键输入实验
STM32C542RC开发板PWM呼吸灯及多功能按键实验
NUCLEO-H5E5ZJ 移植 LVGL
NUCLEO-H5E5ZJ 移植 ST7735 SPI LCD 驱动
NUCLEO-H5E5ZJ 以太网(Ethernet)移植记录
微信公众号
手机版