2024年上海交通大学嵌入式课程大作业
本学年是嵌入式第一次上升到4学分,即在原本的2学分的理论课程之上增设了2学分的实验课,因而成为了一门大课。
不同老师之间大作业的要求不同,所以我把我们班的实验要求罗列出来,并谈一谈我的实现方案,希望能够作为前人的智慧,起到抛砖引玉的效果。一纲举而万目张,在这里我略去具体的代码实现,只做简要的说明,将实现留给各位,以求同学们能够在这门实验课中还能够学到些东西,同时也是为了课程的公平性做出的考量。
实验要求
一、作业概述
利用 S800 板完成一个数字时钟功能。能够实现如下功能:
1、日期的显示及设置。
2、时间的显示及设置。
3、左流水显示及右流水显示。日期,时间流水显示,速度 2 级可调。
4、调整及设置功能需要能够以 8 位按键控制,以及能够通过串行口控制。
5、开机画面最少要包括数码管及 LED 的全灭全亮闪烁 1 次,学号后 8 位闪烁一次,姓名拼音闪烁一次。
6、选做。用 LMFLASH PROGRAMMER 将 APP 通过 UART 烧录进 S800 中并运行。
7、8 位 LED 作为辅助指示,不限位置,自定义功能。
8、串行口能够进行时间及闹钟设置,能够获取时间及闹钟操作等。
其中时钟要求能够可以在休眠(即外部VCC断电,而由内部的电源供电的情况)的时候保持计数,在重新上电后能够恢复显示日历。因而这需要自己查文档实现对S800板的实时时钟实现调用。其他的部分只要理清思路就可以逐步调试完成,所以我先把课堂上没有讲过的RTC实现方法在这里概述一下,然后再展开其他功能的实现。
RTC
The RTC module is designed to keep wall time. The RTC can operate in seconds counter mode or calendar mode. A 32.768 kHz clock source along with a 15-bit predivider reduces the clock to 1 Hz. The 1 Hz clock is used to increment the 32-bit counter and keep track of seconds. In calendar mode, registers are provided which support the tracking of date, month, year and day-of-week. A match register can be configured to interrupt or wake the system from hibernate. In addition, a software trim register is implemented to allow the user to compensate for oscillator inaccuracies using software.
———— excerpt from tm4c1294ncpdt.pdf, 7.3.5 Real-Time Clock
可见,将RTC配置到Calendar模式就可以达到我们的需要,同时可以考虑使用软件补偿来校准时间,下面我们继续看如何调用时钟的API。
7.3.5.3章节中说明了calendar模式设置时需要注意的事项,以及该功能使用的内存器。下面我们在看看在API中如何使用该功能。在SW-TM4C-DRL-UG-2.1.4.178我们查阅到休眠时相关功能(包括RTC)在该手册的第15节中。
查看我们需要的函数,发现值是使用tm类型的struct指针传递的,那么问题来了,tm结构体是怎么定义的呢?在这个文档中并没有任何说明,经过查找资料,发现原来tm结构体是C/C++中常见的定义时间的一个结构体,其定义在C的标准头文件"time.h"中可以找到。其定义如下:
struct tm {int tm_sec; /* 秒,范围从 0 到 59 */int tm_min; /* 分,范围从 0 到 59 */int tm_hour; /* 小时,范围从 0 到 23 */int tm_mday; /* 一月中的第几天,范围从 1 到 31 */int tm_mon; /* 月,范围从 0 到 11 */int tm_year; /* 自 1900 年起的年数 */int tm_wday; /* 一周中的第几天,范围从 0 到 6 */int tm_yday; /* 一年中的第几天,范围从 0 到 365 */int tm_isdst; /* 夏令时 */
};
使用方法如下:
#include <time.h>
sttuct tm t;