关于RTC的万年历实验

合集下载

万年历实训报告.doc

万年历实训报告.doc

万年历实训报告.doc
摘要:
本实训主要用于介绍我们能够实现一个基于C语言、Qt图形接口,实现万年历功能的程序。

由于该项目涉及许多基础知识,让学生能够跨科目获得完整的实践经验。

在实训中,我们先了解基础知识,如如何使用C语言及Qt图形接口;然后构建程序。

程序的核心思想是使用类型插入、提取、比较和计算日期的来求解式的历史时期,展示日历,并计算公历农历的值。

最后,我们完成了基于Qt图形界面的万年历程序,实现了查询公历和农历日期,以
及带复杂信息的今天提醒等功能。

本实训有力地提升了学生的计算机知识及实践能力,优
化了学习的过程。

总结:
通过本次实训,学生可以获得跨学科的实践经验,学习到了C语言和Qt图形接口的
知识,以及利用日期插入、提取、比较和计算的历史知识。

并实现了一个基于Qt的万年
历程序,有助于提升学生的实践能力,极大地增强了学习效率。

STM32 RTC万年历设计

STM32 RTC万年历设计
void USARTx_Receive_Unsized_Date(UsartDate_TypeDef *usart) {
static uint8_t num; //接收计数 uint8_t temp=0; //查询是否发生了空闲中断 if(__HAL_UART_GET_FLAG(usart->huart,UART_FLAG_IDLE) != RESET && \
注意,这部分代码要写在 用户代码区之间,闹钟初始化的部分可以保留在外面,不需要加 入到条件判断语句里面。 到这里,如果断电,在恢复以后时间就可以正常走下去了吗?当然…… 是不可以的!!! 现象是:重新上电后,时分秒的时间是可以继续延续下去,但是日期变成了 2000-01-01 , 为什么??这就需要去追一下初始化的代码了。
如果在日期更新的时候,我们没有重新备份日期到备份寄存器中,那么我们上电读回来的时 间就是我们第一次备份的时间,例如,今天我们备份了日期,然后把板子停电 3 天,三天后 再开启的话,读回来的时间就是今天备份的日期,并不是三天后的日期。
对于这个问题,我们就需要在日期更新和设置日期的时候,都需要把新的日期备份到寄存器 中,做法是在日期更新函数中增加备份代码:
我们需要去查看一下 HAL_RTC_Init(&hrtc)这个函数的代码是实现了什么功能。
在函数结尾,我们看到了上面这一段代码,当调用这个函数的时候就会把日期设置成 2000-01-01 了,找到了原因,我们要怎么改呢?这一段初始化代码什么是规避不了的,那 么我们可以在他执行之后重新把日期设置一下,思路还是利用备份寄存器。 我们可以在初始化时,把日期写到备份寄存中,完善一下之前写的条件初始化程序的内容, 增加日期备份。在这里我们备份的日期仅仅是初始化当时配置的时间,上电后读回来的也是 这个时间,不一定就是正确的!!

15.10、 Calendar实时时钟与农历年月日实验

15.10、 Calendar实时时钟与农历年月日实验

Calendar实时时钟与农历年月日实验上一章节我们讲解了STM32的RTC原理并介绍了通过每秒显示当前实时时间的例程。

本章节我们在上一章节的继续上继续讲解STM32的RTC的高级应用,不仅实现当前时分秒的现实,而且实现Calendar农历年月日与节气和公历日历年月日时分秒的计算和显示,在乐趣中让大家更深入的掌握RTC实时时钟功能及用法。

z意义与作用RTC(Real-time clock)是实时时钟的意思。

神舟IV号开发板的处理器STM32F107集成了RTC(Real-time clock)实时时钟,在处理器复位或系统掉电但有实时时钟电池的情况下,能维持系统当前的时间和日期的准确性。

实时时钟是一个独立的定时器。

RTC实时时钟模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。

修改计数器的值可以重新设置系统当前的时间和日期。

本次实验不仅实现当前时分秒的现实,而且实现Calendar农历年月日与节气和公历日历年月日时分秒的计算和显示,在乐趣中让大家更深入的掌握RTC实时时钟功能及用法。

STM32的RTC主要特性为:●可编程的预分频系数:分频系数最高为220。

● 32位的可编程计数器,可用于较长时间段的测量。

●2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟频率的四分之一以上)。

●可以选择以下三种RTC的时钟源:─ HSE时钟除以128;─ LSE振荡器时钟;─ LSI振荡器时钟。

●2个独立的复位类型:─ APB1接口由系统复位;─ RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位。

●3个专门的可屏蔽中断:─闹钟中断,用来产生一个软件可编程的闹钟中断。

─秒中断,用来产生一个可编程的周期性中断信号(最长可达1秒)。

─溢出中断,指示内部可编程计数器溢出并回转为0的状态z实验原理RTC由两个主要部分组成(参见下图)。

第一部分(APB1接口)用来和APB1总线相连。

基于单片机的万年历设计

基于单片机的万年历设计

一、引言万年历是一种显示当前日期和时间的器件或软件。

随着科技的发展,电子产品普及率愈来愈高,基于单片机的万年历设计成为了一种非常受欢迎的设计方案。

本文将介绍一种基于单片机的万年历设计。

二、设计原理1.显示模块:采用液晶显示屏作为显示模块,可以显示日期、时间等信息。

2.时钟模块:基于RTC(实时时钟)模块,用于获取当前日期和时间。

3.按键模块:采用按键模块作为输入模块,用于设置日期和时间、切换显示模式等。

4.控制模块:基于单片机,用于控制各个模块的工作,并进行相关的计算和显示。

三、硬件设计1.单片机选择在本设计中,选择了一款常用的单片机,STM32F103C8T6、它具有低功耗、高性能的特点,并且具备丰富的外设接口,非常适合用来设计万年历。

2.RTC模块选择在本设计中,选择了一款常用的RTC模块,DS1302、它具有低功耗、稳定性好的特点,并且具备SPI接口,非常适合用来获取当前日期和时间。

3.液晶显示屏选择在本设计中,选择了一款常用的液晶显示屏,1602液晶显示屏。

它具有较大的屏幕尺寸、低功耗的特点,并且可以显示多行字符,非常适合用来显示日期、时间等信息。

4.按键模块选择在本设计中,选择了一款常用的按键模块,4x4按键模块。

它具备4行4列的按键布局,可以满足设置日期和时间、切换显示模式等功能的需求。

五、软件设计1.初始化设置在软件设计中,首先需要对各个硬件模块进行初始化设置。

2.获取当前日期和时间使用RTC模块获取当前日期和时间,并将其存储在相应的变量中。

3.显示日期和时间使用液晶显示屏将当前日期和时间显示出来。

4.设置日期和时间通过按键模块获取用户的输入,并将对应的日期和时间设置到RTC模块中。

5.切换显示模式通过按键模块获取用户的输入,并根据用户的选择切换不同的显示模式,例如切换到年模式、月模式、日模式等等。

六、总结通过以上的设计,基于单片机的万年历完成了日期和时间的获取、显示和设置等功能。

万年历实验报告c

万年历实验报告c

万年历实验报告c万年历实验报告一、引言万年历是一种用来记录时间和日期的工具,它可以帮助人们更好地组织日常生活和工作。

本实验旨在探究万年历的原理和功能,并通过实际操作来验证其准确性和可靠性。

二、实验设备和方法1. 实验设备:万年历软件、计算机、手机等。

2. 实验方法:通过使用万年历软件和其他设备,观察和记录不同日期和时间的显示情况,并与实际情况进行对比。

三、实验结果和讨论1. 日期显示准确性在实验过程中,我们发现万年历软件能够准确地显示当前日期,并且可以根据需要切换到其他日期。

无论是过去的日期还是将来的日期,软件都能正确地显示出来。

这表明万年历软件具有很高的日期显示准确性。

2. 节假日提醒功能万年历软件还具有节假日提醒功能,可以在特定的节假日提醒用户。

我们设置了几个节假日,如春节、国庆节等,并观察软件是否能够准确地提醒。

结果显示,软件能够在相应的节假日前一天或当天提醒用户,这对于人们合理安排假期和活动非常有帮助。

3. 日期计算功能万年历软件还提供了日期计算功能,可以根据用户输入的日期和天数,计算出未来或过去的日期。

我们进行了一些日期计算的实验,结果发现软件能够准确地计算出目标日期。

这对于人们进行时间规划和安排非常方便。

4. 多时区显示功能在实验中,我们还测试了万年历软件的多时区显示功能。

通过设置不同的时区,我们观察软件是否能够准确地显示不同地区的时间。

实验结果显示,软件能够根据设置的时区自动调整时间显示,确保用户能够准确了解不同地区的时间。

5. 天气预报功能一些万年历软件还提供了天气预报功能,可以显示当前和未来几天的天气情况。

我们对软件的天气预报功能进行了测试,结果显示软件能够准确地显示天气情况,并且提供了详细的天气信息。

这对于人们出行和活动的决策非常有帮助。

四、结论通过本实验,我们验证了万年历软件的准确性和可靠性。

它能够准确地显示日期、提醒节假日、进行日期计算、显示多时区时间以及提供天气预报等功能。

单片机课程设计报告电子万年历

单片机课程设计报告电子万年历

单片机课程设计报告电子万年历单片机课程设计报告:电子万年历一、设计简介在本次单片机课程设计中,我们选择了电子万年历作为设计主题。

电子万年历是一种结合了数字电路、单片机技术和实时时钟(RTC)技术的电子产品,它具有显示年份、月份、星期、日、时、分、秒的功能,还可以根据用户的需求进行定时、闹钟、报时等功能。

二、硬件设计我们采用了基于8051内核的单片机作为主控芯片。

该单片机具有丰富的I/O 端口,适于实现各种复杂的输入输出操作。

此外,它还内置了定时器和中断控制器,可以很方便地实现实时时钟功能。

1.显示模块:为了方便用户查看时间信息,我们选用了LCD显示屏作为显示设备。

LCD屏具有功耗低、体积小、显示内容丰富等优点。

2.实时时钟(RTC)模块:我们采用了常用的DS1302芯片作为实时时钟模块。

该芯片可以提供秒、分、时、日、星期、月、年的信息,而且还有可编程的报警功能。

3.按键模块:为了实现人机交互,我们设计了一组按键。

用户可以通过按键来调整时间、设置闹钟等。

4.电源模块:为了保证系统的稳定工作,我们采用了稳定的5V直流电源。

三、软件设计我们采用了C语言编写程序。

程序主要由以下几个部分组成:1.主程序:主程序主要负责读取RTC模块的时间信息,并控制LCD显示屏显示时间。

同时,主程序还要检测按键输入,根据用户的需求进行相应的操作。

2.RTC驱动程序:为了正确地读取和设置DS1302芯片的时间信息,我们编写了相应的驱动程序。

驱动程序包括初始化和读写寄存器两部分。

3.按键处理程序:按键处理程序用于检测按键输入,并根据按键值执行相应的操作。

比如,用户可以通过按键来增加或减少时间,设置闹钟等。

4.LCD显示程序:LCD显示程序用于控制LCD显示屏的显示内容。

在本设计中,我们使用了点阵字符库,将时间信息以字符的形式显示在LCD屏上。

四、测试与验证为了确保我们的电子万年历设计正确无误,我们进行了以下的测试和验证:1.硬件测试:首先,我们对硬件电路进行了测试,确保每个模块都能正常工作。

STM32实现万年历..

STM32实现万年历..

STM32学习笔记一竹天笑实现的功能:1、日历功能。

2、数字和模拟时钟功能。

图1(为LCD截屏保存在SD卡中的图像)最终界面如下,但还存在不少漏洞。

1、没有更改时间的设置;2、只有节气显示没有节假日显示3、背景不是用uCGUI画的,是在PS中画好然后存在SD卡中,然后显示的BMP 格式图像。

要点分析:1、STM32自带了RTC时钟计数器,从0开始计数到232。

每一个计数代表秒计数,每六十个计数代表分计数,以此类推。

24(小时)*60(分钟)*60(秒钟)=86400代表一天的计数时间。

假设当前计数为count,count/86400得到计数的天数,根据这个得到年月日。

Count%86400得到时分秒。

2、一些根据1中得到的年月日时分秒,进行计算的程序有:阳历转阴历,闰年判断,节气判断,星期几计算,当前月有多少天等等。

3、模拟时钟的绘制:时钟指针运动算法、屏幕重绘方法、RTC消息、画笔/画刷等。

指针运动算法和屏幕重绘方法是本程序主要难点所在。

(以下参照百度文库之模拟时钟)不论何种指针,每次转动均以π/30弧度(一秒的角度)为基本单位,且都以表盘中心为转动圆心。

计算指针端点(x, y)的公式如下:x =圆心x坐标+ 指针长度* cos (指针方向角)y =圆心y坐标+ 指针长度* sin (指针方向角)注意,指针长度是指自圆心至指针一个端点的长度(是整个指针的一部分),由于指针可能跨越圆心,因此一个指针需要计算两个端点。

由于屏幕的重绘1秒钟一次,如果采用全屏删除式重绘则闪烁十分明显,显示效果不佳。

本程序采用非删除式重绘,假定指针将要移动一格,则先采用背景色(这里是白色)重绘原来指针以删除原来位置的指针,再采用指针的颜色在当前位置绘制指针(如果指针没有动,则直接绘制指针,此句在程序中被我删除,具体原因,为数据截断导致一些误差)。

另外,秒表为RTC一秒钟定时计数。

程序分析:uCGUI+uCOS,一共三个任务:主处理任务、触摸屏任务、秒更新任务。

基于RTC的万年历显示实验

基于RTC的万年历显示实验

基于RTC的万年历显示实验一、实验目的通过程序读取RTC内部的时间寄存器,通过串口将数据传送到虚拟终端上,进行实时时钟显示。

二、实验仪器PROTEUS7.9、Keil uVision5三、实验原理实时时钟(RTC)提供一套计数器在系统上电和关闭操作时对时间进行测量。

RTC在掉电模式下消耗的功率非常低。

LPC2101/02/03的RTC时钟可由独立的32.768kHz振荡器或基于VPB时钟的可编程预分频器来提供。

另外,RTC还具有专用的电源管脚V BAT,可连接到电池或其它器件使用的相同的3.3V电压上。

特性:●测量保持日历和时钟的时间通路;●超低功耗设计,支持电池供电系统;●提供秒、分、小时、日、月、年和星期;●指定的32kHz振荡器或可编程VPB时钟预分频器;●专用电源管脚可与电池或3.3V的电压相连。

在RTC中,含有8个时间计数器(如秒计数器、分计数器等)。

计数器增量中断寄存器(CIIR)中的每个位都对应一个时间计数器,如果使能其中的某一位,那么该位所对应的时间计数器每增加一次,就产生一次中断。

例如:CIIR寄存器bit0对应RTC中的秒计数器,如果CIIR[0] = 1,那么RTC每秒就会引发一次中断。

四、电路设计五、程序设计#include "lpc2103.h"typedef unsigned char uint8 ;typedef unsigned int uint16 ;typedef unsigned long uint32 ;/* 系统设置, Fosc、Fcclk、Fcco、Fpclk定义*/#define Fosc (11059200)#define Fcclk (Fosc * 6) //Fosc的整数倍(1~32),且<=60MHZ#define Fcco (Fcclk * 4) //CCO频率,必须为Fcclk的2、4、8、16倍,范围为156MHz~320MHz#define Fpclk (Fcclk / 4) * 1 //VPB时钟频率,只能为(Fcclk / 4)的1 ~ 4倍/* 定义串口模式设置的数据结构*/typedef struct UartMode{uint8 datab; /* 字长度5/6/7/8 */uint8 stopb; /* 停止位1/2 */uint8 parity; /* 奇偶校验*/}UARTMODE;# define UART_BPS 9600 /* 串口通信波特率*/void UARTInit (void){uint16 uiFdiv;PINSEL0 = (PINSEL0 & 0xFFFFFFF0) | 0x00000005; /* 串口引脚设置*/U0LCR = 0x83; /* 允许设置波特率*/uiFdiv = (Fpclk / 16) / UART_BPS; /* 设置波特率*/U0DLM = uiFdiv / 256;U0DLL = uiFdiv % 256;U0LCR = 0x03; /* 锁定波特率*/U0FCR = 0x01; /* FIFO 使能*/}void UART0SendByte (uint8 uiDat){U0THR = uiDat; /* 写入数据*/while ((U0LSR & 0x40) == 0); /* 等待数据发送完毕*/}void PCDispChar (uint8 uiX, uint8 uiChr){UART0SendByte(0xFF); /* 起始字符*/UART0SendByte(0x81);UART0SendByte(uiX);UART0SendByte(uiChr);UART0SendByte(0x00);}uint8 const uiSHOWTABLE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};void SendTimeRtc (void){uint32 uiDatas;uint32 uiTimes;uint32 bak;uiTimes = CTIME0; /* 读取完整的时钟寄存器*/uiDatas = CTIME1;bak = (uiDatas >> 16) & 0xfff; /* 获取年*/PCDispChar (0, uiSHOWTABLE [bak / 1000]);bak = bak % 1000;PCDispChar(1, uiSHOWTABLE [bak / 100]);bak = bak % 100;PCDispChar (2, uiSHOWTABLE [bak / 10]);PCDispChar (3, uiSHOWTABLE [bak % 10]);bak = (uiDatas >> 8) & 0x0f; /* 获取月*/PCDispChar (4, uiSHOWTABLE [bak / 10]);PCDispChar (5, uiSHOWTABLE [bak % 10]);bak = uiDatas & 0x1f; /* 获取日*/PCDispChar (6, uiSHOWTABLE [bak / 10]);PCDispChar (7, uiSHOWTABLE [bak % 10]);bak = (uiTimes >> 24) & 0x07; /* 获取星期*/PCDispChar(8, uiSHOWTABLE [bak]);bak = (uiTimes >> 16) & 0x1f; /* 获取小时*/PCDispChar (9, uiSHOWTABLE [bak / 10]);PCDispChar (10,uiSHOWTABLE [bak % 10]);bak = (uiTimes >> 8) & 0x3f; /* 获取分钟*/PCDispChar (11, uiSHOWTABLE [bak / 10]);PCDispChar (12, uiSHOWTABLE [bak % 10]);bak = uiTimes & 0x3f; /* 获取秒钟*/PCDispChar (13, uiSHOWTABLE [bak / 10]);PCDispChar (14, uiSHOWTABLE [bak % 10]);}void RTCInit (void){PREINT = Fpclk / 32768 - 1; /* 设置基准时钟分频器*/PREFRAC = Fpclk - (Fpclk / 32768) * 32768;CCR = 0x00; /* 禁止时间计数器*/YEAR = 2008;MONTH = 04;DOM = 07;DOW = 4;HOUR = 15;MIN = 52;SEC = 59;CIIR = 0x01; /* 设置秒值的增量产生1 次中断*/CCR = 0x01; /* 启动RTC */}int main (void){UARTMODE uart0_set;uart0_set.datab = 8;uart0_set.stopb = 1;uart0_set.parity = 0;UARTInit(); /* 串口初始化*/RTCInit(); /* RTC 初始化*/while (1) {while (0 == (ILR & 0x01)); /* 等待RTC 增量中断*/ILR = 0x01; /* 清除中断标志*/SendTimeRtc(); /* 发送到串口显示*/}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

关于RTC的万年历实验一.实验目的:1.通过实验加深对实时时钟RTC结构和工作原理的理解和相关寄存器的应用;2.通过UART传输数据并由PC机终端软件EasyARM.exe显示,复习异步串行口UART 内容;3.通过对《深入浅出ARM7》中万年历显示实验程序的修改添加,实现闹钟功能,以及通过按键可实现时钟和闹钟时间的调整。

二.实验仪器:ARM开发板一块、装有ADS1.2及EasyJTAG仿真器的电脑一台三.实验原理:1.RTC功能结构如下图所示:2.相关寄存器描述:(1)中断位置寄存器—Interrupt Location Register(ILR – 0xE0024000)(2)时钟控制寄存器—Clock Control Register(CCR – 0xE0024008)(3)计数器增量中断寄存器—Counter Increment Interrupt Register(CIIR – 0xE002400C) 计数器增量中断寄存器可使计数器每次增加时产生一次中断。

在中断位置寄存器的位0(ILR[0])写入1之前,该中断一直保持有效。

(4)报警屏蔽寄存器—Alarm Mask Register(AMR – 0xE0024010)对于报警功能来说,要产生中断,非屏蔽的报警寄存器必须匹配对应的时间计数器。

只有当计数器之间的比较第一次从不匹配到匹配时,才会产生中断。

向中断位置寄存器(ILR)的位写入1,会清除相应的中断。

如果所有屏蔽位都置位,报警将被禁止。

四.实验程序:(见附录。

)五.实验结果:通过EasyARM的万年历功能实现了实时时钟和闹钟时间的显示。

同时LED1每秒间隔闪烁,到预设的闹钟时间(即报警时间)时,LED8闪烁三次后蜂鸣器开始播放“虹彩妹妹”的音乐,播放音乐同时LED1跟随音乐节奏闪烁。

按键KEY1按一次,实时时钟计数停止,LED1长亮指示秒调整状态,可通过KEY3(减一)、KEY4(加一)调节秒。

KEY1按两次,进入分钟调整状态,可通过KEY3(减一)、KEY4(加一)调节分钟。

依次类推,可依次调整秒、分、时、星期、日、月、年;按键KEY2按一次,EasyARM显示闹钟时间,类似实时时钟调整功能,可通过按KEY2依次调整闹钟时间(由于程序中报警屏蔽寄存器AMR只是没屏蔽秒报警值,故只要所设的秒报警值与时钟秒计数值相等就会产生报警)。

每次按键时,都有LED8闪烁一次和BEEP蜂鸣一声提示。

六.调试总结和体会:经过整整一天的努力和老师同学的帮助,终于将实验调试成功了。

一开始,经过反复的调试终于实现了报警功能,然后在实验室通过涂老师的指导,实现了播放音乐过程中时钟实时更新功能以及实现LED灯跟随音乐节奏闪烁。

再经过程序的改进,实现了实时时钟和闹钟调整功能。

在同学建议下,添加了LED灯指示调整时间点(秒、分、时、星期、日、月、年)功能。

在调试过程中,总结了一些错误原因分析以及编程注意点:①刚开始时,由于没注意格式书写,程序看起来很乱,在涂老师的建议下,将程序中函数的正反大括号对齐,这样程序变得更直观。

②经过调试以及和同学的探讨,成功实现了KEY3和KEY4按键在最小值和最大值的变化。

其中关键是使用类似if(SEC==0) SEC=59;else SEC- -;和if(SEC==59) SEC=0;else SEC++; 而自己原来是将类似SEC- -和SEC++放在前面,由于SEC寄存器不能取-1值,所以SEC- -放在前面时,不能减到00的状态,直接从01到59了。

原来只是个顺序问题,让程序变得如此微妙。

③在调试时,由于错在将#define KEY1 1<<16 后面多加了“;”导致调试时显示很多错误。

从中发现,有时会因一个地方出错导致显示很多错误。

同样的,有时也会是调试时只显示一个错误,但其实有多个地方有错。

以后要注意这点。

④在调整星期时发现,当7加一时竟变成0了。

和同学讨论后得知原来星期寄存器只用了3为(26:24),所以当7加一时为8但第四位没被获取故只得0。

以后多了解寄存器地址、结构等内部原理知识,这样一些问题就会迎刃而解。

⑤调试时发现,当双击“{”或“}”所在行,则其所包含的函数体会用黑色显示,如下图,这样即可快速找到“{”或“}”的匹配括号,因此也可以很方便用来查错。

⑥通过调试,掌握了按键释放程序的应用。

程序中采用类似while((IO0PIN &KEY4)==0);语句,其作用与while(!(IO0PIN & KEY4));等价得知“!(IO0PIN & KEY4)”并不是取反的意思。

程序中KEY1和KEY2采用等待按键释放,而为了按住按键时自动快速加减,KEY3和KEY4不用等待按键释放程序。

这次实验,我习得了不少,从中体会到多调试多实际操作练习将会发现很多的问题,同时在解决问题过程中可以获得很多知识。

再次,感谢涂老师的指导和同学的帮助。

附录:#include "config.h"#include "music.h"#define BEEP 1<<7const uint32 KEY1=1<<16;const uint32 KEY2=1<<17;const uint32 KEY3=1<<18;const uint32 KEY4=1<<19;const uint32 LED8=1<<25;const uint32 LED1=1<<18;const uint32 LED2=1<<19;const uint32 LED3=1<<20;const uint32 LED4=1<<21;const uint32 LED5=1<<22;const uint32 LED6=1<<23;const uint32 LED7=1<<24;const uint32 LEDS8=0xFF<<18;// 定义串口模式设置的数据结构const uint32 HCMM[] ={_LA, _SO, _MI, _LA, _SO, _MI,_LA, _LA, _SO, _LA,_LA, _SO, _MI, _LA, _SO, _MI,_RE, _RE, _DO, _RE,_MI, _MI, _SO, _LA, _DO1, _LA, _SO,_MI, _MI, _SO, _DO,_MI, _MI, _MI, _MI, _MI,_1LA,_1LA,_1SO,_1LA,};/* 歌曲节拍*/const uint32 HCMM_L[] ={_4, _8, _8, _4, _8, _8,_8, _4, _8, _2,_4, _8, _8, _4, _8, _8,_8, _4, _8, _2,_4, _8, _8, _8, _8, _8, _8,_8, _4, _8, _2,_4, _4, _4, _8, _8,_8, _4, _8, _2,};typedef struct UartMode{uint8 datab; // 字长度5/6/7/8uint8 stopb; // 停止位1/2uint8 parity; // 奇偶校验0-无校验,1-奇校验,2-偶校验}UARTMODE;void Delay(uint8 dly){uint32 i;for(; dly > 0; dly--){ for(i = 0; i < 0x7FFFF; i++);}}uint8 UART0_Init (uint32 baud, UARTMODE set){uint32 bak;// 参数过滤if ((0 == baud) || (baud > 115200)) return (0);if ((set.datab < 5) || (set.datab > 8)) r eturn (0);if ((0 == set.stopb) || (set.stopb > 2)) return (0);if (set.parity > 4) return (0);// 设置串口波特率U0LCR = 0x80; // DLAB=1bak = (Fpclk >> 4) / baud;U0DLM = bak >> 8;U0DLL = bak & 0xff;// 设置串口模式bak = set.datab - 5;if (2 == set.stopb) bak |= 0x04;if (0 != set.parity){set.parity = set.parity - 1;bak |= 0x08;}bak |= set.parity << 4;U0LCR = bak;return (0);}void SendByte (uint8 data){U0THR = data;while ((U0LSR & 0X20) == 0); // 等待数据发送}void PC_DispChar (uint8 no, uint8 chr){SendByte(0xff);SendByte(0x81);SendByte(no);SendByte(chr);SendByte(0x00);}void abd(void){IO0CLR=BEEP;IO1CLR=LED8;Delay(5);IO0SET=BEEP;IO1SET=LED8;}uint8 const SHOWTABLE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};void SendTimeRtc (void){uint32 datas;uint32 times;uint32 bak;times = CTIME0; // 读取完整的时钟寄存器datas = CTIME1;bak = (datas >> 16) & 0xfff; // 获取年PC_DispChar(0, SHOWTABLE[bak / 1000]);bak = bak % 1000;PC_DispChar(1, SHOWTABLE[bak / 100]);bak = bak % 100;PC_DispChar(2, SHOWTABLE[bak / 10]);PC_DispChar(3, SHOWTABLE[bak % 10]);bak = (datas >> 8) & 0x0f; // 获取月PC_DispChar(4, SHOWTABLE[bak / 10]);PC_DispChar(5, SHOWTABLE[bak % 10]);bak = datas & 0x1f; // 获取日PC_DispChar(6, SHOWTABLE[bak / 10]);PC_DispChar(7, SHOWTABLE[bak % 10]);bak = (times >> 24) & 0x07; // 获取星期PC_DispChar(8, SHOWTABLE[bak]);bak = (times >> 16) & 0x1f; // 获取小时PC_DispChar(9, SHOWTABLE[bak / 10]);PC_DispChar(10, SHOWTABLE[bak % 10]);bak = (times >> 8) & 0x3f; // 获取分钟PC_DispChar(11, SHOWTABLE[bak / 10]);PC_DispChar(12, SHOWTABLE[bak % 10]);bak = times & 0x3f; // 获取秒钟PC_DispChar(13, SHOWTABLE[bak / 10]);PC_DispChar(14, SHOWTABLE[bak % 10]);}void SendTimeRtc1 (void){PC_DispChar(0, SHOWTABLE[AL YEAR / 1000]);AL YEAR = AL YEAR % 1000;PC_DispChar(1, SHOWTABLE[AL YEAR / 100]);AL YEAR = AL YEAR % 100;PC_DispChar(2, SHOWTABLE[AL YEAR / 10]);PC_DispChar(3, SHOWTABLE[AL YEAR % 10]);PC_DispChar(4, SHOWTABLE[ALMON / 10]);PC_DispChar(5, SHOWTABLE[ALMON % 10]);PC_DispChar(6, SHOWTABLE[ALDOM / 10]);PC_DispChar(7, SHOWTABLE[ALDOM % 10]);PC_DispChar(8, SHOWTABLE[ALDOW]);PC_DispChar(9, SHOWTABLE[ALHOUR/ 10]);PC_DispChar(10, SHOWTABLE[ALHOUR% 10]);PC_DispChar(11, SHOWTABLE[ALMIN/ 10]);PC_DispChar(12, SHOWTABLE[ALMIN % 10]);PC_DispChar(13, SHOWTABLE[ALSEC / 10]);PC_DispChar(14, SHOWTABLE[ALSEC % 10]); }void __irq RTC_Int(void){uint32 i,num1;if((IO1SET&LED1)==0)IO1SET=LED1;else IO1CLR=LED1;if(num1!=0)SendTimeRtc1();else SendTimeRtc();if(ILR==0x03){for(i=0;i<3;i++){IO1CLR=LED8;Delay(3);IO1SET=LED8;Delay(3);}PINSEL0 = (PINSEL0&0xFFFF3FFF)|(0x02 << 14); // P0.7选择PWM2功能for(i = 0; i < sizeof(HCMM)/4; i++){if((IO1SET&LED1)==0)IO1SET=LED1;else IO1CLR=LED1;PWMMR0 = Fpclk / HCMM[i]; // 设置输出频率PWMLER = 0x05; // 更新匹配值后,必须锁存Delay(HCMM_L[i]); // 延时,控制播放速度if(num1!=0) SendTimeRtc1();else SendTimeRtc();}PINSEL0 = (PINSEL0&0xFFFF3FFF)|(0x00 << 14); // P0.7取消PWM2功能}ILR = 0x03;VICVectAddr = 0;}void RTCInit (void){YEAR = 2011;MONTH = 04;DOM = 28;DOW = 4;HOUR = 10;MIN = 29;SEC = 50;AL YEAR =2003;ALMON = 04;ALDOM = 01;ALDOW = 4;ALHOUR = 06;ALMIN = 42;ALSEC = 20;AMR =0xFE; //设置报警屏蔽寄存器,设置秒值与报警寄存器比较。

相关文档
最新文档