|
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();% c! W! ?: y' D 9 j2 y: P* q! F5 N: ` #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); 1 M# r- Q0 t! Q: S #define FAKE_I2C_SDA_PD12_GPIO_PORT GPIOD& h( A- [ i3 L9 _9 |9 m #define FAKE_I2C_SDA_PD12_GPIO_PIN GPIO_PIN_12 #define FAKE_I2C_SDA_PD12_GPIO_CLK_ENABLE __HAL_RCC_GPIOD_CLK_ENABLE(); ( N( @ d) ?; |/ N+ B #define FAKE_I2C_SDA_PD12_H HAL_GPIO_WritePin(FAKE_I2C_SDA_PD12_GPIO_PORT , FAKE_I2C_SDA_PD12_GPIO_PIN , GPIO_PIN_SET);$ I6 ~+ ^5 _# @2 \# n* S1 ]" c #define FAKE_I2C_SDA_PD12_L HAL_GPIO_WritePin(FAKE_I2C_SDA_PD12_GPIO_PORT , FAKE_I2C_SDA_PD12_GPIO_PIN , GPIO_PIN_RESET);" p: C U% d2 a I0 I% o / c1 R8 e9 Q4 y( I! D1 t. K+ R2 p 5 a H7 T6 e0 Y$ ^, k! v( m! _3 n #define IIC_READ_SDA_PD12 HAL_GPIO_ReadPin(FAKE_I2C_SDA_PD12_GPIO_PORT , FAKE_I2C_SDA_PD12_GPIO_PIN)0 G' q# D8 K% \( G. O & h- T4 T3 H8 x" k# i+ g 0 F% U; i! N7 x; ?; r; K 具体模拟I2C读写方式和BME680模块基本一致,只修改MPU6050初始化函数和倾角数据读写函数即可: ) S+ s, F" k; T9 D$ G2 @' b o/ ` uint8_t MPU6050_Init()! U d" h3 u; C! x: w { W" o3 d6 U: [9 Y8 ?8 K H uint8_t data; uint8_t mpu9250_id;1 x* J6 t& w5 Y1 W* C) g! r9 K data = 0x07; MPU_Write_Reg(MPU6050_ADDR , MPU_SAMPLE_RATE_REG , data); I v2 N' R5 l- A* u$ V* H2 f 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);; E: {+ G2 s# b$ F2 h printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); ' T7 S6 B0 N, x" A3 M( _ 9 v H1 u" C- q" O# B data = 0; MPU_Write_Reg(MPU6050_ADDR , MPU_CFG_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_CFG_REG);. n' N) m4 r: a6 j+ r0 \ 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);) K9 X, o1 J. K2 K3 w printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); 9 \; ^7 f3 h4 O data = 0x01;4 c5 B+ i* j1 m0 ~; j2 v MPU_Write_Reg(MPU6050_ADDR , MPU_INT_EN_REG , data);3 q9 r+ B# P8 H( t; k data = MPU_Read_Reg(MPU6050_ADDR , MPU_INT_EN_REG); printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); % M/ V3 @/ n! I7 Y8 J data = 0;. c0 _5 J# _% ~' E+ Z MPU_Write_Reg(MPU6050_ADDR , MPU_PWR_MGMT2_REG , data); data = MPU_Read_Reg(MPU6050_ADDR , MPU_PWR_MGMT2_REG);. E( S* O4 W5 B8 O7 o$ ` printf("MPU_PWR_MGMT1_REG = 0x%x.\n" , data); e+ y4 o+ o& ]$ w return mpu9250_id; } ; l: W: E- W8 P4 m* I% d9 O& V 初始化需要用作演示动画的img控件:
6 C4 `' [; a4 E4 ~0 W img_anim = lv_image_create(tile_3);$ x" D! g# x) k. P1 S lv_image_set_src(img_anim , &img_st_logo);9 d! T4 A6 J1 [) @5 k2 Q5 @ lv_obj_align(img_anim , LV_ALIGN_TOP_LEFT , 100 , 100); o% }+ f- m% g( N: q 4 b* Z& @ r, a+ a 读取MPU6050数据并修改图片位置: 4 |. Y1 a" F/ l v" r1 p1 O' ^ static void my_timer1(lv_timer_t * timer) { 。。。& l) ~/ j- k. I1 M8 l1 [& [6 N MPU_Read_Regs(MPU6050_ADDR , ACCEL_XOUT_H , mpu9250_read_data , 2); acc_x = mpu9250_read_data[0] << 8 | mpu9250_read_data[1];2 g- s; x- Y) p0 W3 ^- d. t MPU_Read_Regs(MPU6050_ADDR , ACCEL_YOUT_H , mpu9250_read_data + 2 , 2);+ U$ @, G+ F( I$ L4 _5 z* Z- d. A acc_y = mpu9250_read_data[2] << 8 | mpu9250_read_data[3];) y5 s7 {" G- e0 L) _( C printf("acc_x = %d acc_y = %d %d.\n" , acc_x , acc_y);* P4 ~ Q8 A/ f h ; ~2 _# t$ l: q; t* o/ t0 B . K) e+ h) o2 u acc_x = - acc_x;& o. a0 t% ^0 K0 b/ H% w+ q; f, D4 V acc_x_index = acc_x / 100; if(acc_x_index <= -80)& Z/ v ?; }' G6 `. |' e acc_x_index = -80; else if(acc_x_index >= 80); Y: e2 O# x' W7 R4 x acc_x_index = 80;1 E" t* I" J: F* Y+ c 6 m( V+ g8 U0 \ acc_y_index = acc_y / 80; if(acc_y_index <= -195)8 \% }. a" G0 {# W1 i% ` acc_y_index = -195;0 _+ L# V: N( P T else if(acc_y_index >= 195)* [: j' m% M. ]- J$ M acc_y_index = 195; - W6 W7 Y6 |* T: k1 u3 o lv_obj_align(img_anim , LV_ALIGN_CENTER , acc_x_index , acc_y_index);" e1 U- E4 U; p* o# t# {% _7 I 。。。# i% z2 ~( K) G5 Q( b) I5 ]. r }( v, T/ k9 C' Z( T3 a+ | & _+ @& B/ D6 c" F+ S, J$ ` 然后是添加img_btn在第四页(tile_4)并设置按下和释放的图像数据:
imgbtn_st = lv_imagebutton_create(tile_4);5 {/ [' E/ I1 U" \0 u4 }' O% m7 |, C lv_imagebutton_set_src(imgbtn_st , LV_IMAGEBUTTON_STATE_RELEASED , NULL , &img_st_poster1 , NULL);' P U" r' d" _- i; G8 \! b lv_imagebutton_set_src(imgbtn_st , LV_IMAGEBUTTON_STATE_PRESSED , NULL , &img_st_poster2 , NULL);5 \& x: q+ @' z7 q; l$ q" [: g4 f lv_obj_align(imgbtn_st , LV_ALIGN_TOP_LEFT , 0 , 0);/ Z# p" [$ i4 C' t$ S) R4 p3 G 3 i5 F: Z$ Z7 U- ~) L 9 I" b: u- N9 J. ~* c 演示效果: 6 h0 F7 z4 i& P% o- E# N6 }3 w9 l |
STM32C543RC开发板Stop、Sleep和standby模式测试
【STM32C5教程】(10)LPUART DMA 通信实验
【STM32C5教程】(9)DAC 模拟量信号输出实验
【STM32C5教程】(8)ADC 模拟量数据采集实验
【STM32C5教程】(7)TIM1 互补 PWM 输出实验
【STM32C5教程】(6)定时器 PWM 输出实验
【STM32C5教程】(5)定时器周期中断实验
【STM32C5教程】(4)GPIO 外部中断实验
【STM32C5教程】(3)GPIO 按键输入实验
STM32C542RC开发板PWM呼吸灯及多功能按键实验
微信公众号
手机版