你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32F429I-DISC1的体感控制LCD小球

[复制链接]
A0dy 发布时间:2026-7-1 17:29

一、硬件介绍

本次开发使用的是STM32F429I-DISC1开发板,是基于STM32F429ZIT6U的MCU,具有Arm Cortex-M4内核,配备2.4英寸QVGA TFT LCD、64-Mbit SDRAM、ST-MEMS陀螺仪(I3G4250D)等。

陀螺仪MEMS(ST-MEMS I3G4250D)

I3G4250D 是一款低功耗、三轴角速率传感器;I3G4250D 具有 ±245 / ±500 / ±2000 dps 的满量程,并且能够以用户可选择的带宽测量速率。STM32F429ZIT6 通过SPI_5接口控制此运动传感器。

image-20250505150548985.png

主要特性:

输出类型 I2C / SPI
特性 可调带宽,可选量程,温度传感器
封装/外壳 16-TFLGA
工作温度 -40°C ~ 85°C(TA)
X(俯仰),Y(偏转),Z(横滚)
电流-供电 6.1mA
范围°/s ±245,500,2000
灵敏度(mV/°/s) -
带宽 -
电压-供电 2.4V ~ 3.6V
灵敏度(LSB/(°/s)) 8.75 ~ 70
类型 数字
数据 • 16-bit 原始数据 <br />**

• 8-bit 温度数据** |

SPI通讯时序图

image-20250505153844885.png

原理图:

若要选择 SPI接口,CS线必须低电平

INT2:数据就绪 / FIFO中断

INT1:可编程中断

CS:SPI / I2C模式选择

0: SPI 1: I2C

传感器 -> MCU硬件连接:

SPI5_SCK -> PF7

SPI5_MISO -> PF8

SPI5_MOSI -> PF9

MEMS_CS -> PC1

MEMS_INT2 -> PA2 (可配置)

MEMS_INT1 -> PA1 (可配置)

image-20250505165053776.png

2.4寸TFT_LCD

2.4寸TFT LCD模块, 240x320 RGB全彩TFT液晶模块,内建ILI9341控制器, 工作电源电压:2.4V至3.3V;

RGB接口的屏幕是通过MCU不断发送显示数据到屏幕,逐行扫描显示。

VSYNC: 帧同步信号,表示扫描1帧的开始,一帧也就是LCD显示的一个画面。

HSYNC: 行同步信号,表示扫描1行的开始。

VDEN:数据使能信号。

IM[0..3] = 0110 --> 4-wire 8-bit serial I, SDA:In/Out

4 线 8 位串行接口(SDA 双向)

信号名称 说明
R[7:0] 红色数据
G[7:0] 绿色数据
B[7:0] 蓝色数据
DOTCLK 像素同步时钟信号
HSYNC 水平同步信号
VSYNC 垂直同步信号
ENABLE 数据使能信号

image-20250516164745175.png

原理图:

image-20250515233237296.png

image-20250515234032614.png

image-20250516182016757.png

二、功能实现思想

实现效果:根据移动开发板的方向以及速度,小球同样以相应的速度向对应的方位移动;

三轴传感器

1、配置I3G4250D传感器,将其通过SPI与STM32F429ZIT6U进行通讯,用于获取传感器数据;

2、移动开发板时,传感器获取此时的角度信息,将数据保存用于小球位置控制;

LCD屏幕

1、配置LCD屏幕初始化,将其通过LTDC驱动;

2、在LCD屏幕上显示小球(初始于中间位置);

3、将陀螺仪获取的数据与小球的位置进行绑定;

image-20250517223635008.png

image-20250628104750316.png

三、功能实现

三轴传感器配置

1、配置I3G4250D传感器相关功能;

未配置INT1 / INT2引脚(若有需要可自行配置)

image-20250515213932349.png

image-20250515220611621.png

image-20250515220939311.png

2、配置串口相关功能;

image-20250505181203623.png

LCD屏幕配置

1、LTDC 配置

image.png

image-20250517224253247.png

image-20250517224347474.png

需按原理图重新复用相关引脚

image-20250516184223572.png

2、GPIO 配置

配置相关LCD IO口;

image-20250517224650680.png

3、时钟树 配置

image-20250517224828417.png

代码编写

新建LCD文件夹用于存储相关LCD驱动代码;

相关BSP

image-20250517224958242.png

1、陀螺仪相关代码

i3g4250d_read_data_polling.c 在原来基础上,新增以下代码;

stmdev_ctx_t dev_ctx;

void I3G4250D_Init(void){
  dev_ctx.write_reg = platform_write;
  dev_ctx.read_reg = platform_read;
  dev_ctx.handle = &SENSOR_BUS;
  platform_init();
  platform_delay(BOOT_TIME);
  i3g4250d_device_id_get(&dev_ctx, &whoamI);
  if (whoamI != I3G4250D_ID)
      printf("Mems_Init_Error\r\n");
  else 
      printf("Mems_Init_Sucess\r\n");
  
  i3g4250d_filter_path_set(&dev_ctx, I3G4250D_LPF1_HP_ON_OUT);
  i3g4250d_hp_bandwidth_set(&dev_ctx, I3G4250D_HP_LEVEL_3);
  
  i3g4250d_data_rate_set(&dev_ctx, I3G4250D_ODR_100Hz);     //10ms

}


//获取 X / Y角速度数据
void Get_I3G4250D_Data(int16_t* X,int16_t* Y){
    uint8_t reg; 
    i3g4250d_flag_data_ready_get(&dev_ctx, ®);
    if (reg) {
      memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));
      i3g4250d_angular_rate_raw_get(&dev_ctx, data_raw_angular_rate);
        
      angular_rate_mdps[0] = i3g4250d_from_fs245dps_to_mdps(data_raw_angular_rate[0]) / 1000.0f;
      angular_rate_mdps[1] = i3g4250d_from_fs245dps_to_mdps(data_raw_angular_rate[1]) / 1000.0f;
  
      *X = (int)angular_rate_mdps[1];  
      *Y = (int)angular_rate_mdps[0];
    }
}

2、LCD相关代码

1.打开…\STM32CubeF4\Drivers\BSP\Components\ili9341.c;

在此基础上重新定义以下相关接口函数;

extern SPI_HandleTypeDef hspi5;  


void LCD_IO_Init(void){

    LCD_Delay(100);

}

//写数据
void LCD_IO_WriteData(uint16_t RegValue){
    
    HAL_GPIO_WritePin(LCD_WRX_GPIO_Port, LCD_WRX_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);

    HAL_SPI_Transmit(&hspi5,&RegValue,1,HAL_MAX_DELAY);
    HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);

}


//写命令
void LCD_IO_WriteReg(uint8_t Reg){

    HAL_GPIO_WritePin(LCD_WRX_GPIO_Port, LCD_WRX_Pin, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);

    HAL_SPI_Transmit(&hspi5,&Reg,1,HAL_MAX_DELAY);
    HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);

}

//读数据
uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize){

    HAL_GPIO_WritePin(LCD_WRX_GPIO_Port, LCD_WRX_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);

    HAL_SPI_Receive(&hspi5,&RegValue,ReadSize,HAL_MAX_DELAY);
    HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);

}
  
void LCD_Delay(uint32_t delay) {
    HAL_Delay(delay);  // 直接使用HAL库延时
}

2.创建小球

…\LCD\pic 存储要实现的小球图像,并将其转换为C数组 Ball[ ];

与ltdc.c中的 pLayerCfg.FBStartAdress = (uint32_t)&Ball; 与之相对应;

RGB565 【Layer 0 - Pixel Format】

const unsigned char Ball[4616] = { 0X00,0X10,0X30,0X00,0X30,0X00,0X01,0X1B, …. }

3、main.c 主要代码

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

 __IO uint32_t ReloadFlag = 0;


static int16_t Xpos0 = 96;
static int16_t Ypos0 = 136;

static int16_t X_Angle_Rate = 0;
static int16_t Y_Angle_Rate = 0;

static int16_t Width;
static int16_t Height;

#define Width_Max   192
#define Width_Min   0

#define Height_Max   272
#define Height_Min   0

//计算当前位置
static void PicturesPosition(int16_t* x0, int16_t* y0, int16_t X_Angle_Rate, int16_t Y_Angle_Rate)
{
  
  //计算当前位置
  *x0 = Xpos0 - X_Angle_Rate;
  *y0 = Ypos0 - Y_Angle_Rate;

}


static void Ball_Move(void)
{
    
  //获取角速度
    Get_I3G4250D_Data(&X_Angle_Rate,&Y_Angle_Rate);

    if(X_Angle_Rate > 50)   X_Angle_Rate = 50;
       else if (X_Angle_Rate < -50)   X_Angle_Rate = -50;

    
    if(Y_Angle_Rate > 50)   Y_Angle_Rate = 50;
       else if (Y_Angle_Rate < -50)   Y_Angle_Rate = -50;

        //计算当前位置    
    PicturesPosition(&Xpos0,&Ypos0,X_Angle_Rate,Y_Angle_Rate);

    Width = Xpos0;
    Height = Ypos0;

    if(Width > Width_Max)   Xpos0 = Width_Max; 
        else if(Width < Width_Min)     Xpos0 = Width_Min;    


    if(Height > Height_Max)   Ypos0 = Height_Max; 
        else if(Height < Height_Min)     Ypos0 = Height_Min;    

    HAL_LTDC_SetWindowPosition_NoReload(&hltdc, Xpos0, Ypos0, 0);
    
    ReloadFlag = 0;
    HAL_LTDC_Reload(&hltdc,LTDC_SRCR_VBR);  //更新

    while(ReloadFlag == 0);//等待完成
    
    HAL_Delay(20);
}


/* Reload Event callback */
void HAL_LTDC_ReloadEventCallback(LTDC_HandleTypeDef *hltdc)
{
  ReloadFlag = 1;
}

/* USER CODE END 0 */

int main(void)
{
    ...
  
   I3G4250D_Init();  
   ili9341_Init();
    
  while (1)
  {
    Ball_Move();
  }
  /* USER CODE END 3 */
}

四、实现现象

根据移动开发板的方向以及速度,小球同样以相应的速度向对应的方位移动;

球.gif

收藏 评论0 发布时间:2026-7-1 17:29

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版