基于单片机的数字时钟设计与实现
作品名称
基于MSP430单片机的OLED显示数字时钟
作品功能
本作品实现了一个具有时间显示和整点报时功能的数字时钟。通过OLED屏幕显示当前时间,用户可以通过按键设置时间,并在整点时通过蜂鸣器播放音乐进行报时。
作品的硬件材料
- MSP430 单片机
- OLED 显示屏
- 蜂鸣器
- 按键(4个)
- 电阻和电容若干
- 面包板和连接线
电子元器件连接
以下是各电子元器件与MSP430单片机的连接方式:
OLED 显示屏
- VCC 接 3.3V
- GND 接 GND
- SCL 接 P2.0
- SDA 接 P2.2
按键
- KEY1 接 P1.2(共GND)
- KEY2 接 P1.3(共GND)
- KEY3 接 P1.4(共GND)
- KEY4 接 P1.5(共GND)
蜂鸣器
- VCC 接 3.3V
- GND 接 GND
- DAT 接 P4.3
部分程序功能简介
本程序主要包括初始化时钟、设置RTC、按键读取、显示更新和整点报时等功能。
初始化时钟
通过以下函数设置系统时钟为8MHz:
void initClock(void) {UCSCTL3 = SELREF_2; // 设置DCO FLL参考为REFOUCSCTL4 |= SELA_2; // 设置ACLK为REFOUCSCTL0 = 0x0000; // 设置最低可能的DCOx, MODxdo {UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // 清除XT2,XT1,DCO故障标志SFRIFG1 &= ~OFIFG; // 清除故障标志} while (SFRIFG1 & OFIFG); // 检测振荡器故障标志__bis_SR_register(SCG0); // 禁止FLL控制环路UCSCTL1 = DCORSEL_5; // 设置DCO范围为16MHz操作UCSCTL2 |= 249; // 设置DCO倍增器为8MHz__bic_SR_register(SCG0); // 启用FLL控制环路__delay_cycles(250000); // 延时以稳定DCO
}
设置RTC
通过以下函数设置RTC(实时时钟)模块:
void SetupRTC(void) {RTCCTL01 = RTCHOLD + RTCMODE + RTCTEV_0; // 关闭RTCRTCYEAR = 2024; // 设置年份RTCMON = 5; // 设置月份RTCDAY = 13; // 设置日期RTCHOUR = 23; // 设置小时RTCMIN = 12; // 设置分钟RTCSEC = 12; // 设置秒数RTCDOW = 1; // 设置星期RTCCTL0 |= RTCRDYIE; // 使能RTC就绪中断RTCCTL01 &= ~RTCHOLD; // 打开RTC
}
按键读取
通过以下函数读取按键状态:
unsigned char read_key(void) {unsigned char key = 0;if ((P1IN & BIT2) == 0) {key = 1; // 按键1按下} else if ((P1IN & BIT3) == 0) {key = 2; // 按键2按下} else if ((P1IN & BIT4) == 0) {key = 3; // 按键3按下} else if ((P1IN & BIT5) == 0) {key = 4; // 按键4按下}return key;
}
显示更新
通过以下函数更新OLED显示内容:
void display_all(void) {memset(buf, 0, sizeof(buf));sprintf(buf, "%04d-%02d-%02d", nian, yue, ri); // 格式化日期OLED_ShowString(16, 2, buf, 0); // 显示日期memset(buf, 0, sizeof(buf));sprintf(buf, "%02d:%02d:%02d", shi, fen, miao); // 格式化时间OLED_ShowString(16, 4, buf, 0); // 显示时间// 高亮显示根据mode的值选择的部分if (mode == 1) {sprintf(buf, "%04d", nian);OLED_ShowString(16, 2, buf, 1);} else if (mode == 2) {sprintf(buf, "%02d", yue);OLED_ShowString(16 + 5 * 8, 2, buf, 1);} else if (mode == 3) {sprintf(buf, "%02d", ri);OLED_ShowString(16 + 8 * 8, 2, buf, 1);} else if (mode == 4) {sprintf(buf, "%02d", shi);OLED_ShowString(16, 4, buf, 1);} else if (mode == 5) {sprintf(buf, "%02d", fen);OLED_ShowString(16 + 3 * 8, 4, buf, 1);} else if (mode == 6) {sprintf(buf, "%02d", miao);OLED_ShowString(16 + 6 * 8, 4, buf, 1);}
}
整点报时
当达到整点时,通过蜂鸣器播放音乐:
if (integral_point == 1) { // 如果到达整点integral_point = 0;u = 0, t = 0;while (music0[u] != 0xff) { // 播放音乐TA0CCR0 = SYSCLK / music0[u] / 2;TA0CTL = TASSEL_2 + MC_1 + TACLR + ID_3;for (t = 0; t < music0_JP[u]; t++) {delay1();}u++;}
}
总结
通过本项目,熟悉了MSP430单片机的基础功能,如时钟设置、按键读取和OLED显示。同时,结合蜂鸣器实现了整点报时功能,为单片机应用提供了实用案例。这个数字时钟不仅展示了基本的电子设计和编程能力,还提供了可扩展的基础,适合进一步添加更多功能。
全部代码下载
咨询问询请访问:
https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2