当前位置: 首页 > news >正文

STM32的电子钟功能实现

一、系统架构设计

1.1 硬件组成框图

graph TD A[STM32F103C8T6] --> B[OLED0.96] A --> C[按键矩阵] A --> D[蜂鸣器] B --> I2C总线 C --> EXTI中断

1.2 核心模块划分

  • 时间管理:SysTick定时器中断(1ms精度)
  • 显示驱动:SSD1306 OLED中文显示
  • 用户交互:4x4矩阵键盘+外部中断
  • 电源管理:低功耗模式(待机模式)

二、硬件配置实现

2.1 时钟配置(SystemClock_Config)

void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;  // 72MHzHAL_RCC_OscConfig(&RCC_OscInitStruct);RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;HAL_RCC_ClockConfig(&RCC_ClkInit, FLASH_LATENCY_2);
}

2.2 OLED驱动配置(I2C接口)

// SSD1306初始化
void SSD1306_Init(void)
{SSD1306_WriteCommand(0xAE); // 关闭显示SSD1306_WriteCommand(0x20); // 设置内存地址模式SSD1306_WriteCommand(0x00); // 水平地址模式SSD1306_WriteCommand(0xB0); // 设置页起始地址SSD1306_WriteCommand(0xC8); // 设置COM输出扫描方向SSD1306_WriteCommand(0x00); // 设置低位列地址SSD1306_WriteCommand(0x10); // 设置高位列地址SSD1306_WriteCommand(0x40); // 设置起始行地址SSD1306_WriteCommand(0x81); // 设置对比度SSD1306_WriteCommand(0xFF); // 对比度最大值SSD1306_WriteCommand(0xA1); // 设置段重定向SSD1306_WriteCommand(0xA6); // 正常显示SSD1306_WriteCommand(0xA8); // 设置多路复用率SSD1306_WriteCommand(0x3F); // 1/64 dutySSD1306_WriteCommand(0xD3); // 设置显示偏移SSD1306_WriteCommand(0x00); // 无偏移SSD1306_WriteCommand(0xD5); // 设置显示时钟分频SSD1306_WriteCommand(0x80); // 建议比值SSD1306_WriteCommand(0xD9); // 设置预充电周期SSD1306_WriteCommand(0xF1); // 预充电周期值SSD1306_WriteCommand(0xDA); // 设置COM硬件引脚配置SSD1306_WriteCommand(0x12); // 配置值SSD1306_WriteCommand(0xDB); // 设置VCOMHSSD1306_WriteCommand(0x40); // VCOMH电压值SSD1306_WriteCommand(0x8D); // 设置电荷泵SSD1306_WriteCommand(0x14); // 启用电荷泵SSD1306_WriteCommand(0xAF); // 开启显示
}

三、时间管理系统

3.1 SysTick中断服务程序

volatile uint32_t ms_ticks = 0;void SysTick_Handler(void)
{HAL_IncTick();ms_ticks++;
}// 时间结构体
typedef struct {uint8_t hours;uint8_t minutes;uint8_t seconds;
} TimeTypeDef;TimeTypeDef current_time = {0, 0, 0};// 时间更新函数
void Update_Time(void)
{if(ms_ticks >= 1000) {ms_ticks = 0;current_time.seconds++;if(current_time.seconds >= 60) {current_time.seconds = 0;current_time.minutes++;if(current_time.minutes >= 60) {current_time.minutes = 0;current_time.hours++;if(current_time.hours >= 24) {current_time.hours = 0;}}}}
}

四、OLED中文显示实现

4.1 GB2312字库加载

// 定义字库数组(示例:0x00-0x0F为数字和字母)
const uint8_t Font_GB2312[] = {0x00, 0x7E, 0x11, 0x11, 0x11, 0x7E, // 00x38, 0x44, 0x44, 0x44, 0x38, 0x00, // 1// ... 其他字符数据
};// 显示字符串函数
void OLED_ShowString(uint8_t x, uint8_t y, char* str)
{while(*str) {OLED_DisplayChar(x, y, *str++);x += 8;}
}// 显示中文字符(需扩展字库)
void OLED_DisplayChinese(uint8_t x, uint8_t y, uint16_t code)
{uint8_t page, col;for(page=0; page<8; page++) {OLED_SetCursor(x, y+page);OLED_WriteData(Font_GB2312[code*16 + page]);}
}

五、按键交互系统

5.1 矩阵键盘扫描

#define KEY_MATRIX_ROWS 4
#define KEY_MATRIX_COLS 4GPIO_TypeDef* row_ports[4] = {GPIOA, GPIOA, GPIOA, GPIOA};
uint16_t row_pins[4] = {GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3};GPIO_TypeDef* col_ports[4] = {GPIOB, GPIOB, GPIOB, GPIOB};
uint16_t col_pins[4] = {GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3};// 扫描函数
char Matrix_Key_Scan(void)
{for(uint8_t col=0; col<4; col++) {// 拉低当前列HAL_GPIO_WritePin(col_ports[col], col_pins[col], GPIO_PIN_RESET);for(uint8_t row=0; row<4; row++) {if(HAL_GPIO_ReadPin(row_ports[row], row_pins[row]) == GPIO_PIN_RESET) {while(HAL_GPIO_ReadPin(row_ports[row], row_pins[row]) == GPIO_PIN_RESET); // 消抖return (col<<4) | row; // 返回键值}}HAL_GPIO_WritePin(col_ports[col], col_pins[col], GPIO_PIN_SET);}return 0xFF; // 无按键
}

5.2 外部中断配置

// EXTI回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin == KEY_ADJUST_PIN) {// 进入时间调整模式time_adjust_mode = 1;adjust_counter = 0;}
}

六、主程序流程

int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init();SSD1306_Init();// 初始化时间current_time.hours = 12;current_time.minutes = 0;current_time.seconds = 0;while(1){// 时间更新Update_Time();// 显示时间OLED_Clear();OLED_ShowString(0,0, "Time:");OLED_DisplayString(32,0, "HH:MM:SS");OLED_DisplayString(0,2, "Current:");OLED_DisplayString(32,2, "XX:XX:XX");// 按键处理char key = Matrix_Key_Scan();if(key != 0xFF) {switch(key) {case KEY_MODE:   // 模式切换time_adjust_mode ^= 1;break;case KEY_UP:     // 增加时间Adjust_Time(1);break;case KEY_CONFIRM: // 确认设置time_adjust_mode = 0;break;}}}
}

参考代码 STM32电子钟功能 www.youwenfan.com/contentcnh/56377.html

七、扩展功能实现

8.1 闹钟功能

typedef struct {uint8_t enable;uint8_t hours;uint8_t minutes;
} AlarmTypeDef;AlarmTypeDef alarm = {0, 7, 30}; // 7:30闹钟// 闹钟检测
void Check_Alarm(void)
{if(!alarm.enable) return;if(current_time.hours == alarm.hours &&current_time.minutes == alarm.minutes &&current_time.seconds == 0) {BEEP_ON(); // 触发蜂鸣器HAL_Delay(30000); // 持续30秒BEEP_OFF();}
}

8.2 日期显示扩展

typedef struct {uint8_t year;uint8_t month;uint8_t day;
} DateTypeDef;DateTypeDef current_date = {24, 9, 2025}; // 2025-09-24// 日期显示函数
void OLED_ShowDate(uint8_t x, uint8_t y)
{char date_str[11] = "Date:2025-09-24";OLED_DisplayString(x, y, date_str);
}
http://www.wxhsa.cn/company.asp?id=7626

相关文章:

  • kylin V11安装mysql8.0.41(glibc2.28)
  • __cpuid
  • Gitee崛起:国产代码托管平台如何重塑企业研发效能新格局
  • 字节SQL数据库开发手册
  • 完整教程:视频上传以及在线播放
  • C++ STL 常用算法
  • Gitee:中国开发者生态的成长引擎与数字化转型的加速器
  • 【IEEE出版|五邑大学主办|连续四年EI检索】第五届电子信息工程与计算机技术国际学术会议(EIECT 2025)
  • tightvnc使用记录
  • 高科战神全家软件怎么设置
  • 简单数论函数求和题目的一些技巧
  • 3519DV500 BT.1120 无法输出 59.94帧率
  • 独立做产品,做一个,还是做多个找爆款?
  • 第六届计算机工程与智能控制学术会议(ICCEIC 2025)
  • ARL(灯塔)安装步骤
  • c# grpc
  • win10任务栏频繁卡死、转圈
  • Typora Markdown 编辑快捷键大全(优化补充版)
  • 第二届数字经济与计算机科学国际学术会议(DECS 2025)
  • 文件摆渡系统案例分享:医院如何构建高效内外网文件交换通道
  • 淘天一面
  • 利用小波变换对跳频信号进行参数估计
  • 【Qt】Window环境下搭建Qt6、MSVC2022开发环境(无需提前安装Visual Studio) - 实践
  • 编写测试用例技巧
  • 牛客刷题-Day1
  • TENGJUN防水TYPE-C 16PIN连接器技术解析:从结构设计到认证标准的全面解读 - 实践
  • 第三届人工智能与自动化控制国际学术会议(AIAC 2025)
  • 图纸安全外发平台全解析
  • webshell流量 - voasem
  • 软件测试分类