1 PWM

在STM32里面,PWM也算是TIMER的一种。所以要在TIM里面配置,我用的TIM4。控制的SG90舵机。此时要确保APB1的时钟是84MHz。

Counter Settings:
Prescaler (PSC): 84 - 1 (计数频率变为 1MHz)
Counter Mode: Up (向上计数)
Counter Period (ARR): 20000 - 1 (周期变为 20ms)
Internal Clock Division: No Division
auto-reload preload: Enable (建议开启,防止修改占空比时产生毛刺)
PWM Generation Channel 1:
Mode: PWM mode 1
Pulse (CCR1): 1500 (这是初始位置,1.5ms 对应 90 度,你也可以填 500 作为 0 度起始)
Fast Mode: Disable
CH Polarity: High (高电平代表有效脉宽)

配置如下:

接线如下:

  • 棕色:GND

  • 红色:5V

  • 橙色:信号线(接 PD12)

代码:

//1. 启动 TIM4 的 PWM 输出
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);

while (1)
{
    // 2. 转到 0 度 (脉宽 0.5ms,对应计数值 500)
    __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, 500);
    HAL_Delay(1000); // 等待 1 秒让舵机到位

    // 3. 转到 90 度 (脉宽 1.5ms,对应计数值 1500)
    __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, 1500);
    HAL_Delay(1000);

    // 4. 转到 180 度 (脉宽 2.5ms,对应计数值 2500)
    __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, 2500);
    HAL_Delay(1000);
    
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
}

运行之后就可以看到舵机在转动了。

2 SPI

关于SPI本身,也可以参考我之前的文章:https://blog.csdn.net/fanged/article/details/140876269

1 接线和MX设置

硬件引脚:

屏幕引脚 STM32F407 引脚 说明
VCC 3.3V 电源
GND GND
SCL (CLK) PA5 (SPI1_SCK) 时钟信号
SDA (MOSI) PA7 (SPI1_MOSI) 数据信号
RES (RST) PB0 复位 (GPIO 输出)
DC (RS) PB1 数据/命令切换 (GPIO 输出)
BLK (LEDA) PB2 背光控制 (可选 PWM 或 GPIO)

这里有个注意的,CS必须接地拉低。之前就是没接地,折腾半天。

CubeMX配置:

此外还开了PB0,PB1,PB2作为控制口。还打开了DMA。

2 代码

7789初始化:

void ST7789_Init(void) {
	// 1. 硬件复位
	    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
	    HAL_Delay(100);
	    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
	    HAL_Delay(120);

	    // 2. 软件复位与退出睡眠
	    LCD_WR_REG(0x01); // Software Reset
	    HAL_Delay(120);
	    LCD_WR_REG(0x11); // Sleep Out
	    HAL_Delay(120);

	    // 3. 设置像素格式 (RGB565)
	    LCD_WR_REG(0x3A);
	    LCD_WR_DATA8(0x05);

	    // 4. 设置扫描方向 (可以换成 0x00, 0xC0, 0x70 等尝试不同方向)
	    LCD_WR_REG(0x36);
	    LCD_WR_DATA8(0x00);

	    // 5. 开启显示反相 (ST7789 必设,否则颜色是反的)
	    LCD_WR_REG(0x21);

	    // 6. 开启显示
	    LCD_WR_REG(0x29);
	    HAL_Delay(20);

	    // 7. 点亮背光
	    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
}

辅助函数:

// 发送字节命令
void LCD_WR_REG(uint8_t dat) {
    LCD_DC_Clr(); // 命令模式
    HAL_SPI_Transmit(&hspi1, &dat, 1, 100);
}

// 发送字节数据
void LCD_WR_DATA8(uint8_t dat) {
    LCD_DC_Set(); // 数据模式
    HAL_SPI_Transmit(&hspi1, &dat, 1, 100);
}

// 发送半字数据(用于颜色,ST7789通常是RGB565,即16位)
void LCD_WR_DATA16(uint16_t dat) {
    uint8_t data[] = {dat >> 8, dat & 0xFF};
    LCD_DC_Set();
    HAL_SPI_Transmit(&hspi1, data, 2, 100);
}

// 设置光标窗口
void LCD_Address_Set(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
    LCD_WR_REG(0x2a); // 列地址设置
    LCD_WR_DATA16(x1);
    LCD_WR_DATA16(x2);
    LCD_WR_REG(0x2b); // 行地址设置
    LCD_WR_DATA16(y1);
    LCD_WR_DATA16(y2);
    LCD_WR_REG(0x2c); // 准备写入显存
}

// 填充纯色
void LCD_Fill(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) {
    LCD_Address_Set(x1, y1, x2, y2);
    uint32_t size = (x2 - x1 + 1) * (y2 - y1 + 1);
    for (uint32_t i = 0; i < size; i++) {
        LCD_WR_DATA16(color);
    }
}

在main里面增加这两行。

  ST7789_Init();
  // 填充全屏为红色 (RGB565 中红色为 0xF800)
  // 假设屏幕分辨率为 240x240
  LCD_Fill(0, 0, 239, 239, 0xF800);

好了,这样就可以显示纯红了。

3 ADC

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐