通信工程专业课程设计基于SEP3203的电子琴模型文档格式.docx

上传人:b****6 文档编号:19882520 上传时间:2023-01-11 格式:DOCX 页数:21 大小:274.19KB
下载 相关 举报
通信工程专业课程设计基于SEP3203的电子琴模型文档格式.docx_第1页
第1页 / 共21页
通信工程专业课程设计基于SEP3203的电子琴模型文档格式.docx_第2页
第2页 / 共21页
通信工程专业课程设计基于SEP3203的电子琴模型文档格式.docx_第3页
第3页 / 共21页
通信工程专业课程设计基于SEP3203的电子琴模型文档格式.docx_第4页
第4页 / 共21页
通信工程专业课程设计基于SEP3203的电子琴模型文档格式.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

通信工程专业课程设计基于SEP3203的电子琴模型文档格式.docx

《通信工程专业课程设计基于SEP3203的电子琴模型文档格式.docx》由会员分享,可在线阅读,更多相关《通信工程专业课程设计基于SEP3203的电子琴模型文档格式.docx(21页珍藏版)》请在冰豆网上搜索。

通信工程专业课程设计基于SEP3203的电子琴模型文档格式.docx

调试过程中,需要查看按键的状态,需要查看是否正确检测到了按键,是否能够给出正确的键码,所以增加了这一功能。

功能描述:

利用LED数码管,显示按下的按键。

2、总体设计

2.1基本功能使用的模块

第一部分包括两个主要软件模块和两个外围的硬件模块:

2.2加入附加功能之后的模块组成

加入第二部分后的框图如下:

增加了一个新的程序模块和硬件模块。

程序运行的流程如下:

第二部分是对第一部分的完善和改进,但是在程序执行的流程中,仅仅在处理键码信息步骤,增加了“根据键码控制点亮数码管”这一部分。

3、可行性分析

该系统包含了输入、处理、输出三个部分。

其中,输入即为按键,使用矩阵键盘完成,实际的电子琴键盘含有更多的按键,但由于这仅仅是模型,所以,不需要使用那么多的按键。

处理部分是基于SEP3203的程序,通过输入的按键信息,修改寄存器的相应位,使得最终能够输出相应的PWM波,控制蜂鸣器响。

此外,还可以根据输入的按键信息,将输入的按键值显示在LED七段数码管上。

输出即为蜂鸣器和LED数码管,硬件电路已经在实验箱上连接好。

4、详细设计与分工日志

4.1.1器件原理

采用矩阵键盘,矩阵键盘有两种驱动方式:

一种是行扫描法,另一种是高低电平翻转法。

这里采用了行扫描法。

包括两个步骤:

判断键盘中有无键按下:

将全部行线Y0-Y3置低电平,然后检测列线的状态。

只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。

若所有列线均为高电平,则键盘中无键按下。

判断闭合键所在的位置:

在确认有键按下后,即可进入确定具体闭合键的过程。

其方法是:

依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。

在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。

若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。

4.1.2相关代码

键盘中断的调用:

voidkeyhandler(void)//键盘中断处理函数

{

mask_irq(INT_EXT15);

//屏蔽键盘中断

//找到哪个键被按下,并打印

findkey();

unmask_irq(INT_EXT15);

//打开键盘中断

//这里的键盘中断处理的不仅仅是打印键值,

//还包括了重置PWM波发出的寄存器.

}

寻找被按下的按键:

voidfindkey(void)

U32KEYTIME=0x100000;

U32KEYTIME2=0x10000;

U32dly=0;

U16intstatus;

U8col,row;

//清除garfield中断源

*(RP)PORTH_INTRCLR|=0x8;

//记录下中断状态值,用于判断行地址

intstatus=rucb(0x62);

wucb(0x60,0);

//屏蔽UCB中断

if(!

(intstatus&

KEY_ROW_MASK)){

wucb(0x60,KEY_ROW_MASK);

return;

}

wucb(0x62,KEY_ROW_MASK);

row=intstatus&

KEY_ROW_MASK;

{

inti;

for(i=0;

i<

KEY_ROW_NUM;

i++)

if((row&

(1<

<

i))){

row=i;

break;

}

{

//找到对应得列

U16line=KEY_COL_MSB;

U16tmp;

col=KEY_COL_NUM;

while(col--){

//利用按键拉低相应得中断线

tmp=rucb(0x5a);

tmp=((tmp|KEY_COL_MASK)&

(~line)|KEY_ROW_MASK);

wucb(0x5a,tmp);

if((rucb(0x5a)&

intstatus)==0)

break;

line>

>

=1;

key_code=key_code_map[row][col];

//利用行列取得键码

b=b_code_map[row][col];

l=l_code_map[row][col];

pwm();

led();

if(key_code){//排除无效按键

wucb(0x5a,0);

//所有的列线置0

while(((rucb(0x5a))&

intstatus)==0){

//按键还未抬起

inti;

if(dly++==0){

for(i=0;

KEYTIME;

i++);

//在等待较长时间后,打印键值

DBG_Printf("

key=%c\n"

key_code);

}else{

KEYTIME2;

}

//下一次的判断周期

wucb(0x5a,0x0);

//再次ucb行清除中断状态,因为判断

wucb(0x62,KEY_ROW_MASK);

4.2发声器件

4.2.1PWM波输出原理

发声器件即为蜂鸣器,通过控制输出的PWM波的波形来控制发出的声音。

PWM波包括两个参数:

频率和占空比。

控制频率,可以控制发出声音的频率;

控制占空比,可以控制声音的响度。

在所用开发板GE01中,PWM模块中包含了2个PWM通道,彼此相互独立。

相关寄存器:

地址

寄存器名称

宽度

描述

复位值

0x1000c000

PWMC(TCTL)

32

PWM_1控制寄存器

0000_4000

0x1000c004

PWMS(TPRER)

PWM_1采样寄存器

0000_0000

0x1000c008

PWMP(TCMP)

PWM_1周期寄存器

0000_FFFE

0x1000c00c

PWMCNT(TCR)

PWM_1计数器寄存器

高16位为保留位

bit15——中断请求状态(0=FIFO满、1=FIFO不满)

bit14——中断请求使能(0=不使能(缺省)、1=PWM中断使能)

bit13——FIFO有效状态(0=FIFO满、1=FIFO不满)

bit12——PWM使能(0=PWM不使能、1=PWM使能)

bit11-10——选择playback模式下采样被重放的次数(00=没重复,01=播放两次、10=重复3次(播放4次)、11=重复7次(播放8次))

bit9-0(PRESCALER)——用来提供分频因子的(prescaler+1),对系统时钟进行分频。

缺省值是0。

1=2分频、2=4分频…

Bit15-0——PWMS采样值PWM采样寄存器是FIFO的输入。

此值和一个自由计数的计数器比较。

当大于计数器值时PWM输出为高,反之输出为低。

bit15-0——Period值/定时值在tone模式时,其用于设置计数器的复位值。

计数器计数到此值就复位一次,PWM输出也相应翻转一次。

bit15-0——当前的计数值它保存着自由计数的计数器的当前值。

依据上述寄存器各位的功能,通过合适的赋值便可以实现本实验所要求的基本功能。

主函数:

intmain(void)

{

if(E_OK!

=ModulePwm())

errorinpwmlab\n"

);

successinpwmlab\n"

while

(1);

return1;

STATUS模块初始化

STATUSModulePwm(void)

/*systeminitialized*/

system_init();

/*固定周期发音实验*/

#ifdefFIX_LAB

sample=0X5555DDDD;

if(E_OK!

=set_fix())

returnE_CTX;

#endif

/*设置周期发音实验*/

#ifdefUNFIX_LAB

=set_unfix(0Xf0))

run_pwm();

returnE_OK;

STATUSset_fix(void)

#ifdefGE01MB

*(RP)(PWM2_P)=0X0000FFFE;

#else

*(RP)(PWM1_P)=0X0000FFFE;

#endif

STATUSset_unfix(U8prescaler)

*(RP)(PWM2_C)=0X00001c00|(U32)prescaler;

*(RP)(PWM1_C)=0X00001c00|(U32)prescaler;

voidrun_pwm(void)

#ifdefFIX_LAB

#ifdefGE01MB

*(RP)(PWM2_C)|=0X00001CFF;

while

(1)

*(RP)(PWM2_S)=0X0000FFFF&

sample;

*(RP)(PWM2_S)=sample>

16;

#else

*(RP)(PWM1_C)|=0X00001CFF;

*(RP)(PWM1_S)=0X0000FFFF&

*(RP)(PWM1_S)=sample>

#endif

#ifdefUNFIX_LAB

*(RP)(PWM2_P)=0X00008ffe;

*(RP)(PWM1_P)=0X00008ffe;

return;

4.3LED显示

4.3.1动态显示原理

图十二动态显示LED的连接

由图,六个数码管每个都有一个选择信号,当置“1”时,该数码管的相关段亮。

对于此动态显示电路,有六个数码管,使用的频率由定时器产生,为500Hz,即周期为2ms。

此外,将每个数码管相同的段连在一起到段数据线上。

在第一个2ms,第一个数码管允许点亮,同时,需要点亮的段置“1”,在这2ms内,只有第一个数码管亮。

在第二个2ms,第二个数码管允许点亮,同时,需要点亮的段置“1”,在这2ms内,只有第二个数码管亮……如此,每个2ms只有一个数码管亮,所以,不会相互影响,导致显示不清。

而且,由于每个数码管刷新的周期非常小,本实验中为12ms,小于人眼的分辨时间。

所以,看起来,好像同时亮了。

4.3.2定时器输出

如图,定时器用到的IO端口位置如下:

TIMER是片内集成的32bit定时器,该模块共包括4个通道,每个通道包括一个32位计数器,以及一个加载计数寄存器。

计数器的重新加载、计数使能以及中断的产生受到控制寄存器的各个控制位的控制。

定时器的工作原理是:

首先要设定定时器的初值,然后启动定时器。

一旦启动,定时器就从初值开始累计增加或减小(在实验所用的芯片中是递减)。

每增加或减小一个数需要特定的时间,这个特定的时间是累加指令的机器周期,是由处理器的晶振的频率(本实验中晶振的频率是75MHz)决定的。

计数值从初值计至0时,TIMER模块发出中断,然后计数器跳至用户配置的值,重复递增或递减过程。

在中断寄存器允许的情况下处理器响应中断,通过中断服务程序执行特定的任务。

TIMER中的一个通道的功能结构如下图:

TIMER有两种工作模式:

正常工作模式

TIMER在正常工作模式时,当通道使能后计数器锁存加载计数寄存器的值,然后在系统时钟的驱动下递减计数。

当计数到零时,产生一个计数到零的标志用于设置相应的中断标志位,若中断未被屏蔽则产生中断;

同时,计数器重新锁存加载计数寄存器的值开始一个新的计数周期。

自由工作模式

TIMER在自由工作模式时,当通道使能后计数器锁存加载计数寄存器的值,然后在系统时钟的驱动下递减计数。

同时,计数器加载数据32’HFFFFFFFF开始一个新的计数周期。

TIMER中四个通道的中断都可以通过各自的控制寄存器屏蔽。

任意一个通道计数完毕都会产生一个中断。

TIMER的中断输出是四个中断源的线或。

查询中断源有两种方法:

(一)查询各个通道的中断屏蔽状态寄存器是否被置1;

(二)查询TIMER中断屏蔽状态寄存器,看各个通道相应位是否被置1。

清除中断的方法也有两种:

(一)读各个通道的中断状态清除寄存器,相应通道的中断会被清除;

(二)读TIMER中断状态清除寄存器,所有通道的中断都会被清除。

查询到中断源后,如果不重新配置加载计数寄存器,计数器会按照原来的配置继续计数,直到计数完毕再发出中断。

如果要重新配置,清完中断后应该先将计数器关闭(disable),然后配置新的计数值,再将计数器打开(enable)。

4.3.3相关寄存器

名称

读/写

0x10003000

T1LCR

R/W

通道1加载计数寄存器

32’b0

0x10003004

T1CCR

R

通道1当前计数值寄存器

0x10003008

T1CR

W/R

通道1控制寄存器

0x1000300C

T1ISCR

通道1中断状态清除寄存器

0x10003010

T1IMSR

通道1中断屏蔽状态寄存器

0x10003014

T2LCR

通道2加载计数寄存器

0x10003018

T2CCR

通道2当前计数值寄存器

0x1000301C

T2CR

通道2控制寄存器

0x10003020

T2ISCR

通道2中断状态清除寄存器

0x10003024

T2IMSR

通道2中断屏蔽状态寄存器

0x10003028

T3LCR

通道3加载计数寄存器

0x1000302C

T3CCR

通道3当前计数值寄存器

0x10003030

T3CR

通道3控制寄存器

0x10003034

T3ISCR

通道3中断状态清除寄存器

0x10003038

T3IMSR

通道3中断屏蔽状态寄存器

0x1000303C

T4LCR

通道4加载计数寄存器

0x10003040

T4CCR

通道4当前计数值寄存器

0x10003044

T4CR

通道4控制寄存器

0x10003048

T4ISCR

通道4中断状态清除寄存器

0x1000304C

T4IMSR

通道4中断屏蔽状态寄存器

0x100030A0

TIMSR

TIMER中断屏蔽状态寄存器

0x100030A4

TISCR

TIMER中断状态清除寄存器

0x100030A8

TISR

TIMER中断状态寄存器

调用LED显示:

intled(void)

char*s1,*s2,*s3;

s1="

ThereisnoLEDonGE00\n"

;

s2="

ErrorinLedlab!

!

\n"

s3="

SucceededinLedlab!

#ifdefGE00

DBG_Printf(s1);

return;

#else

=ModuleLed())

//PRINT(s2);

else//PRINT(s3);

DBG_Printf("

//while

(1);

//returnE_OK;

LED显示模块:

STATUSModuleLed(void)

//系统初始化

/*GPIOinitialized*/

GPIO_Init();

/*ledlabbody*/

if(key_code=='

1'

{

LedDisPlay(display1);

//显示用户设定的内容

2'

LedDisPlay(display2);

3'

{

LedDisPlay(display3);

4'

LedDisPlay(display4);

5'

LedDisPlay(display5);

6'

LedDisPlay(display6);

7'

LedDisPlay(display7);

8'

LedDisPlay(display8);

9'

LedDisPlay(display9);

LED显示程序:

voidLedDisPlay(U8data[])

U8*SegData;

//十六进制数字翻译成7段译码值

Hex2Seg(data,SegData);

LedOut(SegData,10);

//在led上显示

翻译码值

VoidHex2Seg(U8hexdata[],U8*p)

inti;

for(i=0;

i<

9;

i++)

//将要显示的数值,通过查找7段译码表翻译成码值

*p++=SEGMENT[hexdata[i]];

LED输出

voidLedOut(U8data[],U32times)

intSegment_i,Bit_i,i;

U8Segment_Data;

U8tempData;

for(i=0;

times;

for(Bit_i=0;

Bit_i<

8;

Bit_i++)

//依次串行导入八个led的显示内容

{

//获得一个led显示的码值

Segment_Data=*(data+Bit_i);

//将7段译码值依次串行输入到GPIO口中

for(Segment_i=0;

Segment_i<

8;

Segment_i++)

{

//得到一段发光管的译码值

tempData=(Segment_Data>

Segment_i)&

0x1;

//写入74HC595的输入端,同时拉低PD3

*(RP)PORTD_

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1