嵌入式系统实验报告.docx

上传人:b****7 文档编号:9416555 上传时间:2023-02-04 格式:DOCX 页数:65 大小:10.71MB
下载 相关 举报
嵌入式系统实验报告.docx_第1页
第1页 / 共65页
嵌入式系统实验报告.docx_第2页
第2页 / 共65页
嵌入式系统实验报告.docx_第3页
第3页 / 共65页
嵌入式系统实验报告.docx_第4页
第4页 / 共65页
嵌入式系统实验报告.docx_第5页
第5页 / 共65页
点击查看更多>>
下载资源
资源描述

嵌入式系统实验报告.docx

《嵌入式系统实验报告.docx》由会员分享,可在线阅读,更多相关《嵌入式系统实验报告.docx(65页珍藏版)》请在冰豆网上搜索。

嵌入式系统实验报告.docx

嵌入式系统实验报告

 

嵌入式系统专题实验报告

 

学院:

电信学院

班级:

电信(硕)81班

姓名:

聂金

学号:

06035021

姓名:

尹鑫

学号:

08058029

提交日期:

2011年5月27日星期五

 

瑞萨嵌入式M16C62P单片机介绍

M16C62P系列单片机是瑞萨科技1996年推出的16位单片机。

采用高性能的硅栅CMOS工艺,使用高效率的复杂指令,具有1兆字节的线性地址空间,能高速执行指令,内置有乘法器和DMAC。

M16C62P单片机融合了基于寄存器型和基于存储器型两种结构的优点。

M16C单片机具有超低功耗、极强的抗干扰能力和很高的C语言编程效率等特点。

片内集成了丰富的周边功能电路模块,应用领域广阔。

该单片机有着非常强大的指令,既有一般的指令格式,也有紧凑的指令格式。

高速的乘法运算、增强的存储器与存储器之间的操作、增强的按位处理功能、高效的对4位和8位的操作、高速的16位处理能力,使处理器速度大大加快。

内置双电源型的FLASH存储器,可高速改写、并支持串、并联输入/输出方式,CPU改写方式等。

M16C单片机配备有软件模拟器和各种级别的硬件仿真器,具有集成调试环境。

采用HEW(High-performanceEmbeddedWorkshop)对源程序进行编译,采用KD30软件对系统进行在线仿真,利用Flashdata对程序进行烧录。

另外,还支持E8仿真器。

M16C62P单片机的系统构架及资源如下:

图1.M16C62P单片机系统架构图

 

实物图如下:

表1.瑞萨嵌入式系统实验设备技术参数表

指标

说明

存储容量

片内RAM3KB~20KB,片内ROM32KB~256KB

机器周期/ns

62.5ns(5V16Mhz)

处理速度/MIPS

8(16Mhz)

寄存器

通用寄存器16位×6×2组专用寄存器16位×5

电源

4.2~5.5VDC(频率为16Mhz)

低功耗

在5V电压,16MH工作频率,1等待方式工作时,功耗为18mW。

中断

25个内部中断源和8个外部中断源,4个软件中断,7级中断优先级可选

定时器

5个输出型定时器,6个输入型定时器

串口

3个异步/同步通道,2个同步通道

DMAC

2个通道(有24种触发源)

A/D转换

10位×8通道

D/A

8位×2通道

CRC计算电路

1个电路

监视定时器

15位(可预分频器)

可编程I/O口

87口

输入口

1个(p8.5与NMI共用)

存储器扩充

1.2MB或4MB

片选输出端

4个

处理器工作模式

3种模式(单片模式、存储器扩充模式、微处理器模式)

实验要求

1、掌握renesas嵌入式系统原理及嵌入式C语言的编程方法。

2、熟悉并掌握renesas嵌入式系统的集成编译环境和仿真调试环境。

3、掌握M16C/62P系列嵌入式微控制器的基本程序设计方法。

实验环境

MicrosoftWindowsXPProfessionalVerb2002

ServicePack3PC

M16C/62P嵌入式系统实验箱

集成开发环境HEW

仿真调试环境KD30

实验任务

实验一:

熟悉M16C/62P嵌入式系统实验箱及嵌入式C语言的基本编程方法

实验目的:

了解renesas嵌入式系统,掌握嵌入式C语言的编程方法。

基本要求:

学会使用M16C/62P嵌入式系统实验箱;熟悉嵌入式C语言的编程方法,了解嵌入式C语言和普通C语言的异同。

内容提要:

了解renesas嵌入式系统的组成结构,熟悉M16C/62P嵌入式系统实验箱。

嵌入式C语言的变量定义;程序结构设计;外围输入、输出设备的控制指令的使用等。

实验二:

M16C/62P嵌入式系统的集成编译环境和仿真调试环境实验

实验目的:

掌握M16C/62P的集成编译HEW和仿真调试环境KD30的使用方法。

基本要求:

能够熟练使用renesas嵌入式设备的集成编译环境HEW和仿真调试环境KD30。

内容提要:

熟悉renesas嵌入式设备的编程环境HEW和调试环境KD30。

能够根据实验要求在编程环境HEW下设计相应的工程项目,包括文件定义、变量定义、程序结构设计、算法实现等;在KD30环境下,掌握程序的调试步骤,如何排除程序中的错误等。

实验三:

基础模块设计实验

实验目的:

掌握各基础模块的使用和编程方法。

基本要求:

熟悉功能函数库library中的函数,通过对各基础模块(如LCD、LED、键盘、定时器和中断等)的学习,了解其工作原理。

并能根据实验要求编制相应的控制程序。

内容提要:

完成7段LED模块、LCD16*2和LCD128*64显示模块、键盘的使用模块,定时器的使用、定时中断的使用、AD和DA等模块基本实验环节。

实验四:

综合设计实验

实验目的:

全面掌握M16C/62P系列嵌入式微控制器的程序设计技术。

基本要求:

利用实验一~三的积累,完成综合实验任务。

内容提要:

1)设计程序查找一维数组的最大(小)值、中值和均值;2)实现具有简单人机界面的加、减、乘、除、开方和幂运算计算器;3)分别采用定时中断和定时器,设计秒表和倒计时表,并能显示日历。

实验思路

由于本实验属于开放式实验,因此在集中设计环节给了我们很大的发挥空间。

由于我们两人都是第一次接触单片机,对单片机编程不是很了解,因此在设计上遇到了很大的问题,很多很好的思路由于技术因素都无法很好的实现,后来我们就抛弃了实用性这一个因素,尽量用上实验箱上所有的模块,使得通过这次实验使我们对瑞萨嵌入式系统以及单片机有更加深入的了解。

在完成基本的四项任务后,我们还未加入的环节有:

红外感应;LED指示灯;AD0旋钮模块;DA声音输出模块;

因此在最后的环节,我们综合了以上所有模块的功能,做出了以LED指示灯为指示效果的跑马灯,其中速度快慢不同声音输出也不同,而速度由AD旋钮模块来控制,红外感应是跑马灯的启停开关。

使用的设备:

LCD12864图形液晶屏、键盘、7段数码管、LED灯、拨动开关、LCD数码液晶屏、定时器和定时中断、Mic插口和Phone插口,红外感应。

源代码与结果

任务1.数组处理程序

该段程序完成的功能如下:

用户规定数组长度,然后输入相应个数个数据,每输入一个数据按“#”键确认,最后程序输出数组的最大值,最小值,中值和平均值结果。

程序流程如下:

1.首先利用键盘读入程序启停开关量,进入程序。

2.将数组长度定义为全局变量,在寻找数组最大值,最小值,中值和平均值时不用反复定义。

3.在主程序内,利用getchar指令从键盘获得数组长度,并通过init函数初始化数组,申请存储空间。

4.利用getchar指令获得用户输入的每一个数组元素。

5.利用max,min,mid,average等子函数完成求最大,最下,中指和平均值的功能。

6.其中,max,min子函数的实现采用算法中的冒泡排序法来进行查找,冒泡方向想法,核心思想都是进行顺序比较,采用中间变量存储暂时最大(小)值,当所有的元素都参与比较完毕之后,中间变量中的元素便是我们所求的最值。

7.中值的获取在完成冒泡排序之后,此时数组已经成为有序数列,位于最中间的就是中值。

8.平均值的求法是设置一累加器,将所有元素相加之后除以数组长度取整即可。

源程序如下所示:

intget_maximum(int*p)//最大值程序

{

inti;

intmax=0;

for(i=0;i

{

max=(max>*(p+i))?

max:

*(p+i);}//冒泡排序法

return(max);

}

该段子程序就是上述采用冒泡排序法求取最大值的子程序,可以看到,变量max为中间变量,用来存储一次排序中较大的那个元素,当所有元素都进行比较之后,max中的元素极为全局最大元素。

这个思想在最小值程序中一样适用。

intget_minimum(int*p)//最小值程序

{

inti;

intmin=*p;

for(i=0;i

{

min=(min<*(p+i))?

min:

*(p+i);}

return(min);

}

intget_average(int*p)//均值程序

{

inti;

intsum=*p;

for(i=0;i

{

sum+=*(p+i);}//累加器

return(sum/ARRAY_LENTH);//均值求取

}

以上程序就是实现求取均值的程序,利用累加器sun将所有元素进行累加求出总和即可。

intget_mid(int*p)//中值程序

{

inti;

intj;

intmid;

inttemp;

for(i=0;i

{

for(j=i;j

if(*(p+i)>*(p+j))

{

*(p+i)=temp;

*(p+i)=*(p+j);

*(p+j)=temp;//中间变量存储

}

}

mid=*(p+(ARRAY_LENTH-1)/2);

return(mid);

}

上述程序为求取中值程序,由于开发环境不支持下标查找数组,因此在上述子程序中采用指针寻址,找到每个元素所在的存储单元,取出在链表最中间存储单元中元素的值即可,由于之前已经做过冒泡排序,因此此单元内的元素便是整个数组的中值元素。

voidshuzhu(void)

{

inti;

di();//关中断;

SW__initialize1();

init_LCD();

init_TimerA0();

ei();//开中断

Lcd12864_init_lcd();

Lcd12864_clear_lcd();

Lcd12864_light_on();

Lcd12864_clear_lcd();

Lcd12864_set_cursol(0,0);//利用12864液晶屏显示字符

Lcd12864_write_lcd("输入数组长度:

");

ARRAY_LENTH=SW__getdec();

while(!

ARRAY_LENTH);

Lcd12864__putdec(ARRAY_LENTH);

Lcd12864_set_cursol(0,1);

Lcd12864_write_lcd("数据:

");

Lcd12864_set_cursol(0,2);

for(i=0;i

{

array[i]=SW__getdec();

Lcd12864__putdec(array[i]);

Lcd12864_write_lcd("");

}

Lcd12864_clear_lcd();

Lcd12864_set_cursol(0,0);

Lcd12864_write_lcd("Result:

");

Lcd12864_set_cursol(0,1);

Lcd12864_write_lcd("MAX:

");

Lcd12864__putdec(get_maximum(array));

Lcd12864_set_cursol(0,2);

Lcd12864_write_lcd("MIN:

");

Lcd12864__putdec(get_minimum(array));

Lcd12864_set_cursol(0,3);

Lcd12864_write_lcd("AVE:

");

Lcd12864__putdec(get_average(array));

_lcd12864__wait(25000);

Lcd12864_clear_lcd();

Lcd12864_set_cursol(0,0);

Lcd12864_write_lcd("MID:

");

Lcd12864__putdec(get_mid(array));

}

以上为数组操作子程序的程序主体,由于lcd12864支持时延,因此在显示方面可以省去循环扫描输出的麻烦。

当时延很大时,相当于恒定显示。

利用lcd12864_set_cursol指令可以设置输出字符在LCD屏幕的位置,这些指令使得输出十分方便灵活。

功能截图如下:

图2.获取键盘输入数组长度

图3.获取用户输入数组数据

图4.数组程序运行结果(最大、最小、平均值、中值)

当输入数组为23125575时,结果如下:

图5.数组结果2(最大,最小,均值,中值)

 

任务2.计算器程序实现

对于任务2,设计的基本思想是读取键盘用户输入的操作数数A,以及另外一个操作数B,用子函数中的变量来存储,然后通过调用功能子函数,来完成加减乘除等基本运算。

此时调用哪个函数则是由用户第二个键入的功能键来决定的,功能键变量作为开关量,用switch结构开启某个功能子函数。

这样一来既能完成四则运算的功能,又可以符合人的输入习惯。

程序的运行流程如下:

1.通过主程序开关量,开启计算器子程序。

2.通过getchar指令获得操作数A。

3.通过getchar指令获得操作方法变量C。

4.通过getchar指令获得操作数B。

5.由操作方法变量C选择调用的功能子函数。

6.将A,B作为功能子函数的输入,获得返回值,即结果,通过LCD显示在液晶屏上。

源程序如下:

intadd(intdata1,intdata2)

{

return(data1+data2);

}

intsub(intdata1,intdata2)

{

if(data1>=data2)

return(data1-data2);

return(data2-data1);

}

intmul(intdata1,intdata2)

{

return(data1*data2);

}

intdiv(intdata1,intdata2)

{

return(data1/data2);

}//四则运算功能子程序

voidcalculator(void)//计算器子功能主程序

{

charop;

intNum1;

intNum2;

intnum1;

di();//关中断;

SW__initialize1();

init_LCD();

init_TimerA0();

ei();//开中断

Lcd12864_clear_lcd();

Lcd12864_set_cursol(0,0);

Lcd12864_write_lcd("请输入:

");

Lcd12864_set_cursol(0,1);

Num1=SW__getdec();//获取操作数A

Lcd12864__putdec(Num1);

SW__gets(&op);//获取操作方法变量op

Lcd12864_write_lcd_char(op);

Num2=SW__getdec();//获取操作数B

Lcd12864__putdec(Num2);

Lcd12864_write_lcd_char('=');

switch(op)//根据操作方法变量调用功能子程序

{

case'+':

num1=add(Num1,Num2);

Lcd12864__putdec(num1);break;

case'-':

num1=sub(Num1,Num2);

Lcd12864__putdec(num1);break;

case'*':

num1=mul(Num1,Num2);

Lcd12864__putdec(num1);break;

case'/':

num1=div(Num1,Num2);

Lcd12864__putdec(num1);break;

default:

break;//若出错,则跳出

}

}

运行结果

图6.计算器乘法算例

图7.计算器加法算例

图8.计算器减法算例

图9.计算器除法算例

任务3.带秒表的电子日历

以例程为基础,使其以:

“年/月/日时:

分:

秒”的格式显示时间。

调用例程中的initTimer函数对计时器进行初始化,编写LCD显示函数使输出月日年时分秒可调整。

利用内部计数器对不同位的。

程序的工作过程是:

通过计数值为7500的TimerA1的时钟中断计时,每次中断为10ms,累加毫秒计数并更新年月日时分秒,在对日期更新时还存在闰年的判断和调整;同时还会根据标志位情况累加秒表毫秒计数和倒计时毫秒计数;在主程序中,循环更新Lcd12864显示,并判断拨动开关的位置进入相应的功能或返回时钟主界面;子功能包括年月日时分秒设置,倒计时器设置。

全局变量定义如下,使得不必在子程序中对需要的变量进行重复定义:

intflag;

intyear;

intmonth;

intday;

inthour;

intminute;

intsecond;

intsecond_percent;

inthour1;

intminute1;

intsecond1;

intsecond_percent1;

intmiaobiaoon;

intdaojishion;

intcount;

程序流程如下:

1.通过主程序的开启变量,开启日历子程序函数。

2.初始化计时器TimerA1。

3.通过键盘,获得用户输入年,月,日,时,分,秒数据。

4.根据用户输入数据,设置计时器初始值。

5.开始计时,循环扫描显示。

源代码:

/*""FUNCCOMMENT""************以下是TimerA1处理函数************************

*ID:

---

*functionname:

voidinit_timerC(void);定时器A1初始化

voidINT_TimerA1(void);定时器A1中断处理函数

voidset_busy(unsignedinttime);定时器A1重载及计数启动函数

*notice:

interruptfunctioncalledbyinterruptprogram

*History:

*""FUNCCOMMENTEND""*********************************************************/

voidinit_TimerA1(void)

{

/*-----initializetimerA1-----*/

ta1mr=0x80;/*settimerA1moderegister*/

/*?

?

?

?

0000*/

/*||||||++timermode*/

/*|||||+--ta0outisI/O*/

/*|||++---ta0inisI/O*/

/*||+-----reserved*/

/*++------selectf32(24MHz/32:

1.43us)*/

ta1ic=0x02;/*setinterrupt(prioritylevel:

2)*/

ta1=69930;/*settimer0.1s=69930*1.43us*/

year=2010;

month=1;

day=11;

ta1s=1;/*startcount*/

}//计时器初始化函数,由例程修改而来

 

voidSetCalendar(void)

{

Lcd12864_clear_lcd();

second_percent=0;

Lcd12864_set_cursol(0,0);

Lcd12864_write_lcd("intputtheyear");

year=SW__getdec();

Lcd12864_set_cursol(0,1);

Lcd12864__putdec(year);

_lcd12864__wait(5000);

Lcd12864_clear_lcd();

Lcd12864_set_cursol(0,0);

Lcd12864_write_lcd("inputthemonth");

Lcd12864_set_cursol(0,1);

month=SW__getdec();

Lcd12864__putdec(month);

_lcd12864__wait(5000);

Lcd12864_clear_lcd();

Lcd12864_set_cursol(0,0);

Lcd12864_write_lcd("inputtheday");

Lcd12864_set_cursol(0,1);

day=SW__getdec();

Lcd12864__putdec(day);

_lcd12864__wait(5000);

Lcd12864_clear_lcd();

Lcd12864_set_cursol(0,0);

Lcd12864_write_lcd("inputthehour");

Lcd12864_set_cursol(0,1);

hour=SW__getdec();

Lcd12864__putdec(hour);

_lcd12864__wait(5000);

Lcd12864_clear_lcd();

Lcd12864_set_cursol(0,0);

Lcd12864_write_lcd("inputtheminute");

Lcd12864_set_cursol(0,1);

minute=SW__getdec();

Lcd12864__putdec(minute);

_lcd12864__wait(5000);

Lcd12864_clear_lcd();

Lcd12864_set_cursol(0,0);

Lcd12864_write_lcd("inputthesecond");

Lcd12864_set_cursol(0,1);

second=SW__getdec();

Lcd12864__putdec(second);

_lcd12864__wait(5000);

return;

}

这个函数是日历显示的函数,由于指令的便利使得很容易将年月日输出不同行,并且留一行专门显示秒表。

voidinit_miaobiao(void)

{

intminute=0;

intsecond=0;

intsecond_percent=0;

return;

}

这个是秒表的初始化函数,将分,秒,毫秒初始化为0。

voi

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

当前位置:首页 > 党团工作 > 入党转正申请

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

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