通信工程专业课程设计.docx
《通信工程专业课程设计.docx》由会员分享,可在线阅读,更多相关《通信工程专业课程设计.docx(28页珍藏版)》请在冰豆网上搜索。
![通信工程专业课程设计.docx](https://file1.bdocx.com/fileroot1/2023-1/3/dcf10547-baf2-4e06-aa92-0a8f392f5fcc/dcf10547-baf2-4e06-aa92-0a8f392f5fcc1.gif)
通信工程专业课程设计
通信工程专业课程设计
实验报告
——带有LED指示的图片播放器
组员:
姓名:
蒋跃
学号:
1004220129
姓名:
陈奇
学号:
1004220120
指导教师:
陈文武
完成日期:
2013.10.18
目录
1、实验目的......................................3
2、实验原理......................................3
3、实验设备......................................3
4、设计思想与功能简介............................3
5、总体设计方案..................................4
6、主要模块实现方案..............................4
1.矩阵键盘模块.................................4
2.LCD显示模块.................................11
3.LED显示模块.................................16
7、整体效果图...................................20
8、实验结论.....................................23
9、实验总结.....................................23
10、参考文献.....................................24
一、实验目的
随着信息化技术的发展,嵌入式系统已经成为当前IT产业界一个非常热门的话题。
嵌入式系统主要由嵌入式处理器、相关支撑硬件和嵌入式软件系统组成,它是集软硬件于一体的可独立工作的“器件”。
总体看来,嵌入式系统具有便利灵活、性能价格比高、嵌入性强等特点,可以嵌入到现有任何信息家电和工业控制系统中。
从软件角度来看,嵌入式系统具有不可修改性、系统所需配置要求较低、系统专业性和实时性较强等特点。
为此我们开展基于SEP3203的通信工程专业课程设计以实现以下目的:
1、通过实验,接触目标开发板、集成开发环境的构建方式和作业方式;
2、通过实验,了解嵌入式系统的硬件和软件、JTAG调试方法,学会如何从头开始着手开发一个嵌入式系统;
3、增加交叉编译、目标板程序调试和加载的真知;积累嵌入式系统开
发流程、开发方法和开发技巧的经验。
通过整个实验流程最终增强实践能力,达到对所学知识的巩固,在实践中
加深对嵌入式软件开发的体会。
二、实验原理
1.通过键盘按键判断的工作原理和方法,利用UCB1400的控制方法,实现按键控制切换;
2.基于LCD的物理特性和工作原理及ARM7TDMI内核LCD控制器的工作原理,设计液晶显示文本及图形的方法与程序;
3.基于LED的工作原理和控制方法及74HC595移位寄存器的使用,实现键控与LED指示的结合;
4.掌握SEP3203GPIO口的配置和读写方法。
三、实验设备
1.硬件:
HOST机一台、调试器一台、ARM实验平台一套。
2.软件:
WIN98或2000操作系统、ADS或SDT开发环境、调试器驱动程序ICE、键控LCD与LED范例源程序。
四、设计思想与功能简介
设计思想的最初来源是对于图片和幻灯片的播放,并且利用LED动态的显示与图片匹配的日期或编号或其他信息。
通过对实验功能的整合,现取以下两个功能实例展示程序的功能:
1、通过键盘按键控制LCD液晶显示屏切换图片,实现播放。
2、达到播放同时在LED数码管上实时显示图片编号。
3、文字提示信息:
当播放成功时会同时显示LCD、LED功能实现成功,在信息提示框中同时显示按键号码、图片号码,当所按按键无图片时会提示“无图片”信息。
4、程序采用模块并列模式,易于扩展图片数量与LED指示,便于动态添加,这正是播放设备的基本需要。
五、总体设计方案
本系统基于SEP3203微处理器,ARM7TDMI内核,主要由矩阵键盘模块、LCD模块、LED模块等部分组成。
系统的总体框图如下:
矩阵键盘模块
LED指示模块
LCD播放模块
六、主要模块实现方案
1.矩阵键盘模块
1.1按键位置的确定
本系统采用矩阵键盘,矩阵键盘有两种驱动方式,一种是行扫描法,另一种是高低电平翻转法。
本系统采用了行扫描法。
包括两个步骤:
判断键盘中是否有键按下:
将全部行线置为低电平,然后检测列线的状态。
只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平与4根行线相交叉的4个按键之中。
若所有列线均为高电平,则键盘中无键按下。
判断闭合键所在的位置:
在确认有键按下后,即可进入确定具体闭合键的过程。
方法是:
依次将行线置为低电平,即在置某根行线为低电平时,其他线为高电平。
在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。
若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
1.2键盘中断
键盘实验的主函数流程如下图所示:
上述的循环等待过程可由按键中断打断,执行相应的键盘中断函数。
键盘中断服务流程可以由下图表示:
1.3实验代码
实验代码主要由三个部分的函数组成:
顶层实现函数,硬件设置函数,中断服务函数。
1.3.1顶层实现函数
voidKeyBoardModule(void);
键盘实验的顶层函数,实现系统初始化及键盘初始化。
1.3.2硬件设置函数
voidkeyboardinit(void);
该函数实现了键盘的初始化。
主要调用InitAC97()和int15init(),完成UCB1400初始化及GPIO口的配置。
voidint15init(void);
GPIO口的配置函数。
voidInitAC97(void);
UCB1400的初始化配置函数。
voidwucb(U32addr,U32val);
通过向AC97CRC寄存器中写入,配置UCB1400的各寄存器值,该函数用来被查找按键函数调用。
U32rucb(U32addr);
通过读出AC97CRC寄存器值,获得UCB1400的各寄存器值,该函数用来被查找按键函数调用。
1.3.3中断服务函数
voidkeyhandler(void);
键盘中断处理函数,调用findkey()函数来查找并显示键号。
中断处理函数的流程如下图所示。
voidfindkey(void);
查找按键的函数,用于求出被按下按键的键号并打印出来,该函数被键盘处理中断调用。
1.4键盘中断相关代码如下:
voidkey_handler(void)
{
U32tmp_int_status;
U32i;
U8key;
char*s;
*(RP)INTC_IMSK=0xffffffff;
tmp_int_status=*(RP)INTC_ISTAT;
for(i=0;i<10000;i++);
if(tmp_int_status==0x20)
{//int4
/*************setY3,Y2,Y1={1,1,0},configGPIO*************/
*(RP)PORTE_DATA|=0x00e0;
*(RP)PORTE_INTRCLR=0xffff;
*(RP)PORTE_DATA&=0xffc3;
for(i=0;i<5000;i++);
if(*(RP)INTC_ISTAT==0x20)
{
key=1;
*(RP)PORTE_DATA&=0xff1f;
for(i=0;i<100;i++);
*(RP)PORTE_INTRCLR|=0x10;
*(RP)INTC_IMSK=0;
}
/*************setY3,Y2,Y1={1,0,1},configGPIO*************/
*(RP)PORTE_DATA|=0x00e0;
*(RP)PORTE_INTRCLR=0xffff;
*(RP)PORTE_DATA&=0xffa3;
for(i=0;i<5000;i++);
if(*(RP)INTC_ISTAT==0x20)
{
key=4;
*(RP)PORTE_DATA=0x0;
for(i=0;i<100;i++);
*(RP)PORTE_INTRCLR|=0x8;
*(RP)INTC_IMSK=0;
}
/*************setY3,Y2,Y1={0,1,1}},configGPIO*************/
*(RP)PORTE_DATA|=0x00e0;
*(RP)PORTE_INTRCLR=0xffff;
*(RP)PORTE_DATA&=0xff63;
for(i=0;i<5000;i++);
if(*(RP)INTC_ISTAT==0x20)
{
key=7;
*(RP)PORTE_DATA=0x0;
for(i=0;i<100;i++);
*(RP)PORTE_INTRCLR|=0x4;
*(RP)INTC_IMSK=0;
}
}
elseif(tmp_int_status==0x10)
{
/*************setY3,Y2,Y1={1,1,0},configGPIO*************/
*(RP)PORTE_DATA|=0xe0;
*(RP)PORTE_INTRCLR=0xffff;
*(RP)PORTE_DATA&=0xffc3;
for(i=0;i<5000;i++);
if(*(RP)INTC_ISTAT==0x10)
{
key=2;
*(RP)PORTE_DATA=0x0;
for(i=0;i<10000;i++);
*(RP)PORTE_INTRCLR|=0x10;
*(RP)INTC_IMSK=0;
}
/*************setY3,Y2,Y1={1,0,1},configGPIO*************/
*(RP)PORTE_DATA|=0x00e0;
*(RP)PORTE_INTRCLR=0xffff;
*(RP)PORTE_DATA&=0xffa3;
for(i=0;i<5000;i++);
if(*(RP)INTC_ISTAT==0x10)
{
key=5;
*(RP)PORTE_DATA=0x0;
for(i=0;i<100;i++);
*(RP)PORTE_INTRCLR|=0x8;
*(RP)INTC_IMSK=0;
}
/*************setY3,Y2,Y1={0,1,1}},configGPIO*************/
*(RP)PORTE_DATA|=0x00e0;
*(RP)PORTE_INTRCLR=0xffff;
*(RP)PORTE_DATA&=0xff63;
for(i=0;i<5000;i++);
if(*(RP)INTC_ISTAT==0x10)
{
key=8;
*(RP)PORTE_DATA=0x0;
for(i=0;i<100;i++);
*(RP)PORTE_INTRCLR|=0x4;
*(RP)INTC_IMSK=0;
}
}
elseif(tmp_int_status==0x8)
{
/*************setY3,Y2,Y1={1,1,0},configGPIO*************/
*(RP)PORTE_DATA|=0x00e0;
*(RP)PORTE_INTRCLR=0xffff;
*(RP)PORTE_DATA&=0xffc3;
for(i=0;i<5000;i++);
if(*(RP)INTC_ISTAT==0x8)
{
key=3;
*(RP)PORTE_DATA=0x0;
for(i=0;i<100;i++);
*(RP)PORTE_INTRCLR|=0x10;
*(RP)INTC_IMSK=0;
}
/*************setY3,Y2,Y1={1,0,1},configGPIO*************/
*(RP)PORTE_DATA|=0x00e0;
*(RP)PORTE_INTRCLR=0xffff;
*(RP)PORTE_DATA&=0xffa3;
for(i=0;i<5000;i++);
if(*(RP)INTC_ISTAT==0x8)
{
key=6;
*(RP)PORTE_DATA=0x0;
for(i=0;i<100;i++);
*(RP)PORTE_INTRCLR|=0x8;
*(RP)INTC_IMSK=0;
}
/*************setY3,Y2,Y1={0,1,1}},configGPIO*************/
*(RP)PORTE_DATA|=0x00e0;
*(RP)PORTE_INTRCLR=0xffff;
*(RP)PORTE_DATA&=0xff63;
for(i=0;i<5000;i++);
if(*(RP)INTC_ISTAT==0x8)
{
key=9;
*(RP)PORTE_DATA=0x0;
for(i=0;i<100;i++);
*(RP)PORTE_INTRCLR|=0x4;
*(RP)INTC_IMSK=0;
}
}
*(RP)INTC_IMSK=0x0;
*(RP)PORTE_DATA&=0xff1f;
for(i=0;i<100;i++);
*(RP)PORTE_INTRCLR=0xffff;
DBG_Printf("key=%x\n",key);
}
voidfindkey(void)
{
U32intstatus=0;
U32i=0;
U16j=0;
U16k=0;
U16l=0;
U16m=0;
U16n=0;
U32datareg=0;
U16key=0;
char*s;
datareg=rucb(0x5a);//记录下数据寄存器原始值,用于判断列地址
intstatus=rucb(0x62);//记录下中断状态值,用于判断行地址
if(intstatus!
=0)
{
for(j=0;j<4;j++)//确定列位置。
{
k=(0x08>>j)|datareg;//依次写入1000010000100001
wucb(0x5a,k);//进行列扫描动作
for(n=1000;n>1;n--);
l=rucb(0x5a);
if((l&0x1e0)==0x1e0)//如果数据寄存器值变化,则输入为"1"的那列号就为按键所在列
break;//此时,j代表的循环数即为列号
}
n=intstatus>>4;//确定行位置。
for(m=0;m<4;m++)
{
n=n>>1;
if((n&0x1)==0x1)
break;
}
}
//下面判断按键是否抬起
n=0;
wucb(0x5a,0x1e0);//向I/O0-3写入全"0"
l=rucb(0x5a);
while((l&0x1e0)!
=0x1e0)//按键如果已经抬起了
{
key=(U16)((m*4+j)%16);//计算得到的键值
if(key<9)
{
key+=1;
}
elseif(key==9)
{
key=0;
}
if(n++==0)//如果是第一次按键抬起了
{DBG_Printf("keey=%x\n",key);
}
elseif(n>=10000)
{//如果在较长时间后,按键依然没有抬起,则快速打印键值
DBG_Printf("keey=%x\n",key);
}
wucb(0x5a,0x1e0);//下一次的判断周期
l=rucb(0x5a);
}
*(RP)PORTH_INTRCLR=0x8;//清除garfield中断源
wucb(0x62,0x1e0);//ucbI/O5-8清除中断状态
wucb(0x5c,0x1f);//配置UCB的I/O口功能,0-3为数据输出,5-8为中断输入
wucb(0x5a,0x1e0);//配置UCB的I/O口初始数据值
wucb(0x60,0x1e0);
}
2.LCD显示模块
2.1LCDC控制器的可编程控制寄存器
本系统中,LCD屏幕用于显示切换图片。
该模块需要完成的主要工作是LCD的驱动,在LCD的基本驱动中,需要配置以下寄存器:
寄存器
地址
复位值
SSA
0x11002000(BASE_LCDC)
0x31f00000
SIZE
BASE_LCDC+0x04
0x014000F0
PCR
BASE_LCDC+0x08
0x22080009
HCR
BASE_LCDC+0x0c
0x20004040
VCR
BASE_LCDC+0x10
0x14008586
PWMR
BASE_LCDC+0x14
0x00000114
DMACR
BASE_LCDC+0x1c
0x80070003
LCDICR
BASE_LCDC+0x20
0x00000000
SEP3203中具有内置的LCD控制器,支持灰度LCD和彩色LCD。
控制器负责将显存(在系统存储器中)中的数据送到LCD驱动电路。
在灰度LCD上,使用基于时间的抖动算法(time-basedditheringalgorithm)和FRC(FrameRateControl)方法,可以支持单色、4级灰度和16级灰度模式的灰度LCD;在彩色LCD上,最多可支持65535(16位)级彩色。
可以通过编程修改相应的LCD控制器寄存器的值,适配不同大小、象素的LCD。
2.2LCD的总体流程图
2.3实验代码
实验代码主要由三部分组成:
顶层实现函数,硬件设置函数,及两个画图函数。
2.3.1顶层实现函数
STATUSModuleLcdc(void)
该函数是Lcdc的顶层函数。
它实现了系统供电的初始化及Lcdc模块的初始化,并且根据Lcdc.h中的宏定义决定是否清屏,最后调用画图函数,画出一个矩形并显示出来。
2.3.2硬件设置函数
ERlcdc_init(void)
该函数实现的是对Lcdc的初始化。
其主要功能包括:
设置LCD数据帧的起始地址、屏幕尺寸、控制方式选择、灰度级别等。
(LCDC初始化的流程见下图)。
ERlcdc_clear(void)
该函数用于清除屏幕上所显示的内容。
2.3.3画图函数
ERlcd_draw2bpp(U8x1,U8y1,U8x2,U8y2,U8color)
该函数用来在屏幕上画一个由坐标(x1,y1)和(x2,y2)所确定的矩形,参数U8color表示所画图形的灰度级别。
voidpic_display(void)
该函数通过写屏幕起始地址寄存器,来显示一幅指定的图画。
2.4相关代码如下:
STATUSModuleLcdc(void)
{
U32i;
init_lcdc();
#ifndefLCD_640_480_Color
#ifdefLCDC_CLEAR
if(E_OK!
=lcdc_clear())
returnE_CTX;
#endif
pic_display();
#else
ShowPics();
#endif
}
ERinit_lcdc(void)
{
U32i=4;
U32k=0;
volatilechartempDot;
*(RP)LECR=0x00000000;//禁用LCDC
//*(RP)PORTE_SEL=0X1<<11;//GPIOtoselectlcd_backlight
//*(RP)PORTE_DATA=(0X1<<11);
/*configtheregisteroflcdc*/
#ifdefLCD_V//竖屏时的初始化
*(RP)SSA=VS_BASE;//lcd数据帧的起始地址
*(RP)SIZE=0x00F00140;//屏幕尺寸设定为240*320
*(RP)PCR=0x22080009;//LCD被动模式,单色显示,4bit总线宽度,2bpp,象素极性高有效,
//小印第安格式,最后刷新率配置必须写奇数这里是9,十分之一的
//AMBA频率
*(RP)HCR=0xc80008b4;//;0xc80008ab;
*(RP)VCR=0x14000304;//0x14000304;//V_WAIT_1=4,V_WAIT_1=4
*(RP)PWMR=0x00000113;//0x00000114;//选取象素时钟,关对比度,最后7位设置输出脉冲数目
*(RP)DMACR=0x80070003;//0x80070003;//burst=1设置DMA高标志7和低标志3,对于固定长度的burst,每次请求
//burst长度为高标志减一,这里是7-1=6。
当bu