嵌入式综合实验_第1页
嵌入式综合实验_第2页
嵌入式综合实验_第3页
嵌入式综合实验_第4页
嵌入式综合实验_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验四综合实验设计一、 实验目的通过熟悉MagicARM2410实验箱各模块的功能,再结合自己所学的专业知识以及各模块的程序设计方法,设计一个综合实验。二、 实验要求设计一个综合实验,要求通过键盘改变控制直流电机的转速,同时通过RTC和UART模块,在PC机超级终端处显示步进机转速的级别以及时间。在此实验中包括了UART、定时器中断、RTC、键盘LED数码管显示、直流步进电机等模块。三、 实验设计思路本实验通过设计一个控制LED数码管显示并接收键盘输入的主程序,在主程序中通过键盘输入调用直流电机中控制转速的子程序,不同的键值输入对应不同的直流电机转速。并且在改变转速的同时,通过调用RTC和UART模块,分别向PC机发送时间和转速的级别。因此关键是设计好主程序,解决好各调用子程序之间的矛盾和冲突,使他们可以很好的共存。实验框图如下:'键盘输入] 〉改变转速 I 二发送时间至II]、 1—r- 1-| J PC上显示LED数码管 发送转速到显示电机模式 PC上显示直流电机的转速改变是通过改变电压来完成的,电压越大,直流电机的转速越快,而不同电压所需要的占空比是不一样的,本实验就是通过改变占空比来实现不同电压的转变,从而控制直流电机的转速。四、实验程序由于实验程序比较长,现只将实验的主程序的main函数表示出来,其他调用程序见附件一。voidmain(void){inti,j;inttemp;uint16key;disp_buf0[0]=0;disp_buf1[0]=1;disp_buf2[0]=2;disp_buf3[0]=3;//直流电机初始化设置//TOUT0口设置rGPBCON=(rGPBCON&(〜(0x03<<0)))I(0x02<<0);//rGPBCON[1:0]=10b,设置TOUT0功能rGPBUP=rGPBUPI0x0001;//禁止TOUT0口的上拉电阻//设置GPH9为GPIO输出模式rGPHCON=(rGPHCON&(〜(0x03<<18)))I(0x01<<18); //GPH9口rGPHDAT=rGPHDAT&(〜(1<<9));//输出0电平rGPHUP=rGPHUPI(1<<9);//GPIO设置rGPACON=rGPACON&(〜(1<<21)); //A口,RUN灯控制口(GPA21)rGPHCON=(rGPHCON&(〜(0x03<<20)))I(0x01<<20); //rGPHCON[21:20]=01b,设置GPH10为I/O输出模式//设置中断服务程序VICVectAddr[10]=(uint32)IRQ_Time0; //定时中断向量地址设置VIC旋ctAddr[4]=(uint32)IRQ_Eint4; //外部中断向量地址设置//设置中断控制器PRIORITY=0x00000000; //使用默认的固定的优先级rINTMOD=0x00000000; //所有中断均为IRQ中//GPIO设置rGPACON=rGPACON&(〜(1<<21)); //A口,RUN灯控制口(GPA21)rGPHCON=(rGPHCON&(〜(0x03<<20)))I(0x01<<20);//rGPHCON[21:20]=01b,设置GPH10为I/O输出模式//初始化I2C接口InitI2C();rINTMSK=0xFFFFFBEF;//使能EINT4中断rEINTMASK=〜0x0000010;//控制LED数码管显示while(i==0){for(j=0;j<1;j++)disp_buf[j]=i;ZLG7290_SendBuf((uint8*)disp_buf,8);DelayNS(10);}//读取按键,设置键值对应的显示位闪烁while(1){DelayNS(1);key=ZLG7290_GetKey();if((key&0xFF00)==0){key=key&0x00FF;}switch(key){case1:ZLG7290_SendBuf((uint8*)disp_buf0,1);PWM_Init(255,255/4);//以1/4占空比改变直流电机的转速UART_SendStr(直流电机以spee1运行\n");DelayNS(20);//延时RTC_Init(0); //初始化RTC(非强行方式)RTC_Read(1);//读日期temp=0;{while(temp==rBCDSEC);break;case2:ZLG7290_SendBuf((uint8*)disp_buf1,1);PWM_Init(255,2*255/4);//以2/4占空比改变直流电机的转速UART_SendStr(直流电机以speed2运行\n");DelayNS(20);//延时RTC_Init(0);//初始化RTC(非强行方式)RTC_Read(1);//读日期temp=0;{while(temp==rBCDSEC);temp=rBCDSEC;RTC_Read(0);//读时间DispRTC();//输出时间显示}break;case3:ZLG7290_SendBuf((uint8*)disp_buf2,1);PWM_Init(255,3*255/4);//以3/4占空比改变直流电机的转速UART_SendStr(直流电机以speed3运行\n");DelayNS(20);//延时RTC_Init(0);//初始化RTC(非强行方式)RTC_Read(1);//读日期temp=0;{while(temp==rBCDSEC);break;case4:ZLG7290_SendBuf((uint8*)disp_buf3,1);PWM_Init(255,4*255/4);〃使直流电机全占空比停止转动UART_SendStr(直流电机停止运行\n");DelayNS(20);//延时RTC_Init(0);//初始化RTC(非强行方式)RTC_Read(1);//读日期temp=0;{while(temp==rBCDSEC);temp=rBCDSEC;RTC_Read(0); //读时间DispRTC(); //输出时间显示}break;default:break;}//endofswitch(key)...}}五、实验步骤:启动ADS1.2IDE集成开发环境,选择【File]->【New…】,使用ARMExecutableImage工程模板建立一个工程,名称为qiub,目录为D:\arm\myproject\qiub0选择【File]->【New…】建立一个新的文件main.c,设置直接添加到项目中,在Targets一栏中选择Debug.输入主程序的程序代码,并保存,此时在工程窗口中可以看到main.c文件。打开所建的工程,选择ADDFlies,向该工程添加实验所需要的各个模块,如图所示:

瞪qiub.mcp |1=1||回1□[蛾司始守修*A0LinkOrderT:±t-gets|啰 File CodeData暮芸-1^3head 0 0 • 旦Dconfig.h 0 0 * 工]Gth 0 0 * Eg]S3C2410.h 0 0 . 二]啰startup 0 0 * * ^1叶 防StartUF.e 0 0 • *曜- Qtarget 0 Cl ♦ ♦ =1曜 目。c 0 0 * ♦ 可啰-'-urLEule 0 0 • ,可P-9u:di-+.h | o| o* p轿 心 c 0 0* ♦可啰-£3IM也「已 0 0•,fGIcdiirive.h 0 0* 二]啰 心Icdilrive.c 0 0• ,可♦ - 0 0 * •工]曜 、置bliss.c 0 0* ♦可啰-taI£C o o • •旦g]I2C.h 0 0 , 工]轿 £1 I2C-c 0 0 * •二]g]zlg7290.h 0 0 • 司常 Q -lgT290.c 0 0 * •司叶-句* 0 0 • •/ 心 main,c 0 0 * ♦F15files 0 0工程文件添加完毕后保存,然后选择【Project!->【Make】,将编译链接整个工程。如果有错误按照错误提示栏提示的错误进行修改,直到链接正确。打开JTAG仿真器软件,并且在电脑开始菜单找到附件一>数据通讯一>超级终端;打开超级终端,设计超级终端的参数,用于观察数据的接收。选择【Project!->[Debug],IDE环境就会启动AXD调试软件,如果首次运行要记得加载初始化文件ARM2410.txt,初试完毕后,可以执行单步或全速运行调试。全速运行后,改变键盘上的键值从0键到3键,观察直流电机的转速改变情况以及超级终端的数据接受情况。六、实验结果及分析通过改变键盘的输入值,直流电机的转速发生改变,当键盘按下0键时,LED数码上显示1,代表直流电机以1/4占空比模式运行,同时可以从超级终端处观察到发送来的数据“直流电机以speel运行”,后面紧接着显示时间如图1所示。同样按下键1和键2时可以分别看到LED数码上显示2和3,他们分别代表直流电机以2/4占空比模式运行和3/4占空比模式运行。在接收端可以从

超级终端分别观察到“直流电机以speed2运行”和“直流电机以speed3运行”后面紧跟着的是他们开始旋转的时间。当按下键3时,LED数码上显示4,表示直流电机切换到全占空比模式,即直流电机停止转动,此时可以从超级终端收到“直流电机停止运行”以及开始停止的时间。通过观察得知直流电机的转速与占空比有关,当占空比小于1时,且逐渐增大时,直流电机的转速越来越快,也就是speed1<speed2<speed3;实验截图如下:文件⑤编辑(£)查看世)呼叫(£)传送如)帮助电)□务福珍如S曾直流电机以speel运行20:57:46 Tuesday, 1/10/2006直流电机以speed3运行20:57:49 Tuesday, 1/10/2006直流电机以speed2运行20:57:51 Tuesday, 1/10/2006直流电机停止运行20:57:53 Tuesday, 1/10/2006直流电机以speel运行120:57:58 Tuesday,1/10/2006直流电机以speed2运行 |20:57:59 Tuesday, 1/10/2006直流电机停止运行20:58:01 Tuesday, 1/10/2006直流电机以speel运行20:58:03 Tuesday, 1/10/2006直流电机以speel运行20:58:04 Tuesday, 1/10/2006直流电机以speel运行20:58:06 Tuesday, 1/10/2006直流电机以speed2运行20:58:07 Tuesday, 1/10/2006直流电机以speed3运行20:58:09 Tuesday, 1/10/2006直流电机以speed2运行20:58:11 Tuesday, 1/10/2006直流电机以speed2运行9HSR-12 TiiP<?rlAu 1 I从截图可以看出各个模式之间可以通过按下不同的键值相互跳转,如果没有其他键按下要求跳转,则直流步进电机一直以该模式运行。七、实验心得:(一)本次实验虽然只是一个小型的综合性实验,但是对于我这么一个初次接触嵌入式的人来说,还是遇到了很多困难。首先在硬件方面上感到很吃力,很多以前学过的东西都忘了,比如中断的优先级,以及各寄存器的组织结构等,加上ARM本身复杂的体系结构,使得我不得不一边操作一边学习,遇到哪里不懂的,就去翻书找相应的知识,或到网上去找相关资料。其次是软件方面的知识还很欠缺,虽然以前学习过C语言,以及汇编语言,但好久没有用过,很多指令都忘了,加上ARM本身的指令集,要想自己真正编写一个完整的程序显得是那么困难。幸好实验室有很多已经编好的实验程序模板,我可以参照上面的实验程序,通过一些修改,达到实现所要的功能。如果没有那些源程序,我想我可能会遇到更多的问题。我知道自己还停留在初级水平,甚至连初级水平都没有达到,因为嵌入式所需要的知识很广,很全,而你必须在各个方面都很熟悉,才能得心应手。还有经验很重要,对于我们初学者来说,最缺乏的就是经验,获取经验的最好的方法就是学习那些已经编好的实验模板,因为那些模板是经验的总结,那正是我们所要需要的。通过不断的学习他人的实验成果,才能不断的积累,当积累经验到一定的程度的时候,你就可以得心应手的实现自己想要实现的各个功能,那时你就可以有自己的东西,可以有自己的创新。(二) 在设计这个实验的过程中,主要经历三个过程:构思,设计,调试。首先是想怎么把各个实验综合到一起,实现各个模块的功能,同时又要有一定的实际意义。经过反复斟酌决定采用键盘控制直流电机的转速,同时输出转速级别以及转速改变的时间,这样就把实验要求的各个模块基本都整合到一起了。初步思路出来了以后,就是开始设计主程序了,这一阶段花了很多时间。因为自己是第一次设计程序,很多东西不是很了解,所以必须先学习一些例子,了解程序设计的一些基本原则。我把实验室电脑中MagicARM2410光盘的基础实验的各个程序仔细研究了一下,同时也熟悉了各个功能模块功能实现的原理,这也为我后面程序设计提供了一种参考。有了这些准备工作,就是开始设计自己的实验程序,通过不断的添加和修改,再经过编译,确定没有问题了保存好工程文件。最后就是调试了,这是最关键的一步,也是最繁琐的一步,同时也是学东西最多的一个阶段。我们不可能设计程序出来了就一点问题都没有,很多时候都是通过一步步调试,不断的修改,一个个问题的解决,才能最终成功。我的也不例外,一开始时什么功能都不能实现,那时真的很失落,很受打击。但我告诉自己,必须耐心的调试,才有可能成功。我通过单步运行,观察程序的运行,分析模块的功能不能实现的原因,一个一个模块单独调试。在调试的过程中运到了很多问题,比如模块之间共用相同寄存器而带来的冲突以及寄存器的某些功能没有开启或是关闭了等。这些问题很多都是通过回过头去研究实验模板的设计,再结合英文的s3c2410.pdf文件的介绍,了解各寄存器的初始化以及寄存器每位所代表的功能来解决的。当这些问题都解决了,实验朝着理想的方向前进,很多功能都能实现了。此时先前的挫败感,一下就消失了,那种调试成功的喜悦是无法用言语来表达的。调试过程是一个很磨砺人的一个过程,在反复失败的时候还要继续尝试,这是很痛苦的。很多人就是因为不能承受折磨而最终放弃了,而成功就是建立在无数次失败之上的,快乐也是建立在痛苦之上的,只有经历了那个过程的点点滴滴,才能体会成功的那份喜悦。(三) 在此次实验中,我还遇到了一些不知道怎么解释的问题,比如说我改变了输出的字符时,整个实验程序就不能正常运行,pc机上也不能接受发送的数据,而当我改回来时,程序又能正常运行。还有就是当我打开定时中断时,按下某一键时,程序不能跳转了,一直停留在此,好像死机了一样。而当卧关闭定时中断时,程序又可以正常运行。我猜这可能与直流电机中的定时器0有冲突或是共用了定时器0才导致了这样。(四) 这次实验让我学到了很多东西,懂得了实验要付出很多艰辛的努力,而所有的这些努力都是值得的。它不仅提升了你的动手能力、学习能力,分析问题和解决问题的能力,同时也教会了我如何学习,如何查找资料。这些东西在课本上是学不到的,你必须自己亲自通过实验这个过程来体验感知。实验过程的点点滴滴都将是我们日后学习、工作的一笔宝贵的财富。附件一实验主程序#include"config.h//定义显示缓冲区chardisp_buf[50];chardisp_buf0[10];chardisp_buf1[10];chardisp_buf2[10];chardisp_buf3[10];//ZLG7290控制LED数码管闪烁命令#defineGlitter_COM0x70//定义当前时间变量uint8g_year=0;uint8g_month=0;uint8g_date=0;uint8g_day=0;uint8g_hour=0;uint8g_min=0;uint8g_sec=0;//定义星期字符串char*str_day[8]={"","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};//定义初始化时钟值#defineINIT_YEAR0x11/*2011年*/#defineINIT_MONTH0x05/*5月*/#defineINIT_DATE0x21/*21日*/#defineINIT_DAY0x06/*星期六*/#defineINITHOUR0x09/*20时*/#defineINITMIN0x30/*30分*/#defineINITSEC0x00/*0秒*///延时voidDelayNS(uint32dly){uint32i;for(;dly>0;dly--)for(i=0;i<50000;i++);}//RTC初始化voidRTC_Init(intforce){interr;uint32bak;//判断当前RTC是否正确运行err=0;if(force==0) //若force为0,则判断当前时钟是否正确{rRTCCON=0x00; //禁止RTC接口(只允许RTC计数和读数)bak=rBCDYEAR&0xFF;if(bak>0x99)err++; //年判断bak=rBCDMON&0x1F;if(bak>0x12)err++; //月判断bak=rBCDDATE&0x3F;if(bak>0x31)err++; //日判断bak=rBCDHOUR&0x3F;if(bak>0x24)err++; //时判断bak=rBCDMIN&0x7F;if(bak>0x59)err++; //分判断bak=rBCDSEC&0x7F;if(bak>0x59)err++; //秒判断if(err==0)return;//若时钟正确,则直接返回}rRTCCON=0x01; //标准模式,RTC接口使能(允许写)rBCDYEAR=INIT_YEAR&0xFF;rBCDMON=INIT_MONTH&0x1F;rBCDDATE=INIT_DATE&0x3F;rBCDDAY=INIT_DAY&0x07;//星期,MON:1TUE:2WED:3THU:4FRI:5SAT:6SUN:7rBCDHOUR=INIT_HOUR&0x3F;rBCDMIN=INIT_MIN&0x7F;rBCDSEC=INIT_SEC&0x7F;rRTCCON=0x00; //禁止RTC接口(只允许RTC计数和读数)}//读时间voidRTC_Read(uint32date){if(date){g_year=rBCDYEAR;g_month=rBCDMON;g_date=rBCDDATE;g_day=rBCDDAY;}g_hour=rBCDHOUR;g_min=rBCDMIN;g_sec=rBCDSEC;}〃显示时间voidDispRTC(void){sprintf(disp_buf,"%02x:%02x:%02x%10s,%2x/%2x/20%02x\n",g_hour,g_min,g_sec,str_day[g_day],g_month,g_date,g_year);UART_SendStr(disp_buf);}//初始化PWM定时器voidPWM_Init(uint16cycle,uint16duty)if(duty>cycle)duty=cycle; //参数过滤//设置定时器0,即PWM周期和占空比//Fclk=200MHz,时钟分频配置为1:2:4,艮口Pclk=50MHz。rTCFG0=97; //预分频器0设置为98,取得510204HzrTCFG1=0; //TIMER0再取1/2分频,取得255102HzrTCMPB0=duty;//设置PWM占空比rTCNTB0=cycle;//定时值(PWM周期)if(rTCON&0x04)rTCON=(1<<1); //更新定时器数据(取反输出inverter位)elserTCON=(1<<2)|(1<<1);rTCON=(1<<0)|(1<<3); //启动定时器}//外部中断初始化voidEINT_init(void){rGPFCON=(rGPFCON&0xFFFFFCFF)|(0x02<<8); //设置GPF4引脚为外部中断EINT4功能rEXTINT0=(0x2<<16); //外部中断EINT4设置为下降沿触发rINTMSK=rINTMSK&(〜(1<<1)); //使能EINT4中断rEINTMASK=〜0x0000010;}〃中断服务程序voidIRQ_Eint4(void){inti;inttemp;//按键去抖动rGPFCON=rGPFCON&(〜(0x03<<8));//设置为GPIO输入方式for(i=0;i<10000;i++); //延时去抖动if(rGPFDAT)//若是假按键,则直接退出rGPFCON=rGPFCONI(0x02<<8);//设置回EINT4中断口//清除中断标志rEINTPEND=(1<<4);rSRCPND=(1<<4);rINTPND=rINTPND;return;}rGPFCON=rGPFCON|(0x02<<8); //设置回EINT4中断口//执行串口发送数据UART_Select(0); //选择UART0UART_Init(); //初始化UART0UART_SendStr("stoptime\n");RTC_Init(0);//初始化RTC(非强行方式)RTC_Read(1); //读日期temp=0;while(temp==rBCDSEC);temp=rBCDSEC;RTC_Read(0);//读时间DispRTC(); //输出时间显示//清除中断标志rEINTPEND=(1<<4);rSRCPND=(1<<4);rINTPND=rINTPND;}//定时器1初始化voidIRQ_TimInit(void)

//Fclk=200MHz,时钟分频配置为1:2:4,艮口Pclk=50MHz。//rTCFG0=255; ////rTCFGl=3;rTCMPBl=0x0000; //rTCFG0=255; ////rTCFGl=3;rTCMPBl=0x0000; //rTCNTB1=255102; //rTCON=(1<<8);rTCON=(1<<7)|(1<<10);IRQEnable(); ////TIMER0再取1/4分频,取得50KHz设置定时器为0定时1秒//更新定时器数据//启动定时器使能IRQ中断(CPSR)//定时中断服务程序voidIRQ_Time0(void)//voidIRQ_Time0(void){inti;UART_Select(0); //选择UART0UART_Init(); //初始化UART0DelayNS(50);for(i=0;i<10;i++){UART_SendStr("continuetime!\n");}//清除中断标志rSRCPND=1<<10;rINTPND=rINTPND;}//主函数voidmain(void)inti,j;inttemp;uint16key;disp_buf0[0]=0;disp_buf1[0]=1;disp_buf2[0]=2;disp_buf3[0]=3;//直流电机设置//TOUT0口设置rGPBCON=(rGPBCON&(〜(0x03<<0)))|(0x02<<0); //rGPBCON[1:0]=10b,设置TOUT0功能rGPBUP=rGPBUPI0x0001; //禁止TOUT0口的上拉电阻//设置GPH9为GPIO输出模式rGPHCON=(rGPHCON&(〜(0x03<<18)))I(0x01<<18);//GPH9口rGPHDAT=rGPHDAT&(〜(1<<9)); //输出0电平rGPHUP=rGPHUPI(1<<9);设置GPH10为I/O输出模式//设置中断服务程序VICVectAddr[10]=(uint32)IRQ_Time0; //定时中断向量地址设置VICVectAddr[4]=(uint32)IRQ_Eint4;//外部中断向量地址设置//设置中断控制器rPRIORITY=0x00000000; //使用默认的固定的优先级rINTMOD=0x00000000; //所有中断均为IRQ中断//GPIO设置rGPACON=rGPACON&(〜(1<<21)); //A口,RUN灯控制口(GPA21)rGPHCON=(rGPHCON&(〜(0x03<<20)))I(0x01<<20); //rGPHCON[21:20]=01b,设置GPH10为I/O输出模式//初始化I2C接口InitI2C()//使能EINT4中断//使能EINT4中断rEINTMASK=~0x0000010;//显示while(i==0){for(j=0;j<1;j++)disp_b

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论