ARM 课程设计 南邮.docx
《ARM 课程设计 南邮.docx》由会员分享,可在线阅读,更多相关《ARM 课程设计 南邮.docx(74页珍藏版)》请在冰豆网上搜索。
ARM课程设计南邮
通信与信息工程学院
2012/2013学年第一学期
课程设计实验报告
模块名称嵌入式开发
专业电子信息工程
学生班级B090110
学生学号B09011027
学生姓名颜泽鑫
指导教师余雪勇
一、实验目的
1、熟悉基于ARM体系结构的TQ2440实验开发板。
通读实验教程,了解开发板包含的软硬件资源。
2、安装ADS1.2开发环境及串口工具,要求熟练掌握ARM的指令系统及相关资料,熟练掌握并使用ADS集成开发环境。
3、熟悉嵌入式开发的流程,学会嵌入式交叉开发环境的建立。
4、掌握基于Linux的应用程序开发步骤,学习使用Linux操作系统的常用命令。
二、实验设备及工具(包括软件调试工具)
硬件:
TQ2440嵌入式实验平台开发板、Windows系统PC机、串口线、网线、电源、USB线。
软件:
PC机操作系统、ADS1.2开发环境。
OracleVMVirtualBox虚拟机环境。
三、实验任务
1、基本要求:
根据开发板及内容选做TQ2440测试程序中的8个实验。
包括:
1:
TestPWM
2:
RTCtimedisplay
3:
TestADC
4:
Testinterruptandkeyscan
5:
TestTouchpanel
6:
TestTFTLCD
7:
TestIICEEPROM
8:
UDA1341playmusic
2、提高要求:
根据学生自己掌握知识,设计一个小应用程序,内容每个学生自己出题。
3、发挥要求:
在完成
(1)、
(2)项要求的基础上,完成具有创新内容的功能。
或做其他相关内容。
4、实验内容(包括原理、方法、步骤以及关键代码)
1、基本要求
在基本要求中,需要从11个测试程序中选做8个,以下是对8个程序的实验过程的叙述,包括实验前的硬件连接准备、软件环境配置(串口工具、dnw、ADS、交叉编译环境等)、每个实验的关键代码以及简单分析。
1.1、硬件连接
用USB线、串口线把开发板连到电脑相应的端口,再将电源线插好。
1.2、软件环境配置
设置串口工具SecureCRT
解压在“windows平台开发工具包\”目录下的“SecureCRT.rar”后,即可使用SeureCRT,
双击图标,打开SecureCRT,如下图所示:
点击图中红色方框图标,出现下图的设置窗口:
在Ptotocol里面选择Serial,出现如下图所示的对话框,详细设置参考下图,超级终端设置部分,不再重复。
注意:
Port选项部分根据您实际使用的端口进行配置,其他选项请一定配置如下图所示:
配置完毕后,点击上图的“Connect”选项即可连通串口。
DNW设置
DNW在这里是我们的.bin文件下载软件,可实现我们向flash或者内存当中烧写程序
的功能。
直接双击“Windows平台工具\DNW”目录下的DNW软件,出现下图:
1.3、实验前准备操作
1、串口工具和开发板连接成功后,将选择开关打到norflash,并按一下重启键,开发板则自动按照选择从norflash启动。
此时,如果SecureCRT界面显示如下,则表示串口工具已经工作正常:
在SecureCRT界面之中输入:
a,然后回车。
(此时即将开发板选择进入到这一种下载模式,然后用DNW配合来实现下载即可。
)选择[a]DownloadUserProgram(eg:
uCOS-IIorTQ2440_Test),就是选择了我们烧写裸奔程序所需要的下载模式。
2、打开ADS1.2(ARMDeveloperSuitev1.2,一款针对ARM的开发套件,电脑中以自带,不需要再安装),并使用ADS打开天嵌科技的出厂自带的测试程序:
测试程序在出厂附带光盘的
文件夹当中,文件格式是TQ2440_Test.mcp。
点击compile键进行编译,点击make键生成我们此处所需要的“*.bin”文件生成自己的bin文件之后,就可以使用SecureCRT配合dnw来实现对bin文件的下载了。
3、打开串口工具,使开发板从norflash启动,再串口工具中出现的信息中,选择a,进入等待下载状态;双击打开dnw,然后选择USBPort>>Transmit>>找到相应的需要烧写的bin文件,双击即可完成烧写。
4、按照以上步骤进行操作,则我们此时基本已经完成了一次完整的程序的从编译到烧写的过程了。
同时,至此天嵌的出厂测试程序已经被我们烧写到了nandflash中。
此时,我们再将选择开关打到nandflash中并重启开发板,使开发板进入我们刚刚烧写的出厂程序中,我们会看到在SecureCRT界面会出现以下信息:
<***************************************>
TQ2440TestProgram
<***************************************>
Pleaseselectfunction:
0:
Pleaseinput1-11toselecttest
1:
TestPWM
2:
RTCtimedisplay
3:
TestADC
4:
Testinterruptandkeyscan
5:
TestTouchpanel
6:
TestTFTLCD
7:
TestIICEEPROM
8:
UDA1341playmusic
9:
UDA1341recordvoice
10:
TestSDCard
11:
TestCMOSCamera
截图如下:
1.4、选做的8个实验分析
1.4.1、TestPWM,调试pwm控制蜂鸣器。
按“—”号,蜂鸣器声音频率逐渐减小,最小Freq=10;按“+”号,蜂鸣器声音频率逐渐增大,最大Freq=2000。
(加号需要按住“shift”不然是等号)。
使用ADS打开出厂程序如下:
双击,打开Main.c文件,找到while
(1)循环,在其中的CmdTip函数上面右键,Goto一下,就转到了:
struct{
void(*fun)(void);
char*tip;
}CmdTip[]={
{Temp_function,"Pleaseinput1-11toselecttest"},
{BUZZER_PWM_Test,"TestPWM"},
{RTC_Display,"RTCtimedisplay"},
{Test_Adc,"TestADC"},
{KeyScan_Test,"Testinterruptandkeyscan"},
{Test_Touchpanel,"TestTouchpanel"},
{Lcd_TFT_Test,"TestTFTLCD"},
{Test_Iic,"TestIICEEPROM"},
{PlayMusicTest,"UDA1341playmusic"},
{RecordTest,"UDA1341recordvoice"},
{Test_SDI,"TestSDCard"},
{Camera_Test,"TestCMOSCamera"},
{0,0}};
从下面struct结构当中去寻找到BUZZER_PWM_Test,并右键goto,跳转到:
voidBUZZER_PWM_Test(void)这个函数。
voidBUZZER_PWM_Test(void)
{
U16freq=800;//lci1000;
Uart_Printf("\nBUZZERTEST(PWMControl)\n");
Uart_Printf("Press+/-toincrease/reducethefrequencyofBUZZER!
\n");
Uart_Printf("Press'ESC'keytoExitthisprogram!
\n\n");
Buzzer_Freq_Set(freq);
while
(1)
{
U8key=Uart_Getch();
if(key=='+')
{
if(freq<2000)//lci20000
freq+=10;
Buzzer_Freq_Set(freq);
}
if(key=='-')
{
if(freq>11)
freq-=10;
Buzzer_Freq_Set(freq);
}
Uart_Printf("\tFreq=%d\n",freq);
if(key==ESC_KEY)
{
Buzzer_Stop();
return;
}
}
}
我们仔细地分析过这个函数之后不难发现,在我们if(key=='-')的时候没有
问题,是因为此处的减号就是我们键盘上的减号,但是,在我们很多键盘上面是
没有if(key=='+')中的这个加号的,我们要想解决这个漏洞有两个办法:
一是,
在我们调试出厂程序的时候,使用shfit加“+”号键来组合实现对于频率控制时
候的增加功能;二是,在这里直接把if(key=='='),这样就可以是我们在调试程
序的时候更加直观了。
其实仅仅是改变按键,包括频率的变化范围、变化步长都可以在这个函数中改变。
1.4.2、RTCtimedisplay调试RTC实时时钟(即RealTimeClock)。
在一个嵌入式系统中,通常采用RTC来提供可靠的系统时间,包括时分秒和年月日等;而且要求在系统处于关机状态下它也能够正常工作(通常采用后备电池供电),它的外围也不需要太多的辅助电路,典型的就是只需要一个高精度的32.768KHz晶体和电阻电容等。
实时时钟(RTC)单元可以通过备用电池供电,因此,即使系统电源关闭,它也可以继续工作。
RTC可以通过STRB/LDRB指令将8位BCD码数据送至CPU。
这些BCD数据包括秒,分,时,日期,星期,月和年。
RTC单元通过一个外部的32.768KHz晶振提供时钟。
RTC具有定时报警的功能。
RTC控制器功能说明:
时钟数据采用BCD编码能够对闰年的年月日进行自动处理具有告警功能,当系统处于关机状态时,能产生告警中断;具有独立的电源输入,提供毫秒级时钟中断,该中断可用于作为嵌入式操作系统的内核时钟。
RTC模块由以下几部分构成构成:
●闰年产生器
这个模块可以根据BCDDATA,BCDMON,以及BCDYEAR的数据决定每个月的最后日期是28,29,30还是31。
一个8位的计数器只能显示两个BCD码,因此它不能判断00年究竟是不是闰年。
例如它不能够判断1900年和2000的差别。
。
为了解决这个问题,S3C2410内的RTC模块中有一个固定的逻辑,用来支持2000年为闰年。
请注意虽然2000年是闰年,但1900年不是闰年。
因此,S3C2410中00代表2000年,而不是1900年。
●读/写寄存器
要求置高RTCON寄存器的0位来表示读和写RTC模块中的寄存器。
。
为了显示秒,分,小时,日期,月和年,CPU会从BCDSEC,BCDMIN,BCDHOUR,BCDDAY,BCDDATE,BCDMON,和BCDYEAR寄存器读取数据。
但是由于多个寄存器的读取,可能产生1秒钟的偏离。
例如,如果用户读取寄存器BCDYEAR到BCDMIN,假设结果为1959年,12月,31日,23点,59分。
在用户读取BCDSEC寄存器时,但如果结果是0,那么很有可能年,月,日,时,分已经变成了1960年1月1日0时0分了。
解决的方法是,当读取到的BCDSEC等于0时,用户应该在读取一次BCDYEAR到BCDSEC的值。
●备用电池
RTC可被备用电池驱动,备用电池通过RTCVDD引脚向RTC提供电压。
当系统掉电时,RTC与CPU之间的接口被阻塞,备用电池仅仅驱动振荡电路以及BCD计数器,这样可减少能量损耗。
●报警功能
RTC工作在掉电模式或正常工作模式时会在一个特定的时间产生报警信号。
在正常工作模式下,报警中断(ALMINT)是激活状态的。
在掉电模式下,电源管理唤醒信号(PMWKUP)与报警中断(ALMINT)都是激活状态。
RTC的报警寄存器(RTCALM)决定了报警的使能与不使能以及报警时间设定的条件。
●节拍中断
RTC节拍时间用于中断请求。
TICNT寄存器具有一个中断使能位,同时其中的计数值用于中断。
当计数值到达0时,节拍时间中断就会触发。
中断的间隔时间计算如下:
Period=(n+1)/128秒
备注n:
节拍时间计数值(1~127)
这个RTC时间节拍中断功能可以作为RTOS(实时操作系统)内核的时间节拍。
如果节拍从RTC时间节拍产生,则RTOS内部与时间相关的功能将一直与实时时钟同步。
RTC相关寄存器如下:
●RTC控制寄存器
寄存器
地址
读/写
描述
重置值
RTCCON
0x57000040(L)
0x57000043(B)
读/写
(用字节)
RTC控制寄存器
0x0
RTCCON
位
描述
初始状态
CLKRST
[3]
RTC时钟计数重置。
0=没重置,1=重置
0
CNTSEL
[2]
BCD计数重置。
0=合并BCD计数器
1=保留(单独的BCD计数器)
0
CLKSEL
[1]
BCD时钟选择。
0=XTAL1/(2的15次方)分开的时钟
1=保留(XTAL时钟只用于测试)
0
RTCEN
[0]
RTC控制使能。
0=失能,1=使能
注意:
只有BCD时间计数和读取操作可以被执行。
0
●实时时钟计数器(TICNT)
寄存器
地址
读/写
描述
重置值
TICNT
0x57000044(L)
0x57000047(B)
读/写
(用字节)
实时时钟计数器
0x0
TICNT
位
描述
初始状态
TICKINTENABLE
[7]
实时时间中断使能。
0=失能,1=使能
0
TICKTIMECOUNT
[6:
0]
实时时间计数值(1~127)。
这个计数器的值在内部减少,用户不能在工作时读取这个计数器的值。
000000
●RTC报警控制寄存器(RTCALM)
RTC报警控制寄存器决定了报警使能以及报警时间。
注意,RTCALM寄存器在掉电模式下会通过ALMINT以及PMWKUP产生报警信号,但在正常模式下只在ALMINT产生报警信号。
寄存器
地址
读/写
描述
重置值
RTCALM
0x57000050(L)
0x57000053(B)
读/写
(用字节)
RTC报警控制寄存器
0x0
RTCALM
位
描述
初始状态
保留
[7]
0
ALMEN
[6]
警报全球使能。
0=失能,1=使能
0
YEAREN
[5]
年报警使能。
0=失能,1=使能
0
MONREN
[4]
月报警使能。
0=失能,1=使能
0
DATEEN
[3]
数据报警使能。
0=失能,1=使能
0
HOUREN
[2]
小时报警使能。
0=失能,1=使能
0
MINEN
[1]
分钟报警使能。
0=失能,1=使能
0
SECEN
[0]
秒钟报警使能。
0=失能,1=使能
0
●报警时间秒数寄存器(ALMSEC)
寄存器
地址
读/写
描述
重置值
ALMSEC
0x57000054(L)
0x57000057(B)
读/写
(用字节)
报警时间秒数寄存器
0x0
ALMSEC
位
描述
初始状态
保留
[7]
0
SECDATA
[6:
4]
BCD值对于报警时间秒数。
0~5
000
[3:
0]
0~9
0000
●报警时间分钟数寄存器(ALMMIN)
寄存器
地址
读/写
描述
重置值
ALMMIN
0x57000058(L)
0x5700005B(B)
读/写
(用字节)
报警时间分钟数寄存器
0x00
ALMMIN
位
描述
初始状态
保留
[7]
0
MINDATA
[6:
4]
BCD值对于报警时间分钟数。
0~5
000
[3:
0]
0~9
0000
●报警时间小时数寄存器(ALMHOUR)
寄存器
地址
读/写
描述
重置值
ALMHOUR
0x5700005C(L)
0x5700005F(B)
读/写
(用字节)
报警时间小时数寄存器
0x0
ALMHOUR
位
描述
初始状态
保留
[7:
6]
00
HOURDATA
[5:
4]
BCD值对于报警时间小时数。
0~2
00
[3:
0]
0~9
0000
●报警时间天数寄存器(ALMDATE)
寄存器
地址
读/写
描述
重置值
ALMDATE
0x57000060(L)
0x57000063(B)
读/写
(用字节)
报警时间天数寄存器
0x01
ALMDAY
位
描述
初始状态
保留
[7:
6]
00
DATEDATA
[5:
4]
BCD值对于报警时间天数,从0到28,29,30,31。
0~3
00
[3:
0]
0~9
0001
●报警时间月数寄存器(ALMMON)
寄存器
地址
读/写
描述
重置值
ALMMON
0x57000064(L)
0x57000067(B)
读/写
(用字节)
报警时间月数寄存器
0x01
ALMMON
位
描述
初始状态
保留
[7:
5]
00
MONDATA
[4]
BCD值对于报警时间月数。
0~1
0
[3:
0]
0~9
0001
●报警时间年数寄存器(ALMYEAR)
寄存器
地址
读/写
描述
重置值
ALMYEAR
0x57000068(L)
0x5700006B(B)
读/写
(用字节)
报警时间年数寄存器
0x0
ALMYEAR
位
描述
初始状态
YEARDATA
[7:
0]
BCD值对于报警时间年数。
00~99
0x0
●秒,分,时,天,月,年寄存器(BCD码格式)
双击“main.c”,在Main.c代码的第38-49行(行数显示在Main.c编辑窗口的左下角)有以下代码:
externvoidLcd_TFT_Init(void);
externvoidLcd_TFT_Test(void);
externvoidTest_Touchpanel(void);
externvoidTest_Adc(void);
externvoidKeyScan_Test(void);
externvoidRTC_Display(void);
externvoidTest_IrDA_Tx(void);
externvoidPlayMusicTest(void);
externvoidRecordTest(void);
externvoidTest_Iic(void);
externvoidTest_SDI(void);
externvoidCamera_Test(void);
函数外部声明的作用是:
使不同文件之间,可以调用同一工程中的其他文件里面的函数。
在externvoidRTC_Display(void)上右击“goto”显示“RTC.c”代码如下:
voidRTC_Display(void)
{
U16year;
U8month,day;//week
U8hour,minute,second;
RTC_Time_Set();
Uart_Printf("\nRTCTIMEDisplay,pressESCkeytoexit!
\n");
while(Uart_GetKey()!
=ESC_KEY)
{
rRTCCON=1;//RTCreadandwriteenable
year=0x2000+rBCDYEAR;//年
month=rBCDMON;//月
day=rBCDDATE;//日
//week=rBCDDAY;//星期
hour=rBCDHOUR;//小时
minute=rBCDMIN;//分
second=rBCDSEC;//秒
rRTCCON&=~1;//RTCreadandwritedisable
Uart_Printf("RTCtime:
%04x-%02x-%02x%02x:
%02x:
%02x\n",year,month,day,hour,minute,second);
Delay(900);
}
}
根据RTC实现原理,不难分析实时时间获取就是获取BCD码数据。
在SecureCRT窗口选择2,调试RTC实时时钟(即RealTimeClock):
RTCTIMEDisplay,pressESCkeytoexit!
RTCtime:
2008-11-0712:
00:
00
RTCtime:
2008-11-0712:
00:
01
RTCtime:
2008-11-0712:
00:
02
RTCtime:
2008-11-0712:
00:
03
……
时钟会按照每一秒钟为周期,准时的+1。
1.4.3、TestADC调试ADC实验。
2440内部ADC结构图如下:
我们从上面的结构图和数据手册可以知道,该A