# 简单 MCU 课设开源 -- 电子钟
# 设计内容与要求
# 1.1 设计目标
选用合适的 MCU 设计一个电子钟,包含以下的功能
时间显示
模式切换
闹钟功能
按键输入
其他发挥
# 1.2 设计要求
设计方案的阐述包括以下内容
电路的原理图
元件的选用
程序的流程图 (包括主程序和子程序)
对流程图的解释说明
调试过程
那根据要求,我们大概的方案可以是使用红外接受器来作为接受端,红外遥控来输入,减少硬件上的器件,然后需要一个显示器件,一个实时时钟芯片,一个蜂鸣器,还有保留 3 个基础按键用于未来拓展,剩下就是主控电路的最小系统啥的,比较简单。现在逐个部分来看。
# 元器件选型
# 2.1 主控芯片选型
作为课设主控芯片的选型,主要考虑因素有两点:
- 是否课程有硬性要求,如果有就直接用就好
- 如果可以任选芯片,那么资料多的芯片首先选用,因为资料多说明用户多,而用户多间接反映了出货量大,也就能能保证价格想读低廉
在这个 blog 中的课程设计我们采用的是 ST 公司的 stm8 系列 MCU,具体型号是 stm8s105c6,选用这款主要是我所在大学社团当年培训用了这块开发板,然后这个开发板用来做样例测试就很方便。当然你可以选用自己熟悉的 MCU,像 51 和 STM32,MSP430,甚至 arduino 都是可以使用,核心的实现逻辑也都是一样。
# 2.2 时钟芯片选型
外部时钟芯片简单来说就是一个低功耗的精确计时器,可以带有后备电源,在外部掉电的情况下也可以正常走时,不会丢失时间。这些芯片的典型代表是 DS1302,DS3231 等等。DS1302 的时钟在每个月会飘逸 2~3 分钟,所以需要设置一个校时补偿的功能。然后晶振的选用和 layout 的布局也会对时间飘逸产生影响,具体可以 Google 相关的文章。相比而言 DS3231,带有集成的温补晶振 (TCXO) 和晶体。该器件包含电池输入端,可保持精确的计时。
综上所述我把两个的优缺点列了以下:
DS1302
- 成本低廉
- 时间飘逸问题
- 性价比很高
DS3231
- 带有温度补偿
- 准确性教高
- 价格略高
综合考虑成本,性价比以及编程难易程度和电子钟对环境的要求之后,我选择了 DS1302 芯片作为实时时钟。因为课设的我们以能够低成本完成为主要的指标。
# 2.3 显示器件选型
显示器件我们选用主要用 OLED 和 LCD 两种方案可选
OLED:
- 不需要背光板
- 驱动简单
- 功耗低
- 颜色可选:白色 蓝色 蓝黄色
- 价格贵
LCD:
- 有背光板
- 功耗高
- 屏幕大
- 价格低
显示这因人而已,主要考虑个人观看的因素,我更偏向于价格低廉和屏幕较大的 LCD Nokia 5110,。
# 2.4 其他部件选型
板子其他器件选用,主要可以使用贴片元件,这样可以直接打板后 SMD,省钱的话也能自己焊接,甚至手工做板的话也是可以的。一般器件的封装我建议是使用 0603 或者 0805 的封装,比较小一些,整个板子设计起来也好看小巧,同时焊接难度也不大,小修小改的余地也有,对新手友好些。
# 硬件部分制作
# 3.1 生产工具
PCB 设计工具:Altium Designer / 立创 EDA / KiCAD / Eagle
打板工具:嘉立创(真香)
推荐用立创 EDA 一站式设计和下单,打板,SMT 非常舒服
# 3.2 原理图设计
# 3.2.1 最小系统
根据 STM8 中文手册的核心板手册建议,采用 104,106 作为滤波电容,同时引出 USB 的接口来供电,同时接外部 16M 晶振,使用 22pf 电容作为晶振的启动,然后引出 ST-Link 接口用于烧录程序。正常设计最小系统的流程走就没啥问题。
# 3.2.2 电源管理
电源管理芯片 AMS117, 同时接入保险丝采用的是 500mA, 能够保证异常电流情况,短路情况下能够保证核心芯片不烧坏以及造成其他器件损坏,然后接入一个 LED 用来显示是否正常工作。也是正常设计的操作。
# 3.2.3 实时时钟
按照 Datasheet 给的推荐电路接入晶振和下拉电阻,同时把后背电源和纽扣电池给安排上,同时别忘记加滤波电容
# 3.2.4 其他简单的部分
这部分简单看图就懂
# Layout
# 3.3.1 布局
因为频率不高,而且实际信号设计的方面较少,所以布局以美观为主,紧凑规整,然后双面走线,顶层
横向为主,底层以竖向为主, 其他采用一般的布线规则就可以了,顶层覆铜是 3.3V 的电源,底层是 GND。
# 3.3.2 顶层
# 3.3.3 底层
# 3.3.4 板子设计效果
背后留有足够的空间,能够设计自己的 Logo 和自己的标识
# 3.3.5 板子的 3D 预览
整体器件可以藏在 LCD 后面,进一步优化的话,可以多加两个固定柱子在前面,这样就比较完备了
# 软件部分
# 4.1 软件环境
编程环境: IAR/Keli5/Clion + OpenOCD
烧录环境: ST-Link v2 / 串口
# 4.2 大概流程图
# 4.3 主要部分解析
uchar LCD_Display_menu() | |
{ | |
// 省略次要部分 | |
while(1) | |
{ | |
if(receive_over==1) // 数据接收完成后再执行解码及显示函数 | |
{ | |
receive_over=0; | |
decode(); // 进行解码 | |
if(ir_code[2] == 0x44 || ir_code[2] == 0x40) | |
{ | |
if(ir_code[2] == 0x44 && menu_flag == 1) menu_flag = 4; | |
else if(ir_code[2] == 0x40 && menu_flag == 4) menu_flag = 1; | |
else if(ir_code[2] == 0x44) menu_flag = menu_flag >> 1; | |
else menu_flag = menu_flag << 1; | |
LCD5110_Put_String_6_8(0,5,getBit(menu_flag,0),"Act"); | |
LCD5110_Put_String_6_8(24,5,getBit(menu_flag,1),"Time"); | |
LCD5110_Put_String_6_8(54,5,getBit(menu_flag,2),"ALarm"); | |
} | |
else if(ir_code[2] == 0x46) | |
{ | |
mode_status = ~mode_status; | |
PD_ODR_ODR4 = 1; | |
} | |
else if(ir_code[2] == 0x43) | |
{ | |
return menu_flag; | |
} | |
} | |
LCD_show_time(mode_status); | |
} | |
} |
这这里采用一个位运算的方式,然后用一个变量的某一位来记录现在光标所在的位置,这样能够提升性能也能减少变量空间。
while(1) | |
{ | |
Alarm_LCD_show_time(alarm_flag); | |
if(receive_over==1) // 数据接收完成后再执行解码及显示函数 | |
{ | |
receive_over=0; | |
decode(); // 进行解码 | |
if(ir_code[2] == 0x43) | |
{ | |
mode_status = 1; | |
Save_to_EEP(EEP_Save_buffer,alarm_index); | |
LCD5110_Clear(); | |
return 0; //return | |
} | |
else if(ir_code[2] == 0x15) | |
{ | |
Save_to_EEP(EEP_Save_buffer,alarm_index); | |
alarm_index++; | |
} | |
else | |
{ | |
if(ir_code[2] == 0x44 || ir_code[2] == 0x40) | |
{ | |
if(ir_code[2] == 0x44 && alarm_flag == 1) alarm_flag = 8; | |
else if(ir_code[2] == 0x40 && alarm_flag == 8) alarm_flag = 1; | |
else if(ir_code[2] == 0x44) alarm_flag = alarm_flag >> 1; | |
else alarm_flag = alarm_flag << 1; | |
} | |
else | |
{ | |
alarm_number = get_key(ir_code[2]); | |
for(int i = 0; i < 4;i++) | |
if(getBit(alarm_flag,i)) | |
EEP_Save_buffer[i] = alarm_number; | |
} | |
} | |
} | |
} |
光标逻辑和上面代码一样,然后再闹钟里面能够通过红外遥控直接输入数字,来设置闹钟时间,确认后可以直接存入 EEPROM
软件实现比较简单,没有什么难的,主要思路清晰就可以了。
# 4.4 BUG
调试过程 1:时间校准错误
问题描述:往 DS1302 写入数据时,只写入了年的数据,月份和日还有时间的都写不进去.
解决办法: 多次写入并且在烧录写入多按几下红外遥控,写入需要时间,多次操作就好。
调试过程 2:LCD5110 显示
问题描述:显示不了
解决办法:发现屏幕的接触不是很好,按一按屏幕就好了
More~~
# 4.5 烧录
路径修改
右键工程,Option > Genernal Option 确认芯片是否一致
右键工程,Option > C/C++ compiler > Perprocessor 设置当前各个文件的结构如图所示
右键工程,Option > Debugger > Setup 设置 Driver 为 ST-Link
编译及烧录
- Make
- Download
完整代码: https://github.com/junwide/MCU-Clock
# 打板
嘉立创
实际做板下来价格为:
- 打板 5 块 - 5RMB
- 立创商城元器件 5 套 - 88RMB
手工焊接一套大概是 93/5=18.6 元一套,如果不在立创商城购买器件整个价格能够压到 15 以下应该没问题。
# 最后
开源这个小的课设项目,希望能够给一些入门的小伙伴帮助,在基础上取优化和开发更好的东西。