北邮微机硬件实验报告

2024-08-28

北邮微机硬件实验报告(共5篇)

篇1:北邮微机硬件实验报告

实训四底板LED点阵控制实训个人总结

通过led点阵实验的实践,使我在理论的基础上更深刻的掌握了嵌入式系统的深层内容及实际生活中的应用,实践锻炼了自己动手能力和思维能力,还有在软件方面的编程能力,让我受益匪浅,同时也暴露出一些平时学习上的问题,这次实践让我懂得了如何编写一些简单的程序,这几周我们经过老师耐心的讲解和指导通过自己认真的动手操作,终于完成了本次实训。

在这次实训过程中我们锻炼了自己的思考能力、动手能力和排除故障的能力。虽说在实训过程中遇到很多不懂的地方,但我们还是在老师和同学的帮助下完成了。对于点阵这个实验,刚开始的步骤就不用多说了,和之前的一样,关键在于程序的改写。首先,我们运行原始程序并单步调试观察每一句执行后的结果,对数据寄存器rGPFDAT进行分析,DM1_RL1高四位控制左边点阵前两行,DM1_RL2控制左边点阵中间四行,DM1_RL3低四位控制左边点阵后两行,DM1_RL3高四位控制右边点阵前两行,DM1_RL4控制右边点阵中间四行,DM1_RL5低四位控制右边点阵后两行。如果显示姓名首字母缩写,在点阵中将亮的点置一,写出对应的十六进制数,右边比左边高,下边比上边高,依次写出DM1_RL1、DM1_RL2、DM1_RL3、DM1_RL4、DM1_RL5寄存器中所存的十六进制数据。修改完程序,编译运行程序,最终点阵显示寄存器写入的数据,点阵呈现所设姓名首字母字样。

通过这次试验,使我更加深入的了解了寄存器是如何控制点阵的以及简单程序的编写,加强了我们的实际动手操作能力。

实训三底板LED数码管控制实训个人总结

这次实训主要目的是用led数码管显示学号的后八位,实践锻炼

了自己动手能力和思维能力,还有在软件方面的编程能力。实验开始

忘记了八段数码管是如何控制显示的,但在请教同学之后,我们就很

快写出了学号所对应的十六进制数。虽然实验过程并不顺利,但最终

还是完成了实验内容。

打开实验原始程序,首先,我们运行原始程序并单步调试观察每一句执行后的结果,对数据寄存器rGPFDAT进行分析,观察每步调试

后的数码管显示变化,对寄存器进行分析。根据试验任务要显示三个

人的学号,前四位为8033,led灯显示几,八段数码管的哪位置一,例如八段数码管显示8,则对应hgfe dcba分别为0111 1111,即对应

十六进制为7f,依次写出对应的十六进制,DM1_RL1控制左边数码

管,DM1_RL2控制右边数码管。例如8033对应的十六进制为7f3f4f4f,数码管右边为高位,对应寄存器中应为4f4f3f7f,同理可写出学号的后四位。修改完程序,编译运行程序在不出现错误的情况下可以交替

显示三个不同的学号。

这次实验还算比较顺利,不过在最初的过程中由于理解错误显示的学号是反着的,修改程序后最终得到了想要的效果。这次实验使我掌握了寄存器是如何控制八段数码管的基本原理,锻炼了我们的动手

能力。掌握了编程的基本方法,更加熟悉了c语言的编写以及运用,在学习的过程中也享受了编程的乐趣。

实训二 16个LED灯实训个人总结

第二次实验具体是编程利用实验板控制底板的led数码管闪烁,实现底版上16个LED的单 双 三灯的跑马灯过程以及LED(16个)的单灯汇集。在这次的实验过程中,对软件的应用更加深刻熟练。在修改程序的过程中又温习了c语言的编写以及应用,通过这次实验掌

握了不少的知识,对于寄存器有了更深的认识。

对于这次的实验,我们首先用ARM软件打开工程,编译连接工

程,用AXD 进行调试,观察源程序,单步运行分析程序,观察每一

步执行后led灯的显示效果,根据实验任务修改程序。Led0到led15

分别由四位十六进制代码控制,即16位二进制代码控制,二进制的最低为控制led15,最高位控制led0,置一时对应位置的led灯亮。

首先,用rGPFDAT=rGPFDAT&0xfffffffe;设置I/O口GPBDAT相应LED

寄存器的初始值,分别设置寄存器DM1_RL1=0x00000000;

DM1_RL1=0x00010000;接着用for、while循环实现灯的移位及汇聚效

果,寄存器分别保存移位前和移位后的数值,单灯跑马灯,从左向右

跑到另一侧停止,且一直保持亮的状态。

这次试验要比第一次的实验难,在改写代码这一环节我们就遇

到了很大的困难,要实现跑马灯用源程序类似的代码需要很长一段,为了减少代码使程序简明易懂我们在请教同学的基础上对程序进行

了修改,采用了for循环。这次试验证明c语言在编程中的重要性,而且从这次的实验中我发现了自己c语言的功底还是有待提高,以后的日子里还需努力。

实训一对四个led灯编程个人总结

微机与嵌入式系统实训是我们第一次接触硬件操作,在老师的带领下

我们进入第一节实训课。通过这次实训对微机与嵌入式的硬件操作有

了基本的了解。

首先要进行的是pc机与主板的连接,运行H-Jtag并进行设置,用ARM

软件打开工程,编译连接工程,用AXD 进行调试,观察源程序,单

步运行分析程序,对原程序进行修改。在运行源程序的过程中,由于

第一次接触,最初的设置不成功导致程序运行不出,在同学的指导下,最终顺利运行。接着的难题就是修改程序,根据试验任务,实验中的四个灯由上到下依次分别由三位十六进制数700H、380H、580H、680H

控制,对应的二进制代码D7D8D9D10位分别控制 led1、led2、led3、led4的亮灭,置1时对应的led灯灭,置0时对应的led灯亮,即低

电平有效。首先设用rGPBCON=rGPBCON&0xffc03fff;设置I/O口

GPBCON相应LED寄存器为输出属性,GPBCON=rGPBCON|0xffd57fff;

rGPBDAT=rGPBDAT&0xfffff87f;设置I/O口GPBDAT相应LED寄存器的初

始值。然后根据推算的十六进制代码改写数据寄存器rGPBDAT的内容。

在程序中,对于循环不是很懂,因此用了好几段程序来分别控制led

灯由上到下,再由下到上,最终全亮的效果。修改完程序之后编译运

行,效果不是很明显,因此对于汇编延迟函数delay进行了修改延长

时间。

这次试验让我更深认识了c语言的重要性,对于微机与嵌入式的编程

运行以及寄存器的工作原理有了更深的了解,增强了我们的动手能力。

篇2:北邮微机硬件实验报告

实验名称:

CAN总线技术与iCAN模块实验

学院:

自动化学院

专业:

自动化专业

班级:

2010211411

姓名:

韩思宇

学号:

10212006

指导老师:

杨军

一、实验名称:

实验一:CAN总线技术与iCAN模块实验

二、实验设备:

计算机,CAN总线系列实验箱,测控设备箱,万用表。

三、实验内容:

1、熟悉iCAN各模块的功能及原理,了解接线端子。

2、学习USBCAN-2A接口卡的使用及安装,安装USBCAN-2A接口卡的驱动程序。

3、根据实验指导书中的手动设置iCAN模块MACID的方法手动设置各模块的MACID。

4、使用提供的iCANTest测试软件工具来测试各模块的功能及用法,利用测试工具与模块之间通信。

5、学习了解iCAN主站函数库中的主要操作函数及其应用。

6、学习利用VC或者VB编程来对iCAN系列各模块进行操作。

四:实验过程:

1、驱动程序安装:

USBCAN-2A接口卡的驱动程序需要自己手动进行安装,驱动程序已经存放于实验准备内容中。找到驱动程序,直接点击进行安装即可。安装完成后,在“管理->设备管理器->通用串行总线控制器”中查看驱动是否安装成功。

注意:安装驱动程序过程中PC机不能连接USB电缆。

2、iCANTEST安装与运行:

连接设备后,打开iCANTEST软件,点击“系统配置”,设置设备类型为USBCAN2,点击“启动”->“上线”,试验各模块的功能。点击“全部下线”,将断开主机与所有模块的连接。

3、各种iCAN模块的测试

4、指示灯,按钮,温湿度传感器的连接

5、测试运行记录与截屏图:

iCAN模块测试运行记录与截图。

图(1)

iCANTEST界面

iCAN4055模块界面如图(2)。DI输入由测控设备箱中的开关控制,DO输出控制设备箱上的灯泡亮灭。

图(2)

iCAN4055模块界面

iCAN4210模块如图(3)。iCAN4210模块为2路模拟量输出模块。将该模块的输出通道0与iCAN4017模块的输入通道3相连,可观察到改变iCAN4210的通道0设定值时,iCAN4017的通道3显示值会随之变化。(通道0为0x8000时,通道3显示为5.000V。)

图(3)

iCAN4210模块界面

iCAN4017模块如图(4)。iCAN4017模块为8路模拟量输入模块。将该模块的通道0与通道1与测控设备箱的温湿度传感器相连,可由通道0和1的电压值推导出传感器测出的环境温度和湿度。由于实验时使用的温湿度传感器温度测量部分故障,所以通道0显示0.000V,湿度测量部分正常,通道1显示为6.182V。

图(4)

iCAN4017模块界面

6、自编程序主要功能

(1)添加一个输入编辑框和一个按钮控件,通过输入0x00-0xFF之间的十六

进制数来控制iCAN4055的DO通道的输入;再设置一个编辑框edit控件来读取iCAN4055的8位数字量输入通道的状态。(2)设置两个输入编辑框控件,来分别设置iCAN4210两个通道的输出。(3)设置4个编辑框edit控件来分别读取iCAN4017前四个通道ch0、ch1、ch2、ch3的模拟量输入值。

7、自编程序运行结果与截图(课上未做,课下做了界面和程序)

图(5)

iCAN4055模块界面

图(6)

iCAN4017模块界面

8、主要程序部分

(1)有关iCAN4055功能模块的简单功能的实现的整体代码如下:

首先在生成的类头文件Sample4055dlg.h中的类CSample4055中添加申明变量: public:

unsigned char buf[1];//发送数据的数据缓存区 unsigned char recbuf[1];//接受数据的数据缓存区 unsigned long len;int outvalue;int count;CString str;在Sample4055.cpp文件中编写控制代码: 首先添加对变量的定义: ROUTECFG cfg;

HANDLE hRoute=0;//新的ICAN网络

HANDLE hSlave4055=0;//数字量输入输出模块4055,MACID=1 CSample4055::CSample4055(CWnd* pParent /*=NULL*/){

}

(2)添加每个控件消息响应函数的代码: void CSample4055::OnStartsysButton1(){ : CDialog(CSample4055::IDD, pParent)buf[0]=0;recbuf[0]=0;count=0;len=0;str=“";

// TODO: Add your control notification handler code here cfg.iCardType=4;//使用usbcan2接线口 cfg.iCardInd=0;//卡序号

cfg.iCANInd=0;//CAN通道选择(0表示0通道;1表示1通道)cfg.wCANBaud=0x001c;//波特率的设定0x001c(500kbps)cfg.iMasterCycle=500;//主站循环周期 cfg.wMasterID=0;//主站ID

Mgr_AddRoute(cfg,&hRoute);//添加iCAN网络

if(Mgr_StartSys()!=ICANOK)//调用Mgr_StartSys()函数对CAN网络是否启动进行判断,返回为ICANOK

} void CSample4055::OnLink4055Button2(){ if(Mgr_IsStarted()!=1){ { } else { } MessageBox(”CAN网络已启动“);MessageBox(”系统启动失败“);

MessageBox(”系统未启动或启动失败,请先启动CAN网络“);

} else { // TODO: Add your control notification handler code here Route_AddSlave(hRoute,1,&hSlave4055);//添加从站4055,MACID=1

if(Slave_Connect(hSlave4055)!=ICANOK)//判断从站4055是否连接成功 { } MessageBox(”4055连接失败“);

else

{ } MessageBox(”4055连接成功“);

SetTimer(1,1000,NULL);//设定开启定时循环,1代表消息事件id,1000表示1000ms即1s } void CSample4055::OnTimer(UINT nIDEvent)//Timer事件函数 {

// TODO: Add your message handler code here and/or call default if(nIDEvent==1){ }

len=1;Slave_GetDIData(hSlave4055,recbuf,&len);//读取4055数字量输入端口数据 str.Format(”0x%02x:%d“,recbuf[0],count);

m_getDI.SetWindowText(str);count=count+1;

CDialog::OnTimer(nIDEvent);

} } void CSample4055::OnButtonSetvalue()//设定4055数字量输出端口值 { // TODO: Add your control notification handler code here if((Mgr_IsStarted()==1)&&(Slave_IsConnected(hSlave4055)==1))

{

UpdateData(true);

outvalue=strtol(m_invalue,NULL,16);//按十六进制进行读取 if(outvalue >= 0 && outvalue <= 255){

buf[0]=(unsigned short)strtol(m_invalue,NULL,16);

Slave_SendData(hSlave4055,0x20,buf,1);//发送数据 } else { } } else { MessageBox(”请输入00~FF之间的十六进制数“);

MessageBox(”系统未启动或从站未连接,请查看后再进行操作“);}

(3)2路模拟量输出模块iCAN4210的编程使用 实验代码如下:

首先添加所用变量的申明: ROUTECFG cfg;

HANDLE hRoute=0;//新的ICAN网络 HANDLE hSlave4210=0;//MACID=2

控制代码:

void CSample4210::OnBUTTONStartCANSys(){ // TODO: Add your control notification handler code here } 8

cfg.iCardType=4;//使用usbcan2接线口 cfg.iCardInd=0;//卡序号

cfg.iCANInd=0;//CAN通道选择(0表示0通道;1表示1通道)cfg.wCANBaud=0x001c;//波特率的设定0x001c(500kbps)cfg.iMasterCycle=500;//主站循环周期 cfg.wMasterID=0;//主站ID

Mgr_AddRoute(cfg,&hRoute);//添加iCAN网络

if(Mgr_StartSys()!=ICANOK)//调用Mgr_StartSys()函数对CAN网络是否启动进行判断,返回为ICANOK

} void CSample4210::OnButtonLink4210(){

// TODO: Add your control notification handler code here if(Mgr_IsStarted()!=1){ { } else { } MessageBox(”CAN网络已启动“);MessageBox(”系统启动失败“);

MessageBox(”系统未启动或启动失败,请先启动CAN网络“);

} else { // TODO: Add your control notification handler code here Route_AddSlave(hRoute,2,&hSlave4210);

if(Slave_Connect(hSlave4210)!=ICANOK){ } MessageBox(”4210连接失败“);

else

} void CSample4210::OnButtonCanok(){ if((Mgr_IsStarted()==1)&&(Slave_IsConnected(hSlave4210)==1)){ } } MessageBox(”4210连接成功“);

{ unsigned char buf[32]={0};

UpdateData(true);if(m_setch0>=0.0&&m_setch0<=10.0){

buf[1]=(unsigned short)(m_setch0/10)*65535;

buf[0]=(unsigned short)((m_setch0/10)*65535)>>8;

} else { } if(m_setch1>=0.0&&m_setch1<=10.0)MessageBox(”提示:请输入0~10V电压“);

{

buf[3]=(unsigned short)(m_setch1/10)*65535;

buf[2]=(unsigned short)((m_setch1/10)*65535)>>8;

}

else { } MessageBox(”提示:请输入0~10V电压“);

Slave_SendData(hSlave4210,0x60,buf,4);

} else {

MessageBox(”系统未启动或从站未连接,请查看后再进行操作“);}(4)8路模拟量输入模块iCAN4017 首先,在生成的.h头文件中添加使用到的变量的申明。public:

unsigned char recbuf[16];unsigned long len;int count;} 在.cpp文件中首先添加iCAN网络定义和申明以及变量的初始化操作。

ROUTECFG cfg;HANDLE hRoute=0;//新的ICAN网络

HANDLE hSlave4017=0;//AI模块4017,MACID=3

CSample4017::CSample4017(CWnd* pParent /*=NULL*/){

: CDialog(CSample4017::IDD, pParent)//{{AFX_DATA_INIT(CSample4017)m_valuech0 = 0.0;m_valuech1 = 0.0;m_valuech2 = 0.0;

} m_valuech3 = 0.0;m_counter = 0;//}}AFX_DATA_INIT recbuf[0]=0;recbuf[1]=0;recbuf[2]=0;recbuf[3]=0;recbuf[4]=0;recbuf[5]=0;recbuf[6]=0;recbuf[7]=0;len=0;count=0;void CSample4017::OnBUTTONStartCANSys(){

// TODO: Add your control notification handler code here cfg.iCardType=4;//使用usbcan2接线口 cfg.iCardInd=0;//卡序号

cfg.iCANInd=0;//CAN通道选择(0表示0通道;1表示1通道)cfg.wCANBaud=0x001c;//波特率的设定0x001c(500kbps)cfg.iMasterCycle=500;//主站循环周期 cfg.wMasterID=0;//主站ID

Mgr_AddRoute(cfg,&hRoute);//添加iCAN网络

if(Mgr_StartSys()!=ICANOK)//调用Mgr_StartSys()函数对CAN网络是否启动进行判断,返回为ICANOK

{

} } else { } MessageBox(”系统启动失败“);MessageBox(”CAN网络已启动“);void CSample4017::OnButtonLink4017(){

// TODO: Add your control notification handler code here if(Mgr_IsStarted()!=1){

MessageBox(”系统未启动或启动失败,请先启动CAN网络“);

} else { // TODO: Add your control notification handler code here Route_AddSlave(hRoute,3,&hSlave4017);if(Slave_Connect(hSlave4017)!=ICANOK){ } MessageBox(”4017连接失败“);

else

{ }

SetTimer(1,1000,NULL);} MessageBox(”4017连接成功");} void CSample4017::OnTimer(UINT nIDEvent){

// TODO: Add your message handler code here and/or call default if(nIDEvent==1){

Slave_GetAIData(hSlave4017,recbuf,&len);

m_valuech0=((double)(recbuf[0]*16*16+recbuf[1])-0x8000)*10/(double)0x8000;

m_valuech1=((double)(recbuf[2]*16*16+recbuf[3])-0x8000)*10/(double)0x8000;

m_valuech2=((double)(recbuf[4]*16*16+recbuf[5])-0x8000)*10/(double)0x8000;

m_valuech3=((double)(recbuf[6]*16*16+recbuf[7])-0x8000)*10/(double)0x8000;

}

篇3:北邮-信息与网络实验报告一

信息网络应用基础实验报告

实验一

静态网页的设计

学院:电子工程学院

班级:

姓名:

学号:

一、实验主题

1、设计主题:本次实验我设计的该网页主题是围绕当前热门的多人联机在线网游DOTA2进行的。并对该游戏的由来、背景及其内容做了一些简要的描述。

2、功能:在主页中可以观看该游戏的宣传视频以及该游戏的一些精美的图片,并且通过选择相应选项可以了解更多的游戏内容。

3、运行流程:

① 首先打开主页时可以选择播放视频,并且看到丰富的图片;

② 然后点击相应的选项可以进入到分别的附页中查看内容;

③ 并且在主页点击最下的图片可以回到主页顶部,在其他页面点击最下的图片也可以回到主页。

4、实现功能的html技术:

① 在主页中观看视频利用的是html多媒体中的标签插入一个视频的URL进行播放;

② 在页面中的图片是利用了html多媒体中的标签进行图片的加入;

③ 设置页面的背景图片是在标签中加入background参数即可;

④ 在页面内、本机页面间及本机文档连接互联网页面时则是利用了超链接的三种方法建立;

⑤ 在页面中显示表格则是利用了相关的表格创建的语句来建立一个表格,并且可以对表格中插入图片并且可以改变表格的背景颜色以及背景图片。

二、实验内容运行结果

① 打开主页可以看到插入的图片以及背景图片

② 点击页面中插入的视频,点击播放即可以进行播放

插入视频的html代码如下:

③ 点击主页中的超链接则可以跳转到相应的页面。如:

点击英雄介绍链接

则可以显示英雄介绍页面

当选择一个类型的英雄时可以在本页面跳转到对应类型的介绍

当选择某个英雄时则可以链接到互联网上的详细介绍页面

④ 当在副页面点击最下面的图片则可以跳转到主页面

⑤ 在页面中建立的表格并且改变表格背景颜色并且插入图片

三、实验心得与感受

本次实验真正的了解到了如何设计一个最基本的网页,也是将所学的html语言的知识进行了充分的应用,也对这些知识有了更加可视化的了解。由于是第一次进行网页的设计,我选择的是利用记事本来编辑html代码来进行设计的,由于代码都是利用各种标签手动输入的,所以对语句有了深刻的记忆,包括在以后的学习中也会很好的利用它们。我认为这样相对于利用dreamweaver来设计有很多的好处,因为这样第一次可以让我们了解页面的每一部分是怎么实现的,不过在了解过后可以选择软件来设计,因为那样更加具有可视化且方便。

在设计的过程中,也遇到了不少的困难。首先感觉就是对于一个网页的背景图片选择来说比较困难,因为在网页中不会对一个图片进行伸缩,显示的是图片本身的大小,所以只好找到与页面较符合的图片。而且在插入视频时,我利用书中的代码写入时不能在页面中无法播放视频。后来我在网上查阅相关资料,后来直接利用视频网站中的分享视频的代码加入即可在页面中显示一个可播放的视频。

篇4:邝坚_北邮嵌入式实验报告

一、实验要求

题目:支持消息驱动模式的实时软件框架

目的:在充分理解嵌入式处理器特点、RTOS 及强实时嵌入式系统软件设计规范的基础上,构建自己的实时系统软件框架基本功能,并在其上自拟应用(如部分模拟TCP 的C/S两端通信流程),测试软件框架的相关功能。

环境:VxWorks 的VxSim 仿真环境或2440(ARM920T)内容: 必选功能:

1.消息驱动的Task 统一框架,包含统一消息格式定义及使用规范; 2.支持消息驱动模式的软定时器的机制; 3.Task 启动同步功能;

4.体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。

可选功能(加分):

其它有利于实时处理的有效机制,如:无信号量(互斥)支持的临界资源访问方式,zero copy 等;

二、实现的功能

1.消息驱动的Task 统一框架,包含统一消息格式定义及使用规范; STATUS Task(){ Initialization(MBox, Data Structure, Timer, etc.)Forever{ MsgReceive If(…){ …… }else if(…){ …… } ……

} } typedef struct _MESSAGE { int mType;

/* 消息类型 0:timer->client *1:client->server 2:server->client*/ int mSendId;/* 发送任务的MESSAGE ID */ int mRecvId;/* 接收任务的MESSAGE ID */ int mData;/* 消息中传递的数据 */ }MESSAGE;2.支持消息驱动模式的软定时器的机制;

/* timer(id)向客户端消息队列定时发送的定时器*/ STATUS timer(int id){ MESSAGE* txMsg;/* 用于从消息队列中接收消息 */ int tick;/*创建一个定时,用于提醒发送者任务定时发送消息*/ tick=sysClkRateGet();semTake(semSynStart,WAIT_FOREVER);FOREVER {

taskDelay((int)(tick*DELAY_SECOND));txMsg =(MESSAGE*)memMalloc(MAX_MSG_LEN);txMsg->mType = 0;txMsg->mSendId = MID_TIMER(id);txMsg->mRecvId = MID_CLIENT(id);txMsg->mData = 0;printf(“tTimer%d send message to tClient%d!n”,id,id);if(msgQSend(msgQIdClient[id],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_{ return(ERROR);} PRI_NORMAL)== ERROR)

} } 3.Task 启动同步功能;

由manager()创建的任务优先级最高,先创建timer()、server()、client()的任务,让他们都在等待信号量semSynStart而被阻塞,最后创建manager()的任务,占据CPU,等待其他所有任务都被阻塞,解锁所有等待信号量的任务,让它们同时启动。/* progStart()启动实例程序*/ STATUS progStart(void){

int id;/* 用来区分不同的定时器或者客户任务 */ mallocPtr=&sysMalloc;mallocPtr->frontBlock = 0;return(OK);

initialPtr = initial();tidServer = tidManager = 0;for(id = 0;id < NUM_CLIENT;id++){ tidClient[id] = 0;} for(id = 0;id < NUM_TIMER;id++){

} /* 创建消息队列 */ msgQIdServer = msgQCreate(MAX_MSGS, MAX_MSG_LEN, MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR_NOTIFY);if(msgQIdServer == NULL){

} for(id = 0;id < NUM_CLIENT;id++){

} semSynStart = semBCreate(SEM_Q_FIFO | SEM_EVENTSEND_ERR_NOTIFY,SEM_EMPTY);semMalloc = semBCreate(SEM_Q_PRIORITY,SEM_FULL);semFree = semBCreate(SEM_Q_PRIORITY,SEM_FULL);/* 创建任务 */ tidServer = taskSpawn(“tServer”, 220, 0, STACK_SIZE,(FUNCPTR)server,0,0,0,0,0,0,0,0,0,0);for(id = 0;id < NUM_CLIENT;id++){

char tempName[20];sprintf(tempName, “tClient%d”, id);tidClient[id] = taskSpawn(tempName, 210, 0, STACK_SIZE, msgQIdClient[id] = msgQCreate(MAX_MSGS, MAX_MSG_LEN, if(msgQIdClient[id] == NULL){ return(ERROR);} MSG_Q_FIFO|MSG_Q_EVENTSEND_ERR_NOTIFY);return(ERROR);tidTimer[id] = 0;(FUNCPTR)client,id,0,0,0,0,0,0,0,0,0);} for(id = 0;id < NUM_TIMER;id++){

} tidManager = taskSpawn(“tMannager”, 200, 0, STACK_SIZE,(FUNCPTR)manager,0,0,0,0,0,0,0,0,0,0);printf(“programe start!n”);return(OK);} /* manager()管理进程,实现task同步*/ STATUS manager(){ int id;while(taskIsSuspended(tidServer)|| taskIsReady(tidServer))

{ while(taskIsSuspended(tidClient[id])|| taskDelay(10);taskIsReady(tidClient[id]))

} for(id = 0;id < NUM_TIMER;id++){

} semFlush(semSynStart);return(OK);} /* server()处理来自各个客户任务的消息*/ STATUS server(void){ …… while(taskIsSuspended(tidTimer[id])|| taskIsReady(tidTimer[id]))taskDelay(10);taskDelay(10);for(id = 0;id < NUM_CLIENT;id++)char tempName[20];sprintf(tempName, “tTimer%d”, id);tidTimer[id] = taskSpawn(tempName, 230, 0, STACK_SIZE,(FUNCPTR)timer,id,0,0,0,0,0,0,0,0,0);semTake(semSynStart,WAIT_FOREVER);FOREVER { } return(OK);} /* timer(id)向客户端定时发送的定时器*/ STATUS timer(int id){ ……

semTake(semSynStart,WAIT_FOREVER);FOREVER { } /*client(id)向服务器任务发请求消息*/ STATUS client(int id){ ……

semTake(semSynStart,WAIT_FOREVER);FOREVER { } return(OK);} 4.体现前次实验中实现的自定义内存管理机制,最大限度降低外部碎片对系统可靠性的威胁。

静态内存的数据结构为单链表,采用头插法,申请内存时,修改firstavailable另其指向第二块,将firstavailable指向的头块取出,回收内存时,将回收的块的frontBlock指向第一块,修改firstavailable另其指向回收的块,将回收的块作为第一块,数据结构如下所示: …… ……

} return(OK);…… poolpoolHeadnextfirstavailable blockHeadfrontBlockblockHeadfrontBlockblockHeadfrontBlockblockHeadpoolHeadfirstavailableblockHeadfrontBlockblockHeadfrontBlockblockHeadfrontBlockblockHead 静态分配了含有32个16B块的内存池和含有16个256B块的内存池,如果申请的内存大于256B,调用系统malloc。

/*initial()初始化内存池*/ pool* initial(void){ int i;pool* mem;pool* poolPtr;poolHead* poolHeadPtr;blockHead* blockHeadPtr;

mem=(pool*)malloc(6000);/*分配6000B内存作为内存池*/

/*初始化pool*/ poolPtr =(pool*)mem;poolPtr->poolNum = 2;poolPtr->pool =(poolHead*)((char*)mem + sizeof(pool));/*pool指向申请内存区尾*/

/*初始化pool 1 该内存池分配大小为16B的内存*/ poolHeadPtr =(poolHead*)((char*)mem + sizeof(pool));/*初始化内存池的首地址*/ poolHeadPtr->available = 32;/*初始化可用块数32*/ poolHeadPtr->blockSize = 16;/*块大小16B*/ blockHeadPtr =(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));初始化块的首地址*/ poolHeadPtr->firstavailable = blockHeadPtr;/*初始化第一块可用块的地址*/ poolHeadPtr->next=(poolHead*)((char*)poolHeadPtr + sizeof(poolHeadPtr)

/*+ 32*(sizeof(blockHead)+16));/*next指向第二个内存池 */

blockHeadPtr->poolId =1;blockHeadPtr->frontBlock = 0;

for(i=1;i<32;i++)/*将该内存池划分为32个容量16B的内存块*/ {

址*/ } /*初始化pool 2 该内存池分配大小为256B的内存*/ poolHeadPtr = poolHeadPtr->next;poolHeadPtr->available = 16;/*初始化可用块数16*/ poolHeadPtr->blockSize = 256;/*块大小256*/

blockHeadPtr =(blockHead*)((char*)poolHeadPtr+sizeof(poolHead));

poolHeadPtr->firstavailable = blockHeadPtr;poolHeadPtr->next = 0;

blockHeadPtr->poolId =2;blockHeadPtr->frontBlock = 0;

for(i=1;i<16;i++)/*将该内存池划分为16个容量256B的内存块*/ {

} return(pool*)mem;} blockHeadPtr=(blockHead*)((char*)blockHeadPtr + blockHeadPtr->poolId = 2;/* pool号为2,表示他是256B容量的*/ blockHeadPtr->frontBlock = poolHeadPtr->firstavailable;poolHeadPtr->firstavailable = blockHeadPtr;(sizeof(blockHead)+256));

blockHeadPtr=(blockHead*)((char*)blockHeadPtr + blockHeadPtr->poolId = 1;/* pool号为1,表示他是16B容量的*/ blockHeadPtr->frontBlock = poolHeadPtr->firstavailable;/* 当前首poolHeadPtr->firstavailable = blockHeadPtr;/* 求下一首个可用块地(sizeof(blockHead)+16));/*块的首址移动16加结构体的开销长度*/ 个可用块地址赋给frontBlock */

/*memMalloc()分配内存*/ void* memMalloc(int Size){ void* mem;poolHead* poolHeadPtr;blockHead* blockHeadPtr;

semTake(semMalloc,WAIT_FOREVER);

poolHeadPtr = initialPtr->pool;

if((Size <= 16)&&(poolHeadPtr->available!= 0))/*长度小于16时,分配长度为16的内存空间*/ {

blockHeadPtr = poolHeadPtr->firstavailable;/*首个可用块地址赋给poolHeadPtr->firstavailable = blockHeadPtr->frontBlock;/*改变下poolHeadPtr->available--;/*可用块数减一*/ semGive(semMalloc);分配块的首地址*/ 一第一可用块的地址*/

return(void*)((char*)blockHeadPtr + sizeof(blockHead));/*分配内存时加入块头开销*/ } else if((Size <= 256)&&((poolHeadPtr->next)->available!= 0))

{

} else

{ printf(“n[Warning] : Too large for blocks or the blocks are /*其他情况用系统的内存分配函数malloc分配*/ blockHeadPtr =(poolHeadPtr->next)->firstavailable;(poolHeadPtr->next)->firstavailable = blockHeadPtr->frontBlock;(poolHeadPtr->next)->available--;semGive(semMalloc);return(void*)((char*)blockHeadPtr + sizeof(blockHead));/*长度大于16小于256时,分配长度为256的内存空间*/ exhausted n”);

} } /*memFree()释放内存空间*/ void memFree(void* dataPtr){ char* mem=(char*)dataPtr;poolHead* poolHeadPtr;blockHead* blockHeadPtr;

semTake(semFree,WAIT_FOREVER);

poolHeadPtr = initialPtr->pool;/*恢复内存池首址*/ blockHeadPtr =(blockHead*)((char*)memsizeof(blockHead));Timer0Timer1Timer9ClientMsgQ0ClientMsgQ1……ClientMsgQ9Client0Client1Client9ServerMsgQserver6.zero copy 消息队列存储的是指向消息的指针,从而实现了零拷贝。#define MAX_MSG_LEN sizeof(MESSAGE*)MESSAGE* rxMsg;/* 用于从消息队列中接收消息 */ MESSAGE* txMsg;/* 用于向消息队列中发送消息 */ msgQReceive(msgQIdServer,(char*)&rxMsg,MAX_MSG_LEN,WAIT_FOREVER);

msgQSend(msgQIdClient[mSendId],(char*)&txMsg,MAX_MSG_LEN,WAIT_FOREVER,MSG_PRI_NORMAL);

三、运行结果

在shell中输入progStart,观察VxSim,输入progStop结束。

四、心得

实验中遇到了各种各样的问题,特别是代码调试,对报错的分析,定位错误,但是通过不懈努力,完成了本次实验,让我对课堂上所讲的内容有了更深刻的认识,对嵌入式实时操作系统有了更深的理解。

篇5:北邮微机硬件实验报告

实验报告

班级: 姓名: 学号: 指导老师: 学院:

北京邮电大学

一、实验要求

1、遥控对象8个,被控制设备用LED分别代替,LED发光表示工作。接收机与发射机的距离不小于2米。2、8路设备中的一路为LED灯,用指令遥控LED灯亮度,亮度分为8级并用数码管显示级数。

3、在一定的发射功率下,尽量增大接收距离。

4、增加信道干扰措施。

二、实验步骤

1、实验前的准备工作

分析题目,对各个模块进行详细的设计,查找要使用的芯片的管脚图、功能表等,设计整体电路,详细到各个管脚的连线、所接电阻电容的大小、电路工作频率等。

2、搭建电路

按照设计的电路图搭建电路,电路分为发射和接收两部分,搭建时一定要耐心细致,避免错误,连线应当清晰明了,方便后期电路的检查和调试,各模块间最好相互独立,搭线时注意VCC和地线的连接。总之,搭建电路就是要细心、耐心。

3、电路调试与改进

这是本次实验的重点和难点,也是最耗费时间和精力的部分。往往在电路调试中会发现实验电路的一些细节性错误。如果在电路确认无误的情况下却仍然得不到期望的结果,就要考虑电路的改进了,主要是要改变一些所连接的电阻和电容的值。当然,问题也可能出在面包板上,我们所用的面包板由于长期的使用,有一些插口之间发生了短路,或者接触不良,都将会影响我们的实验结果,所以这也是一个需要考虑和检查的地方。

三、芯片选择以及具体电路图

见《简易红外遥控系统设计方案》

四、实验截图

发射管的输出波形:

接收波形:

五、实验中遇到的问题及解决方法

1、无线接收问题。

很多同学都遇到了这个问题,使用有线连接时能够得到想要的输出,使用无线时却根本收不到信号。通过示波器对各个管脚输出进行检测,发现问题出在CX20106这个芯片。后来通过改变CX20106芯片管脚所接的电阻,得到了输出,接受到了信号。

2、数码管显示问题

在发射和接收都调试好后,我发现我的数码管在开关拨1和拨4的时候都只显示0,用示波器检查输出没有错误,怀疑是面包板插口下面短路了,于是重新换了个位置插,结果就输出显示正确了。验证了是面包板的问题。

六、心得体会

这次的小学期为期一周,我选择的题目是简易红外遥控系统设计,因为在网上找到了上一届学长的设计方案,因此方案设计这个较为困难的步骤就比较投机取巧地解决了。

然后是按照设计方案搭建电路,搭建电路是一件不困难但要细致的工作。事实也证明,我们大多数同学都很快的完成了电路的搭建,但调试却不那么顺利,最后检查会发现很多细节上的遗漏或错误。对于我们的电路而言,任何一个细节的错误都可能导致结果的失败。

在电路搭建完成并且检查完成后,我开始用示波器检查每个芯片的输出管脚,在发射模块的调制部分,一开始NE555D的输出不正确,检查电路连接也没有错误,芯片也是好的,最后只能重插了该电路,结果就对了,所以之前应该是面包板某个地方短路了,事实证明我们用的面包板某些插口间短路或者接触不良是个还比较普遍存在的问题。总之发射部分比较顺利。

至于接收部分,当我从发射部分直接连线过去,结果很快就出来了,本来还挺高兴,结果用无线时接收部分却一点反应都没有。由于对芯片的了解并不深,一开始只是盲目按照学长的设计方案连线,连线完成后结果出不来,瞬间有种手足无措的感觉,无奈只好自己又重新学习认识了一下用到的几块芯片,尝试着改变一些管脚所接的电阻和电容,后来又重新搭建了两次电路,调试了三天终于有了结果。

通过这次课程设计,我不仅提高了动手能力,还学会了一些道理,那就是不能投机取巧,打好基础最重要。试想如果一开始自己先好好研究芯片和电路而不是为了省事儿直接用学长的电路,后期的调试就不会那么困难,结果也应该会更快出来。

上一篇:花卉学试题答案下一篇:一年级语文:《画》教学反思