1、目录摘要1一、设计任务和要求2二、设计过程2三、设计流程图6四、源程序清单及说明7五、调试过程11六、设计心得11七、参考文献11摘要 今年来,32位嵌入式系统发展很快,32位单片机已逐渐占领8位机的市场,并以很高的性价比赢得了越来越多的用户的青睐。随着科技和工艺的进步,32位单片机的优势会更加突显出来,将会成为嵌入式系统的主流。在32位嵌入式系统中,基于ARM的应用占据了大部分份额。EasyARM2131开发板是广州周立功公司设计的EasyARM系列开发套件之一,采用了PHILIPS公司基于ARM7TDMI-S 核、单电源供电、LQFP64封装的LPC2131,具有JTAG仿真调试、ISP编
2、程等功能。本次设计是采用LPC2138的32位芯片设计的可调万年历,具有调时、调分,60秒倒计时和准点报时的功能。同时当倒计时至0时,LED亮;采用的是PWM输出音乐准点报时。关键词:ARM LPC2138 LED PWM一、设计任务和要求:1、 课程设计目的(1) 了解嵌入式芯片的工作原理,从而学会制作相关的东西。 (2) 通过课程设计进一步的了解各种在设计中常用到的程序的作用及程序的调试方法。 (3) 进一步了解嵌入式系统以及嵌入式在实际生活中的应用2、 课程设计要求(1) 本次设计要包含ARM板上的几个模块 (2) 本次设计要有一定有实际意义(有应用价值)二、设计过程: 本设计实现了时钟
3、、星期、日期(月、日)的显示,校时校分,60秒倒计时以及准点报时等功能。各功能原理描述如下:(一)、时钟、星期、日期(月、日)的显示:LPC2138的RTC时钟可由独立的32.768kHz振荡器或基于VPB时钟的可编程预分频器来提供。RTC提供秒、分、小时、日、月、年和星期。RTC功能结构方框图: RTC包含了许多寄存器,按照功能可分:混合寄存器、时间寄存器、时间计数器、报警寄存器和预分频器。 如下图所示,设置时钟控制寄存器(CCR)可以选择RTC的计数时钟,实时时钟CTC计数器的时钟源使用由PCLK通过基准时钟分频器(PREINT、PREFRAC)调整出的 32768Hz时钟信号,或者直接使
4、用独立的外部 32.768KHz振荡器产生的时钟信号。CTC是一个 15 位的计数器,它位于秒计数器之前,CTC每秒计数 32768个时钟;当有CTC秒进位时,完整时间CTME02、RTC时间寄存器(如SEC、MIN等)将会更新。RTC时钟控制寄存器CCR用于使能实时时钟和CTC复位控制等。(二) 、校时校分:本功能采用按键控制。EasyARM2131开发板上的6个按键,电路图如下图所示:先要设置IODIR使口线成为输入方式,然后读取IOPIN的值,判断是否有键按下,若KEY1按下,则小时计数器HOUR加1,若KEY2按下,则分钟计数器加1,从而实现了校时校分的功能。(三)、60秒倒计时:定义
5、一个外部变量yhy且初始值为59,当RTC产生增量中断时,yhy减1。当yhy为0时,8个LED全亮,否则全暗。再赋予yhy等于59进行下一次倒计时。Yhy的显示取代RTC的年。即RTC显示年的四个数码管中选两个用来显示yhy的值。Yhy的值将和秒、分、日、月、星期一起送到上位机显示。EasyARM2131开发板上的8路LED(LED8LED1)分别可选择P125:18进行控制。当跳线JP12全部选择LED8LED1后,P1.25P1.18分别控制这8路LED。当P125:18都输出低电平时,8个 LED点亮,当P125:18都输出高电平时,8个LED熄灭。实验程序首先设置管脚连接GPIO,接
6、着设置P125:18口为输出模式,然后通过IO1CLR和IO1SET控制P125:18,驱动8个LED的亮灭, 8路LED电路如下图所示:(四)、准点报时:当时钟计数至准点时,PWM2输出音乐,报时时间为15秒。LPC2138的脉宽调制器(PWM)建立在标准定时器0/1之上。两个匹配寄存器可用控制单边沿PWM输出。PWMMR0控制PWM周期率,另一个匹配寄存器(PWMMR1PWMMR6)控制PWM边沿的位置。每个额外的单边沿PWM输出只需要一个匹配寄存器,因为所有PWM输出的重复率速率是相同的。多个单边沿控制PWM输出在每个PWM周期的开始,当PWMMR0发生匹配时,都有一个上升沿。通过改变P
7、WMMR0的值,可以改变PWM输出的频率。实验设定PWM输出单边沿PWM方波,控制蜂鸣器BEEP发声,改变PWM的频率,蜂鸣器发出不同频率的声音。进行PWM音乐输出实验,需要了解一些简谱和频率的关系。单边沿控制PWM输出规则示意图: PWM输出音乐流程图:三、设计流程图:四、源程序清单及说明:#include config.h#include music.hconst uint32 KEY1 = 1 16;/ P0.16连接KEY1const uint32 KEY3 = 1 18;/ P0.18连接KEY3const uint32 LEDS8 = (0XFF 115200)return (0)
8、;if (set.datab 8)return (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 |=
9、 0x08;bak |= set.parity 8) & 0x0f;/ 获取 月PC_DispChar(4, SHOWTABLEbak / 10);PC_DispChar(5, SHOWTABLEbak % 10);bak = datas & 0x1f;/ 获取 日PC_DispChar(6, SHOWTABLEbak / 10);PC_DispChar(7, SHOWTABLEbak % 10);bak = (times 24) & 0x07;/ 获取 星期PC_DispChar(8, SHOWTABLEbak);bak = (times 16) & 0x1f;/ 获取 小时PC_DispC
10、har(9, SHOWTABLEbak / 10);PC_DispChar(10, SHOWTABLEbak % 10);bak = (times 8) & 0x3f;/ 获取 分钟PC_DispChar(11, SHOWTABLEbak / 10);PC_DispChar(12, SHOWTABLEbak % 10);bak = times & 0x3f;/ 获取 秒钟PC_DispChar(13, SHOWTABLEbak / 10);PC_DispChar(14, SHOWTABLEbak % 10);/* 函数名称 :DelayNS()* 函数功能 :长软件延时*/void Delay
11、NS (uint32 dly)uint32 i;for ( ; dly0; dly-)for (i=0; i500000; i+);/* 函数名称 :RTCInit()* 函数功能 :初始化实时时钟*/void RTCInit (void)PREINT = Fpclk / 32768 - 1; / 设置基准时钟分频器PREFRAC = Fpclk - (Fpclk / 32768) * 32768;CCR = 0x00; / 禁止时间计数器MONTH = 01;DOM = 10;DOW = 4;HOUR = 8;MIN =59;SEC = 50;CIIR = 0x01;/ 设置秒值的增量产生1
12、次中断CCR = 0x01;/ 启动RTC/* 函数名称 :main()* 函数功能 :读取实时时钟的值,通过串口发送出去。*/int main (void) uint8 s_cnt=0; UARTMODE uart0_set;PINSEL0 = 0x00000005; / 连接IO到UART0PINSEL1 = 0x00000000;PINSEL2 = PINSEL2 & (0x08);/ P125:16连接GPIOIO1DIR = LEDS8;/ 设置LEDS8控制口为输出uart0_set.datab = 8;uart0_set.stopb = 1;uart0_set.parity =
13、0;UART0_Init(115200, uart0_set);U0FCR = 0x01;/ FIFO使能 /* PWM初始化 */ PWMPR = 0x00; / 不分频,计数频率为Fpclk PWMMCR = 0x02;/ 设置PWMMR0匹配时复位PWMTC PWMPCR = 0x0400;/ 允许PWM2输出,单边PWM PWMMR0 = Fpclk / 450; PWMMR2 = PWMMR0 / 2;/ 50%占空比 PWMLER = 0x05;/ PWM0和PWM2匹配锁存 PWMTCR = 0x02; / 复位PWMTC RTCInit();while (1) if (IO0P
14、IN & KEY1) = 0) CCR = 0x00; / 禁止时间计数器 DelayNS(1); HOUR=(HOUR+1)%24; / 如果KEY1按下, CCR = 0x01; / 启动RTC if (IO0PIN & KEY3) = 0) CCR = 0x00; / 禁止时间计数器 DelayNS(1); MIN=(MIN+1)%60; / 如果KEY3按下, CCR = 0x01; / 启动RTC while (0 = (ILR & 0x01)/ 等待RTC增量中断 if(SEC=0)&(MIN=0) hour_flag=1; ILR = 0x01;/ 清除中断标志 yhy=yhy-
15、1; if(yhy=0) IO1CLR = LEDS8;/ 8个LED点亮 else IO1SET = LEDS8;/ 8个LED熄灭 if(yhy=(-1) yhy=59; SendTimeRtc(); if (hour_flag) /每秒一次 if (s_cnt16) PINSEL0 = 0x00000005 | (0x02 14);/ 连接IO到UART0 PWMMR0 = Fpclk / HCMMs_cnt; / 设置输出频率 PWMTCR = 0x09; / 启动PWM输出 PWMLER = 0x05; / 更新匹配值后,必须锁存 s_cnt+; else PINSEL0 = 0x0
16、0000005 ; / 连接IO到UART0 s_cnt=0; hour_flag=0; return (0);/* End Of File*修改,即引入外部变量yhy来代替年份的显示即每次增量中断产生时yhy减1。将修改的程序进行编译然后下载到芯片,然后运行。观察开发板的现象,看是否能五、调试过程:整个设计的调试过程是分步进行的。 1)、 60秒倒计时的调试:对深入浅出ARM7课本中的万年历源程序进行实现倒计时功能。倒计时功能实现后再添加LED的提示,即当倒计时至0时所有LED亮否则灭。同样将添加好的程序进行编译并下载到芯片,然后运行,观察开发板现象看看是否能实现所需功能。这一项相对简单,所
17、以调试过程也很快成功。2)、 校时、校分的调试:在能够实现倒计时功能的程序中添加校时校分的程序。KEY1按下计数器停止计数小时(HOUR)加1,KEY3按下计数器停止计数分钟(MIN)加1。程序添加完之后编译,编译无错之后下载到芯片,然后运行。按下KEY1或KEY3,观察是否能实现所需功能。这个过程运用到了按键,所以存在一个消抖的问题,若消抖不合理可能可能会造成按键按一下,小时或分钟可能不止加1。3)、 准点报时:在前面的程序当中添加准点报时的程序。准点报时采用的是PWM2输出15秒的音乐。先将PWM2输出音乐的程序单独调试运行,反复修改频率直至输出音乐达到最好的效果。然后将程序添加到前面的程
18、序当中。这个过程遇到了一个问题:当PWM2输出音乐的时候计数器会停止计数。说明添加不合理。将流程图重新画了一遍,再引入了一个标志位,反复修改程序并调试,直至准点报时的时候计数器仍能计数。具体见源程序。六、设计心得:在实训的这五天里,前三天老师每天上午都在讲课,我基本都听不懂,感觉自己都学得好差。下午在图书馆查找资料,形成设计思想,写出大概的程序。最后两天时间就是呆在实验室,经常忘了时间,在实验室反复修改,调试。与同学相互讨论,咨询老师。在此,我要特别感谢我的同学廖艳霞和华永金,还有指导老师涂老师,谢谢他们的指点。 通过这次实训,感觉自己的动手能力还有待提高,当然,在这次实训中,我能够独立的思考。以前摸棱两可的知识变得更加清晰了。对ARM7感觉没有没有以前那么恐怖了。这门课程的学习最主要的还是自学,终于理解师傅领进门,修行在个人着句话了。 七、参考文献:1:周立功等 深入浅出ARM7 北京航天航空出版社2: 薛钧义 微机原理与接口技术 高等教育出版社12