首页 ARM课程设计——报时表及闹钟

ARM课程设计——报时表及闹钟

举报
开通vip

ARM课程设计——报时表及闹钟ARM课程设计——报时表及闹钟 实验名称:报时表及闹钟的设计实验 系 部:物理与机电工程学院 专业班级:07电子信息工程(2)班 学生姓名:阙 开 灿 学 号:2006050427 指导教师:涂二生老师 完成时间:2010年5月6日 报告成绩: 1 GPIO、SPI 1) 设计一个由万年历改装的报时表和闹钟 2) 复习GPIO、SPI的7段数码显示管的工作原理和应用 3) 了解和掌握实时时钟的工作原理及应用 4) 学会综合以前所学的知识实现新的功能 5) 更加熟悉Easy-ARM2138...

ARM课程设计——报时表及闹钟
ARM课程设计——报时表及闹钟 实验名称:报时表及闹钟的设计实验 系 部:物理与机电工程学院 专业班级:07电子信息工程(2)班 学生姓名:阙 开 灿 学 号:2006050427 指导教师:涂二生老师 完成时间:2010年5月6日 报告成绩: 1 GPIO、SPI 1) 设计一个由万年历改装的报时表和闹钟 2) 复习GPIO、SPI的7段数码显示管的工作原理和应用 3) 了解和掌握实时时钟的工作原理及应用 4) 学会综合以前所学的知识实现新的功能 5) 更加熟悉Easy-ARM2138开发板的结构和使用方法 硬件:Easy-ARM实验开发板一套 计算机一台(内装有ADS1.2及EasyJTAG仿真器) 软件:Windows xp系统,ADS1.2集成开发环境 1. 概述: 1) 实时时钟(RTC,Real Time Clock)提供一套计数器在系统上电和关闭 操作时对时间 进行测量,RTC消耗的功率非常低。 2) LPC2131的RTC时钟可由独立的32.768KHz 振荡器或基于VPB时钟的 可编程预分频器来提供。 3) 另外,RTC还具有专用的电源管脚Vbat,可连接到电池或其它器件使用 的相同的 3.3V 电压上。 要使RTC中断能够唤醒掉电的CPU,必须选择外部时钟源。 2. RTC的特性: , 测量保持日历或时钟的时间通路; , 超低功耗设计,支持电池供电系统; , 提供秒、分、小时、日、月、年和星期; , 指定的 32KHz 振荡器或可编程 VPB 时钟预分频器; , 专用电源管脚可与电池或 3.3V 的电压相连。 3. RTC结构: RTC功能结构如图4.116 所示: 2 4. 时间计数器: 1时间计数器寄存器: 秒值 该值的范围为 0~59 0xE0024020 SEC 6 R/W 分值 该值的范围为 0~59 0xE0024024 MIN 6 R/W 小时值 该值的范围为 0~23 0xE0024028 HOUR 5 R/W 日期(月)值该值的范围为1~28,29,30 ,310xE002402C DOM 5 R/W 星期值 该值的范围为 0~6 0xE0024030 DOW 3 R/W 日期(年)值 该值的范围为 1~365 0xE0024034 DOY 9 R/W 月值 该值的范围为 1~12 0xE0024038 MONTH 4 R/W 年值 该值的范围为 0~4095 0xE002403C YEAR 12 R/W 时间计数器的关系和值: 秒 6 0 59 Clk1(图4.116) 分秒6 0 59 小时 分 5 0 23 日期(月) 小时 28, 29, 30 或 31 5 1 星期 小时 3 0 6 日期(年) 小时 365 或 366(闰年) 9 1 月 日期(月) 4 1 12 年月或日期(年)12 0 4095 3 5. 预分频器: 预分频器允许从任何频率高于65.536KHz(2×32.768KHz)的外设时钟源产生一个32.768KHz 的基准时钟。这样,不管外设时钟的频率为多少RTC总是以正确的速率运行。预分频器通过一个包含整数和小数部分的值对外设时钟 (pclk)进行分频。这样就产生了一个不是恒定频率的连续输出,有些时钟周期比 其它周期多1个pclk周期,但是每秒钟的计数总数总是32768。 基准时钟分频器包含一个13位整数计数器和一个15位小数计数器。使用该 规格 视频线规格配置磁共振要求常用水泵型号参数扭矩规格钢结构技术规格书 的原因如下: 1) 对于 LPC2131 所支持的频率,13位整数计数器是必要的。可以这样 进行计算:频率160MH除以32768再减去1等于4881,余数为 26,624。保存4881需要13个位。13位实际所能支持的?高频率为 268.4MHz(32768×8192) 2) 余数的?大值为 32767,需要 15 位来保存。 6. RTC中断: 中断的产生由中断位置寄存器(ILR)、计数器递增中断寄存器(CIIR)、报警寄存器和报警 屏蔽寄存器(AMR) 控制,只有转换到中断状态才能产生中断。ILR 单独使能CIIR和AMR中断(ILR 寄存器实际是一个中断标志寄存器)。 CIIR中的每个位都对应一个时间计数器,如果CIIR使能用于一个特定的计 数器,那么该 计数器的值每增加一次就产生一个中断,如图4.118所示。 报警寄存器允许用户设定产生中断的日期或时间。AMR提供一个屏蔽报警比较的机制,如果所有非屏蔽报警寄存器与它们对应的时间计数器的值相匹配时, 则会产生中断,如 图4.119 所示。 如果 RTC 使用独立的外部振荡器,RTC 中断可使 LPC2131 退出掉电模式。当 RTC 中 断唤醒使能并且所选中断事件出现时,将启动 XTAL 1/2 管脚相关的振荡器,经过一定周期 后,CPU 被唤醒。 4 7. 基本操作: LPC2131 的实时时钟,可用来进行定时报警,日期及时分秒计时等等。RTC 具有独立的电源和时钟源,电源消耗很低,特别适合于电池供电,CPU不连续工作(掉电模式)的系统。通过设置中断唤醒寄存器(INTWAKE),RTC中断还能将CPU从掉电模式下唤醒。设置时钟控制寄存器(CCR)可以选择RTC的计数时钟,由独立的 32.769KHz 振荡器提供或将 Fpclk 进行分频得到。当使用Fpclk作为时钟源时,它的基准时钟分频器允许调节任何频率高于 65.536KHz的外设时钟源产生一个32.768KHz的基准时钟,实现准确计时操作。 如图4.120 所示,实时时钟CTC计数器的时钟源使用由PCLK通过基准时钟分频器 (PREINT、PREFRAC)调整出的32768Hz时钟信号,或者直接使用 独立的外部32.768KHz振荡器产生的时钟信号。CTC是一个15位的计数器,它位于秒计数器之前,CTC每秒计数 32768个时钟;当有CTC秒进位时,完整时间CTME0~2、RTC时间寄存器(如SEC、MIN等)将会更新;RTC中断有两种,一种是增量中断,由CIIR进行控制,另一种为报警中断,由AMR寄存器和各报警时间寄存器控制,如ALSEC、ALMIN等;报警位置寄存器ILR用来产生相应的中断标志;RTC时钟控制寄存器CCR用于使能实时时钟,CTC复位控制等。 其中,日期寄存器(表示“日”)有两个,分别为DOY和DOM,DOY表示为一年中的 第几日,值为1~365(闰年为 366);而DOM则为一月中的第几日,值 为1~28/29/30/31,一般日期计数使用DOM 即可。 RTC 基本操作方法: , 选择时钟源(CCR 寄存器); , 设置 RTC 基准时钟分频器(PREINT、PREFRAC)(根据上一步选择 执行此步操作); , 初始化 RTC 时钟值,如 YEAR、MONTH、DOM 等; , 报警中断设置,如 CIIR、AMR 等; , 启动 RTC,即 CCR 的 CLKEN 位置位; , 读取完整时间寄存器值,或等待中断。 5 开始 选择引脚连接SPI;设置连接串口0; P0.7、P1.18、P[21:16] 选择连接GPIO; 设置P0.7、P1.18为输出状态,P[21:16] 为输入状态 SPI,串口0初始设置基准时钟; 化 设置年、月、日、星期、 时、分、秒; RTC初始化 设置秒增量产生中断; 启动RTC 增量中断标志置位? 否 是 清除RTC中断 读取时钟,送到上位机显示 KEY1 KEY2 KEY3 KEY4 KEY5 KEY6 否 否 否 否 否 否 按下 按下 按下 按下 按下 按下 ? ? ? ? ? ? MONTH=1 DOM=1 DOW=1 HOUR=0 MIN=0 年份自增1 星期 分钟 月份 日期 小时 YEAR++ 大于7 大于59 大于12 大于30 大于23 是 是 是 是 是 ? ? ? ? ? 月份自增 否 否 否 否 否 MONTH+日期自增 星期自增 小时自增 分钟自增 + DOM++ DOW++ HOUR++ MIN++ A 6 A MIN=59?& SEC=59? 否 是 LED1灯熄灭; LED1灯闪烁; 蜂鸣器停止鸣叫; 蜂鸣器鸣叫10声; LED2灯熄灭; 数码管熄灭 数码管显示10s倒计时 蜂鸣器停止鸣叫; 数码管熄灭 否 MIN & SEC==0?& HOUR==7? 是 7点闹钟报警; LED2灯亮; 蜂鸣器鸣叫;数码管显示7 结合GPIO、SPI,用实时时钟实现报时和闹钟的功能。 1) 按照开发板说明连接计算机,打开ADS1.2和H-JTAG软件给开发板上电调 试。 2) 观察实验现象,看看蜂鸣器是否鸣叫,程序是否正常运作。 3) 适当调节定时器的定时时间,观察程序运行现象。 4) 修改程序,观察程序运行后,是否符合预计程序的功能。 程序说明: 本程序是结合了GPIO、SPI和实时时钟设计的一个由万年历改装的报时表 和闹钟。 实验程序(): #include "config.h" #define HC595_CS (1 << 29) // P0.29口为74HC595的片选 7 #define BEEP 1 << 7 // P0.7控制蜂鸣器,低电平蜂鸣 const uint32 LEDS8 = (0xFF << 18);// P1[25:18]控制LED8~LED1,低电平点亮 const uint32 KEY1 = 1 << 16; // P0.16连接KEY1 const uint32 KEY2 = 1 << 17; const uint32 KEY3 = 1 << 18; const uint32 KEY4 = 1 << 19; const uint32 KEY5 = 1 << 20; const uint32 KEY6 = 1 << 21; uint8 rcv_data; /**************************************************************************************** ** 函数 excel方差函数excelsd函数已知函数     2 f x m x mx m      2 1 4 2拉格朗日函数pdf函数公式下载 名称:MSPI_Init() ** 函数功能:初始化SPI接口,设置为主机。 ** 入口参数:无 ** 出口参数:无 ****************************************************************************************/ void MSPI_Init(void) { //PINSEL0 = (PINSEL0 & 0xFFFF00FF) | 0x00005500; PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x55 << 8) ; SPCCR = 0x52; // 设置SPI时钟分频 SPCR = (0 << 3) | // CPHA = 0, 数据在SCK 的第一个时钟沿采样 (1 << 4) | // CPOL = 1, SCK 为低有效 (1 << 5) | // MSTR = 1, SPI 处于主模式 (0 << 6) | // LSBF = 0, SPI 数据传输MSB (位7)在先 (0 << 7); // SPIE = 0, SPI 中断被禁止 } /**************************************************************************************** ** 函数名称:MSPI_SendData() ** 函数功能:向SPI总线发送数据。 ** 入口参数:data 待发送的数据 ** 出口参数:返回值为读取的数据 ****************************************************************************************/ uint8 MSPI_SendData(uint8 data) { IOCLR = HC595_CS; // 片选74HC595 SPI_SPDR = data; while( 0 == (SPI_SPSR & 0x80)); // 等待SPIF置位,即等待数据发送完毕 IOSET = HC595_CS; return(SPI_SPDR); } uint8 const DISP_TAB[11] = { // 0 1 2 3 4 5 6 7 8 9 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90,0xff }; 8 // 定义串口模式设置的数据结构 typedef struct UartMode { uint8 datab; // 字长度 5/6/7/8 uint8 stopb; // 停止位 1/2 uint8 parity; // 奇偶校验 0-无校验, 1-奇校验, 2-偶校验 }UARTMODE; /**************************************************************************************** ** 函数名称 :DelayNS() ** 函数功能 :长软件延时 ** 入口参数 :dly 延时参数,值越大,延时越久 ** 出口参数 :无 ****************************************************************************************/ void DelayNS (uint32 dly) { uint32 i; for ( ; dly>0; dly--) for (i=0; i<50000; i++); } /**************************************************************************************** * 函数名称 :UART0_Init() ** 函数功能 :初始化串口:设置工作模式和波特率。 ** 入口参数 :baud 波特率 ** set 模式设置(UARTMODE数据结构) ** 出口参数 :返回1表示成功,0表示参数出错。 ****************************************************************************************/ uint8 UART0_Init (uint32 baud, UARTMODE set) { uint32 bak; // 参数过滤 if ((0 == baud) || (baud > 115200)) return (0); if ((set.datab < 5) || (set.datab > 8)) return (0); if ((0 == set.stopb) || (set.stopb > 2)) return (0); if (set.parity > 4) return (0); // 设置串口波特率 U0LCR = 0x80; // DLAB=1 bak = (Fpclk >> 4) / baud; U0DLM = bak >> 8; U0DLL = bak & 0xff; 9 // 设置串口模式 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); } /**************************************************************************************** ** 函数名称 :SendByte() ** 函数功能 :向串口UART0发送字节数据,并等待发送完毕。 ** 入口参数 :data 要发送的数据 ** 出口参数 :无 ***************************************************************************************/ void SendByte (uint8 data) { U0THR = data; while ((U0LSR & 0X20) == 0); // 等待数据发送 } /**************************************************************************************** ** 函数名称 :PC_DispChar() ** 函数功能 :向PC机发送显示字符。 ** 入口参数 :no 显示位置 ** char 显示的字符,不能为ff ** 出口参数 :无 ****************************************************************************************/ void PC_DispChar (uint8 no, uint8 chr) { SendByte(0xff); SendByte(0x81); SendByte(no); SendByte(chr); SendByte(0x00); } uint8 const SHOWTABLE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; /**************************************************************************************** ** 函数名称 :SendTimeRtc() ** 函数功能 :读取RTC的时间值,并将读出的时分秒值通过串口送到上位机显 10 示。 ** 入口参数 :无 ** 出口参数 :无 ****************************************************************************************/ 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]); } 11 /**************************************************************************************** ** 函数名称 :RTCInit() ** 函数功能 :初始化实时时钟 ** 入口参数 :无 ** 出口参数 :无 ****************************************************************************************/ void RTCInit (void) { PREINT = Fpclk / 32768 - 1; // 设置基准时钟分频器 PREFRAC = Fpclk - (Fpclk / 32768) * 32768; CCR = 0x00; // 禁止时间计数器 YEAR = 2005; MONTH = 01; DOM = 10; DOW = 4; HOUR = 8; MIN = 30; SEC = 59; CIIR = 0x01; // 设置秒值的增量产生1次中断 CCR = 0x01; // 启动RTC } /**************************************************************************************** ** 函数名称 :main() ** 函数功能 :读取实时时钟的值,通过串口发送出去。 ****************************************************************************************/ int main (void) { PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x55 << 8) ;// 设置SPI管脚连接 PINSEL1 = 0x00000000; IO0DIR = HC595_CS| BEEP; // 从机片选 IO0SET = BEEP; MSPI_Init(); IO0DIR = BEEP; PINSEL2 = PINSEL2 & (~0x08); // P1[25:16]连接GPIO IO1DIR = LEDS8; // LEDS8控制口 UARTMODE uart0_set; PINSEL0 = 0x00000005; // 连接IO到UART0 uart0_set.datab = 8; uart0_set.stopb = 1; uart0_set.parity = 0; UART0_Init(115200, uart0_set); U0FCR = 0x01; // FIFO使能 12 RTCInit(); while (1) { while (0 == (ILR & 0x01)); // 等待RTC增量中断 if((IO0PIN & KEY1)==0) YEAR++; //调节年 if((IO0PIN & KEY2)==0) if(MONTH<12) MONTH++; //调节月 else MONTH=1; SendTimeRtc( ) if((IO0PIN & KEY3)==0) if(DOM<30) DOM++; //调节日 else DOM=1; SendTimeRtc( ) if((IO0PIN & KEY4)==0) if(DOW<7) DOW++; //调节星期 else DOW=1; SendTimeRtc( ) if((IO0PIN & KEY5)==0) if(HOUR<23) HOUR++; //调节小时 else HOUR=0; SendTimeRtc( ) if((IO0PIN & KEY6)==0) if(MIN<59) MIN++; //调节分钟 else MIN=0; SendTimeRtc( ) if(MIN==59 & SEC==50) //倒计时10s { IO0CLR=BEEP; IO1CLR=LED1; DelayNS(10); IO0SET=BEEP; IO1SET=LED1; DelayNS(10); for(i=59;i>10;i--) rcv_data = MSPI_SendData(DISP_TAB[i]); // 发送显示数据 } else IO0SET=BEEP; IO1SET=LED1; rcv_data = MSPI_SendData(DISP_TAB[11]); // 发送显示数据 if(MIN==0&SEC==0&HOUR=7) { IO0CLR=BEEP; IO1CLR=LED2; rcv_data = MSPI_SendData(DISP_TAB[8]); // 发送显示数据 } else IO0SET=BEEP; IO1SET=LED2; rcv_data = MSPI_SendData(DISP_TAB[11]); // 发送显示数据 13 while (0 == (ILR & 0x01)); // 等待RTC增量中断 ILR = 0x01; // 清除中断标志 SendTimeRtc(); } return (0); } /**************************************************************************************** ** End Of File ****************************************************************************************/ 在运行本实验程序后,打开EasyARM.exe,实验现象如下: 打开万年历窗口,显示2010年,05月06,10:50:30。 , 当KEY1键按一下时,年会增加1; , 当KEY2键按一下时,月份小于12则会增加1,要是月份为12则变为1; , 当KEY3键按一下时,日期小于30则会增加1,要是日期为30则变为1; , 当KEY4键按一下时,星期小于7则会增加1,要是星期为7则变为1; , 当KEY5键按一下时,小时小于23则会增加1,要是小时为23则变为0; , 当KEY6键按一下时,分钟小于59则会增加1,要是分钟为59则变为0。 1) 当分钟为59,秒钟为50时,即到整点时的最后10s,数码管显示9~0的 倒计时、蜂鸣器相应的鸣叫10声和LED1灯相应的闪10次。 2) 当时钟的时、分、秒分别显示为07:00:00,即早上7点整时,有闹钟 会响,即蜂鸣器会鸣叫,而且LED2灯会亮,数码管显示7。 通过本次实验,让我又复习了GPIO、SPI的7段数码管的应用;了解了实 时时钟的工作原理及其应用;以及掌握了综合几个小实验实现一个新功能;更加 熟练了ARM的实验环境。 通过这次实验也让我学会了如何不断地发现问题并解决问题。比如,在定时 10s时,定时不准,不能实现每倒计时一秒蜂鸣器就响一次、LED灯闪一下和数码管显示相应的数字。后来想了很久并通过和同学讨论才解决这个问题。还有就 是在一些小细节上也遇到不少问题,不过这些小问题都通过一次又一次的运行仿 真解决了。 总的来说,要做到每做一个实验,不但能实现该有的功能还要能学到不少的 知识。这样才能达到了做实验的目的。 14
本文档为【ARM课程设计——报时表及闹钟】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_003124
暂无简介~
格式:doc
大小:134KB
软件:Word
页数:21
分类:互联网
上传时间:2017-10-08
浏览量:10