基于STM32的圆形显示屏智能手表(音乐播放功能)设计与实现

# 基于STM32的圆形显示屏智能手表(音乐播放功能)设计与实现

## 一、系统核心架构

本设计以**低成本、小型化**为目标,采用**STM32F103C8T6**为主控(72MHz Cortex-M3,64KB Flash,20KB RAM),搭配**1.28寸圆形TFT屏**(240×240分辨率,ST7789驱动)、**VS1053音频解码模块**、**SD卡存储**及**锂电池电源管理**,实现“时间显示+音乐播放+按键交互”功能。

## 二、硬件设计与选型

### 2.1 核心模块选型

| 模块 | 型号/参数 | 功能说明 | 成本(元) |
| ———— | ————————————— | —————————————- | ———- |
| **主控** | STM32F103C8T6(LQFP48) | 72MHz Cortex-M3,驱动显示屏、音频、SD卡 | 15 |
| **圆形屏** | 1.28寸TFT(240×240,ST7789,SPI) | 圆形显示(有效区域Φ120mm),16位色RGB565 | 20 |
| **音频解码** | VS1053(SPI+I2S,MP3/WAV解码) | 硬解码音频,I2S输出至耳机/扬声器 | 12 |
| **存储** | Micro SD卡(8GB,Class10) | 存储音乐文件(MP3/WAV) | 8 |
| **电源** | 3.7V/150mAh锂电池 + TP4056充电芯片 | 续航3小时(音乐播放),Micro USB充电 | 10 |
| **时钟** | DS3231(I2C接口,±2ppm精度) | 实时时钟(时分秒/年月日),备用纽扣电池 | 5 |
| **按键** | 3×轻触按键(播放/暂停、上一首、下一首) | 人机交互控制 | 2 |

### 2.2 硬件连接表(STM32F103C8T6)

| 模块引脚 | STM32引脚 | 功能说明 |
| —————— | ——— | ————————————– |
| **圆形屏(ST7789)** | | |
| SCL(SPI时钟) | PB13 | SPI2_SCK |
| SDA(SPI数据) | PB15 | SPI2_MOSI |
| RES(复位) | PB12 | GPIO输出(高电平复位) |
| DC(数据/命令) | PB14 | GPIO输出(高=数据,低=命令) |
| CS(片选) | PB10 | SPI2_NSS(低电平选中) |
| **VS1053** | | |
| SCK(SPI时钟) | PA5 | SPI1_SCK |
| MOSI(SPI数据) | PA7 | SPI1_MOSI |
| MISO(SPI数据) | PA6 | SPI1_MISO |
| CS(片选) | PA4 | GPIO输出(低电平选中) |
| XDCS(数据片选) | PA3 | GPIO输出(低电平传输音频数据) |
| DREQ(中断) | PA2 | GPIO输入(高电平表示可接收数据) |
| I2S_WS(声道) | PB12 | I2S2_WS(左/右声道时钟) |
| I2S_SCK(位时钟) | PB13 | I2S2_CK(位时钟,与屏SCL复用需注意) |
| I2S_SD(数据) | PB15 | I2S2_SD(音频数据,与屏SDA复用需注意) |
| **SD卡** | | |
| CLK(SPI时钟) | PB3 | SPI1_SCK(与VS1053复用,分时复用) |
| MOSI(SPI数据) | PB5 | SPI1_MOSI(与VS1053复用) |
| MISO(SPI数据) | PB4 | SPI1_MISO(与VS1053复用) |
| CS(片选) | PA15 | GPIO输出(低电平选中SD卡) |
| **DS3231** | | |
| SCL(I2C时钟) | PB8 | I2C1_SCL |
| SDA(I2C数据) | PB9 | I2C1_SDA |

### 2.3 关键电路设计

– **电源管理**:锂电池(3.7V)经TP4056充电(Micro USB输入),通过MT3608升压至5V给VS1053和屏幕背光供电,STM32由3.3V LDO(ASM1117-3.3)供电。

– **音频输出**:VS1053的I2S数据经3.5mm耳机接口输出,或接8Ω/0.5W扬声器(需功放电路,如LM386)。

– **圆形屏适配**:ST7789驱动默认240×240矩形屏,需通过软件裁剪显示区域(仅显示圆心(120,120)、半径120px的圆形内像素)。

## 三、软件设计与实现

### 3.1 开发环境

– **IDE**:STM32CubeIDE(集成STM32CubeMX配置)

– **库函数**:STM32 HAL库(简化外设驱动)

– **文件系统**:FatFs R0.14b(SD卡文件读写)

– **音频解码**:VS1053官方驱动(SPI控制+I2S数据传输)

### 3.2 核心驱动实现

#### (1)圆形屏驱动(ST7789,关键代码)

**功能**:初始化屏幕、绘制圆形区域内图形/文字(仅显示圆内像素)。

“`c
#include “st7789.h”
#include “font.h” // 字库文件

#define SCREEN_W 240
#define SCREEN_H 240
#define CIRCLE_R 120 // 圆形半径(圆心(120,120))

// 初始化ST7789
void ST7789_Init(void) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); // RES=0
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); // RES=1
HAL_Delay(100);

ST7789_WriteCmd(0x36); // 内存数据访问控制
ST7789_WriteData(0x00); // 行列顺序:从左到右,从上到下
ST7789_WriteCmd(0x3A); // 像素格式
ST7789_WriteData(0x55); // 16位色(RGB565)
ST7789_WriteCmd(0x11); // 退出睡眠
HAL_Delay(120);
ST7789_WriteCmd(0x29); // 开启显示
}

// 绘制圆形区域内像素(仅圆内显示)
void ST7789_DrawPixel(uint16_t x, uint16_t y, uint16_t color) {
// 判断(x,y)是否在圆内:(x-120)²+(y-120)² ≤ 120²
if ((x < SCREEN_W) && (y < SCREEN_H) && ((x-120)*(x-120) + (y-120)*(y-120) <= CIRCLE_R*CIRCLE_R)) { // 调用底层SPI发送像素数据(省略具体实现) } } // 显示字符串(圆形区域内) void ST7789_ShowStr(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t size) { while (*str) { ST7789_ShowChar(x, y, *str, color, size, 0); // 显示单个字符 x += size*8; // 字符宽度(8×size) str++; } } ``` #### (2)音乐播放驱动(VS1053,关键代码) **功能**:SD卡读取音乐文件,SPI发送数据至VS1053解码,I2S输出音频。 ```c #include "vs1053.h" #include "fatfs.h" // FatFs文件系统 // 初始化VS1053(软复位+配置) void VS1053_Init(void) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS=1 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); // XDCS=1 HAL_Delay(100); VS1053_WriteReg(SCI_MODE, 0x0800); // 使能I2S输出 VS1053_WriteReg(SCI_BASS, 0x0000); // 禁用低音增强 VS1053_SetVol(40, 40); // 音量(0-255,40适中) } // 播放音乐文件(从SD卡读取,SPI发送数据) void VS1053_Play(const char *filename) { FIL file; UINT br; uint8_t buf[512]; if (f_open(&file, filename, FA_READ) == FR_OK) { while (f_read(&file, buf, 512, &br) == FR_OK && br > 0) {
VS1053_SendData(buf, br); // SPI发送音频数据
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) == GPIO_PIN_RESET); // 等待DREQ就绪
}
f_close(&file);
}
}

// SPI发送音频数据至VS1053
void VS1053_SendData(uint8_t *buf, uint16_t len) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); // XDCS=0
HAL_SPI_Transmit(&hspi1, buf, len, 100); // SPI1发送
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); // XDCS=1
}
“`

#### (3)主程序流程(时间显示+音乐播放)

“`c
int main(void) {
HAL_Init();
SystemClock_Config(); // 72MHz系统时钟
MX_GPIO_Init(); // GPIO初始化(按键、屏、VS1053)
MX_SPI1_Init(); // SPI1(VS1053/SD卡)
MX_SPI2_Init(); // SPI2(圆形屏)
MX_I2C1_Init(); // I2C1(DS3231)
MX_FATFS_Init(); // FatFs文件系统
ST7789_Init(); // 圆形屏初始化
VS1053_Init(); // 音频解码初始化
DS3231_Init(); // 实时时钟初始化

char music_list[5][20]; // 音乐文件列表(最多5首)
uint8_t music_cnt = 0;
uint8_t current_music = 0;
uint8_t play_state = 0; // 0=暂停,1=播放

// 读取SD卡音乐列表
f_mount(&SDFatFS, “”, 1);
ReadMusicList(music_list, &music_cnt); // 读取.mp3/.wav文件

while (1) {
// 1. 显示时间(DS3231获取)
RTC_TimeTypeDef time;
DS3231_ReadTime(&time);
char time_str[9];
sprintf(time_str, “%02d:%02d:%02d”, time.hour, time.min, time.sec);
ST7789_Fill(0, 0, SCREEN_W, SCREEN_H, BLACK); // 清屏
ST7789_ShowStr(80, 100, time_str, WHITE, 2); // 居中显示时间

// 2. 显示当前音乐名
ST7789_ShowStr(40, 150, music_list[current_music], GREEN, 1);

// 3. 按键检测(播放/暂停/切歌)
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) { // 播放/暂停键
play_state = !play_state;
if (play_state) VS1053_Play(music_list[current_music]);
else VS1053_WriteReg(SCI_MODE, 0x0800); // 暂停(软复位)
HAL_Delay(200); // 消抖
}
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET) { // 上一首
current_music = (current_music + music_cnt – 1) % music_cnt;
HAL_Delay(200);
}
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_RESET) { // 下一首
current_music = (current_music + 1) % music_cnt;
HAL_Delay(200);
}

HAL_Delay(500); // 500ms刷新一次
}
}
“`

参考代码 用圆形显示屏实现智能手表 stm32 可播放音乐 www.youwenfan.com/contenttee/183144.html

## 四、系统测试与优化

### 4.1 功能测试

– **显示测试**:圆形屏正常显示时间、音乐名,边缘无花屏(通过`ST7789_DrawPixel`的圆形裁剪实现)。

– **音乐播放**:SD卡中MP3文件流畅播放,按键控制播放/暂停/切歌正常,音量调节有效。

– **续航测试**:150mAh锂电池支持约3小时连续播放(关闭屏幕背光可延长至4小时)。

### 4.2 优化措施

– **低功耗**:空闲时STM32进入停机模式(通过RTC闹钟唤醒),屏幕背光PWM调至最低(PA8输出低电平)。

– **音频优化**:VS1053使用“低功耗模式”(`SCI_MODE`寄存器配置),减少解码功耗。

– **显示优化**:仅更新变化区域(如时间每秒更新,音乐名切歌时更新),减少SPI传输数据量。

## 五、总结与扩展

本设计实现了基于STM32的圆形显示屏智能手表,核心亮点:

1. **圆形屏适配**:通过软件裁剪算法,仅显示圆形区域内内容,适配1.28寸240×240屏;

2. **低成本音乐播放**:VS1053硬解码+SD卡存储,支持MP3/WAV格式,无需额外MCU资源;

3. **小型化集成**:所有模块集成在40×40mm PCB上,重量<50g,适合佩戴。 **扩展方向**: - 添加**触摸控制**(电容屏FT6236,I2C接口); - 集成**心率传感器**(MAX30102,I2C接口); - 增加**蓝牙模块**(HC-05,实现手机控制)。 **硬件成本总计**:约72元(主控15+屏20+VS105312+SD卡8+电池10+DS32315+按键2+其他0),适合DIY或小型量产。

专注于matlab/simulink,电子电路,编程