北邮嵌入式系统设计实验-实验报告

北邮嵌入式系统设计实验-实验报告
北邮嵌入式系统设计实验-实验报告

嵌入式实验报告

学院:xxx

班级:xxx

学号:xxx

姓名:xxx

成员:xxx

一、基础知识部分

1.多线程实验

本章主要讲解线程的概念和线程间的同步方式。实验一主要介绍线程的概念和线程的创建,实验二、实验三、实验四分别介绍了信号量、互斥锁、条件变量的作用和使用。

1.1 线程的介绍

线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。线程是允许应用程序并发执行多个任务的一种机制,是程序运行后的任务处理单元,也是SylixOS操作系统任务调度的最小单元。在多核CPU中,同时可以有多个线程在执行,实现真正意义上的并行处理。

线程入口函数是一个能够完成特定任务的函数,因此线程入口函数的编写上与普通函数没有太多区别。线程的创建函数如下:

●创建线程失败,函数返回非0的错误代码,成功返回0;

●*thread pthread_t类型的缓冲区,保存一个线程的线程ID;

●*attr 设置线程属性,设置为NULL标识创建的新线程使用默认属性;

●*(*start_routine) 线程入口函数函数名

●*arg 向所创建线程传入的参数

1.2 信号量的概念

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。

信号量是一个在进程和线程中都可以使用的同步机制。信号量类似于一个通知,某个线程发出一个通知,等待此通知的线程收到通知后,会执行预先设置的工作。当接收通知的线程没有收到通知前,会处于阻塞状态。

信号量可以连续发送多次,处理线程同样也会处理多次。信号量实质是一个计数器,信号量发送一次,计数值增加1,信号量每获取一次,计数值就减1,当计数值为0时,等待信号量线程阻塞。等待信号量过程中,还可以设置等待时间,超过设定时间,等待信号量的线程就不会继续等待,而是继续执行后续任务。

1.3 互斥锁

在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。

互斥锁是避免在同一时间共享资源被多个线程同时访问。互斥锁在使用时类似一把锁,在访问共享资源前对其上锁,在访问完成后,将此资源解锁以便其他线程可以访问。

任何试图访问已经被上锁资源的的线程都会被阻塞,直至访问的资源被解锁。如果该资源解锁时有多个试图访问资源的线程被阻塞,那么只有一个线程会被唤醒访问共享资源,SylixOS唤醒原则采用基于优先级的判断,优先级高的优先被唤醒。

1.4 条件变量

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。

互斥锁能够解决多线程中访问资源冲突的问题,其状态非常简单,只有上锁和解锁两种状态。当线程之间有其他需要同步的条件时,使用互斥锁会十分不方便。比如将线程设置为等待某一个条件满足后开始工作,这个时候使用互斥锁,只能频繁的查询该状态,这样会宝贵的CPU资源。这时使用条件变量是一个更合适的解决方案。

条件变量能够给多个线程提供一个会合的场所,条件变量与互斥锁一起使用,允许线程以无竞争的方式等待特定的条件发生。条件变量本身需要使用互斥锁保护,在改变条件变量之前需要使用互斥锁对其上锁。

1.5信号量与互斥锁的区别

信号量强调的是线程(或进程)间的同步:“信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作。当信号量为单值信号量时,也可以完成一个资源的互斥访问。

互斥锁(又名互斥量)强调的是资源的访问互斥:互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候锁和信号量会同时使用的”

也就是说,信号量不一定是锁定某一个资源,而是流程上的概念,比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。而线程互斥量则是“锁住某一资源”的概念,在锁定期间内,其他线程无法对被保护的数据进行操作。在有些情况下两者可以互换。

条件变量常与互斥锁同时使用,达到线程同步的目的:条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足。在发送信号时,如果没有线程等待在该条件变量上,那么信号将丢失;而信号量有计数值,每次信号量post操作都会被记录。

2.多进程实验

本章主要讲述进程相关概念、进程的创建、退出和进程间的通信。针对进程的创建和进程间通信设计了3组实验,实验一主要讲述进程的创建,实验二和实验三讲述了进程间通信常用的2种方式。

2.1 进程的介绍

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

进程是一个可执行程序的实例。一个编译后的可执行程序在操作系统中运行后,就成为了一个进程,如果执行了两次,就创造了两个进程。从资源管理的角度看,一个进程会独占一些资源,如地址空间、程序代码、文件描述符表和程序运行的其他必要数据集合。其他进程中的函数无法访问此进程的资源,同样此进程的函数也无法访问其他进程中的资源。比如进程1打开了串口1,那么进程2就无法使用进程1打开的串口文件描述符向串口1收发数据。

进程在操作系统中使用进程号(进程ID)表示,进程ID是一个非负整数,用以唯一标识系统中的某个进程。

2.2 进程的创建

进程管理主要是指进程的创建和退出。在Linux/Unix中,进程的创建往往通过fork 函数和exec函数配合使用来完成,fork函数从一个进程(父进程)复制出一个新的进程(子进程),随后子进程调用exec函数装载一个新的可执行文件替换当前进程代码,从而实现一个进程启动另外一个进程。

2.3 进程间通信

2.2.1共享内存

共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。

共享内存是允许两个或多个进程读写一个共享的物理存储区域。因为数据不需要在进程间进行复制,因此共享内存是速度最快的进程间通信方式。但共享内存本身也存在一些不足,由于共享内存的数据会被两个或多个进程操作,如果两个进程同时向共享内存写入数据,会产生冲突。而且当一个进程向共享内存区域写入数据后,另外的进程也无法“知道”共享内存的数据发生了变化。因此共享内存通常会与另一种进程通信方式如:信号量组合使用。由信号量实现两个进程的同步,共享内存实现数据的交换。

信号量分为互斥信号量与普通信号量,互斥信号量用来解决多个进程(或线程)对共享数据对象访问时的互斥问题;普通信号量(计数信号量或二值信号量)用来解决(进程)线程直接同步通信问题。可以把信号量理解为是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行发送和获取操作。当信号量被发送一次,其数值就增加1,当信号量大于0的时候,等待此信号量的进程会从阻塞状态转为就绪状态,并将信号量减1。进程间通过信号量来实现简单的同步。信号量有命名信号量和匿名信号量,本实验使用命名信号量实现进程间的同步。

共享内存的使用流程:

●创建打开共享内存文件并设置文件大小;

●将内存文件映射到实际的物理内存上;

●创建信号量实现使用共享内存通信的两个进程间的同步;

●对内存进行读写操作;

●取消共享内存的内存映射、关闭共享内存文件。

2.2.2消息队列

消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。

消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。消息队列是内核提供给各个进程之间传递消息的通信机制。消息队列的使用流程:

●使用mq_open 函数创建消息队列,创建队列时会设置消息队列的操作权

限和消息关联的键;

●使用mq_send 函数向消息队列发送一个消息;

●使用mq_receive 函数从消息队列中读取一个消息;

●如果不再需要消息通信,使用mq_close 函数关闭此消息队列;

●使用mq_unlink函数删除此消息队列。

2.3进程与线程的比较

一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

2) 线程的划分尺度小于进程,使得多线程程序的并发性高。

3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极

大地提高了程序的运行效率。

4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入

口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同

时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

二、基于Qt图形界面的驱动编程实验

1. 实验目的

●理解GPIO输入的应用程序设计方法

●掌握select函数的使用方法

● 掌握QtCreater 程序的开发流程

● 掌握Qt 下操作SylixOS 硬件设备的方法

2. 实验内容

● 创建一个Qt 工程实现对验证平台GPIO 的输出操作

● 实现数码管从0000-9999数字的显示

● 实现显示数字的加减以及清除操作

3. 程序设计流程图

4. 程序源代码及注释

mainwindow.h

#ifndef MAINWINDOW_H

#defineMAINWINDOW_H

#include

#include /*添加qt 线程的头文件*/

namespace Ui {

class MainWindow ;

}

//-----------------------MainWindow类定义(界面主线程)

------------------------------------

class MainWindow:public QMainWindow

{

Q_OBJECT

public:

explicit MainWindow(QWidget*parent=0);

~MainWindow();

privateslots:

void on_pushButton_clicked();//加1按键响应函数

void on_pushButton_2_clicked();//减1按键响应函数

void setnumber(char*p,int i);//inttochar转换

void on_pushButton_3_clicked();//清零按键响应函数

/*

*添加界面主线程的信号槽函数,用来实现与线程的信号对接

*/

void lcdnumValSet(int num);

void on_spinBox_editingFinished();//数字设置窗响应函数

private:

Ui::MainWindow*ui;

/*--------------用于接收gpio驱动函数返回值的一些变量-----------*/ int g_led_flag;

int status;

int fd;

int gpioled;

int ret;

signals:

void send(int num);//线程通信函数

};

//------------------实体按键监督线程(加1)----------------------class MyThread:public QThread

{

Q_OBJECT

public:

MyThread();

void run();//线程函数

int fd;//实体数码管的标志位

privateslots:

void setfd(int num);//信号槽函数,用来实现与主线程的信号对接

void setnumber(char*p,int i);//inttochar转换

signals:

void send(int num);//线程通信函数

};

//------------------实体按键监督线程(减1)----------------------class MyThread_sub:public QThread

{

Q_OBJECT

public:

MyThread_sub();

void run();//线程函数

int fd;//实体数码管的标志位

privateslots:

void setfd(int num);//信号槽函数,用来实现与主线程的信号对接

void setnumber(char*p,int i);//inttochar转换

signals:

void send(int num);//线程通信函数

};

//------------------实体按键监督线程(清零)----------------------class MyThread_clear:public QThread

{

Q_OBJECT

public:

MyThread_clear();

void run();//线程函数

int fd;//实体数码管的标志位

privateslots:

void setfd(int num);//信号槽函数,用来实现与主线程的信号对接

void setnumber(char*p,int i);//inttochar转换

signals:

void send(int num);//线程通信函数

};

#endif//MAINWINDOW_H

Mainwindow.cpp

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include"mainwindow.h"

#include"ui_mainwindow.h"

#defineDIGITLCD_DEVICE"/dev/digitLcd"

#defineDOWNLOAD_MAX32

#defineDLCD_BUF_MAX16

#defineDLCD_NUM_MAX4

#defineDLCD_CHAR_TAG"CHAR-"

#defineDLCD_DOT_TAG"DOT-"

static UCHAR_G_ucDownloadMap[DOWNLOAD_MAX]={

'0','1','2','3','4','5','6','7','8','9',

'A','b','C','d','E','F','G','H','i','J',

'L','o','p','q','r','t','U','y','c','h',

'T',0xFF

};

int smgnumber=0;/*当前显示数值*/

pthread_mutex_t lock;/*互斥锁*/

/****************************************************************************** **类名称:MainWindow

**函数名称:MainWindow

**功能描述:构造函数

******************************************************************************/ MainWindow::MainWindow(QWidget*parent):

QMainWindow(parent),

ui(new Ui::MainWindow)

{

ui->setupUi(this);

status=0;

gpioled=24;

/*--------------申请打开数码管--------------*/

fd=open(DIGITLCD_DEVICE,O_RDWR);

if(fd<0){

printf("canNOTopen%s,error:%s\n",DIGITLCD_DEVICE,strerror(errno));

return;

}

/*--------------创建实体按键监督线程-------------*/

MyThread*myth=new MyThread;

MyThread_sub*myth_sub=new MyThread_sub;

MyThread_clear*myth_clear=new MyThread_clear;

/*--------------建立线程间的通信-----------*/

connect(myth,SIGNAL(send(int)),this,SLOT(lcdnumValSet(int)));

connect(this,SIGNAL(send(int)),myth,SLOT(setfd(int)));

connect(myth_sub,SIGNAL(send(int)),this,SLOT(lcdnumValSet(int)));

connect(this,SIGNAL(send(int)),myth_sub,SLOT(setfd(int)));

connect(myth_clear,SIGNAL(send(int)),this,SLOT(lcdnumValSet(int)));

connect(this,SIGNAL(send(int)),myth_clear,SLOT(setfd(int)));

/*--------------运行3个线程-----------*/

myth->start();

myth_sub->start();

myth_clear->start();

/*--------------将数码管申请打开的返回值送给各线程-----------*/

emit send(fd);

if(pthread_mutex_init(&lock,NULL)!=0){/*初始化互斥锁*/

printf("mutexinitfailed!\n");

return;

}

}

/****************************************************************************** **类名称:MainWindow

**函数名称:~MainWindow

**功能描述:析构函数

******************************************************************************/ MainWindow::~MainWindow()

{

delete ui;

/****************************************************************************** **类名称:MainWindow

**函数名称:lcdnumValSet

**功能描述:设置屏幕led计数,界面主线程的信号槽函数,用来实现与线程的信号对接**输入:int数值

******************************************************************************/ void MainWindow::lcdnumValSet(int num)

{

ui->lcdNumber->display(num);

}

/****************************************************************************** **类名称:MainWindow、MyThread、MyThread_sub、MyThread_clear(相同代码)

**函数名称:setnumber

**功能描述:设置计数(int2char),将int数值转换为4位char数组

**输入:char指针、int

******************************************************************************/ void MainWindow::setnumber(char*p,int i)

{

int n,j;

for(j=0;j<4;j++)

{

n=i%10;

i=(i-n)/10;

memset(p,_G_ucDownloadMap[n],DLCD_NUM_MAX-j);

}

}

void MyThread::setnumber(char*p,int i)

{

int n,j;

for(j=0;j<4;j++)

{

n=i%10;

i=(i-n)/10;

memset(p,_G_ucDownloadMap[n],DLCD_NUM_MAX-j);

}

}

void MyThread_sub::setnumber(char*p,int i)

{

int n,j;

for(j=0;j<4;j++)

{

n=i%10;

i=(i-n)/10;

memset(p,_G_ucDownloadMap[n],DLCD_NUM_MAX-j);

}

}

void MyThread_clear::setnumber(char*p,int i)

{

int n,j;

for(j=0;j<4;j++)

{

n=i%10;

i=(i-n)/10;

memset(p,_G_ucDownloadMap[n],DLCD_NUM_MAX-j);

}

}

/****************************************************************************** **类名称:MainWindow

**函数名称:on_pushButton_clicked

**功能描述:加1按键响应函数

******************************************************************************/ void MainWindow::on_pushButton_clicked()

{

pthread_mutex_lock(&lock);/*对资源上锁*/

printf("add\n");

smgnumber++;/*加1*/

if(smgnumber>=10000)

{

smgnumber=0;

}

char*pbuf;

char buf[DLCD_BUF_MAX];

strcpy(buf,DLCD_CHAR_TAG);

pbuf=buf+strlen(DLCD_CHAR_TAG);

setnumber(pbuf,smgnumber);/*int2char*/

ui->lcdNumber->display(smgnumber);/*屏幕显示*/

ret=write(fd,buf,(strlen(DLCD_CHAR_TAG)+DLCD_NUM_MAX));/*实际数码管显示显示*/ if(ret>0){

//printf("Showkey:%c\n",_G_ucDownloadMap[i]);

}

else{

printf("writecharerror\n");

return;

}

pthread_mutex_unlock(&lock);/*对资源解锁*/

}

/****************************************************************************** **类名称:MainWindow

**函数名称:on_pushButton_2_clicked

**功能描述:减1按键响应函数

******************************************************************************/ void MainWindow::on_pushButton_2_clicked()

{

pthread_mutex_lock(&lock);/*对资源上锁*/

printf("sbb\n");

if(smgnumber<=0)

{

smgnumber=10000;

}

smgnumber--;/*减1*/

char*pbuf;

char buf[DLCD_BUF_MAX];

strcpy(buf,DLCD_CHAR_TAG);

pbuf=buf+strlen(DLCD_CHAR_TAG);

setnumber(pbuf,smgnumber);/*int2char*/

ui->lcdNumber->display(smgnumber);/*屏幕显示*/

ret=write(fd,buf,(strlen(DLCD_CHAR_TAG)+DLCD_NUM_MAX));/*实际数码管显示显示*/ if(ret>0){

//printf("Showkey:%c\n",_G_ucDownloadMap[i]);

}

else{

printf("writecharerror\n");

return;

}

pthread_mutex_unlock(&lock);/*对资源解锁*/

}

/****************************************************************************** **类名称:MainWindow

**函数名称:on_pushButton_3_clicked

**功能描述:清零按键响应函数

******************************************************************************/ void MainWindow::on_pushButton_3_clicked()

{

pthread_mutex_lock(&lock);/*对资源上锁*/

printf("clear\n");

smgnumber=0;/*清零*/

char*pbuf;

char buf[DLCD_BUF_MAX];

strcpy(buf,DLCD_CHAR_TAG);

pbuf=buf+strlen(DLCD_CHAR_TAG);

setnumber(pbuf,smgnumber);/*int2char*/

ui->lcdNumber->display(smgnumber);/*屏幕显示*/

ret=write(fd,buf,(strlen(DLCD_CHAR_TAG)+DLCD_NUM_MAX));/*实际数码管显示显示*/

if(ret>0){

//printf("Showkey:%c\n",_G_ucDownloadMap[i]);

}

else{

printf("writecharerror\n");

return;

}

pthread_mutex_unlock(&lock);/*对资源解锁*/

}

/****************************************************************************** **类名称:MyThread

**函数名称:MyThread

**功能描述:构造函数

******************************************************************************/ MyThread::MyThread()

{

}

/****************************************************************************** **类名称:MyThread

**函数名称:run

**功能描述:进程函数,实现实体按键加1功能

******************************************************************************/ void MyThread::run()

{

int ret;

int fd_button;

fd_set fdset;

int gpio_in_num=36;

/*--------------申请打开按键--------------*/

fd_button=gpiofd(gpio_in_num,0,GPIO_FLAG_TRIG_FALL|GPIO_FLAG_TRIG_RISE);

if(fd_button<=0){

printf("gpiofdcreateerror!");

return;

}

FD_ZERO(&fdset);

/*--------------监督过程(死循环)--------------*/

while(1){

FD_SET(fd_button,&fdset);

/*--------------进入阻塞,等待按键被按下-------------*/

ret=select(fd_button+1,&fdset,NULL,NULL,NULL);

/*--------------按键被按下后,执行响应-------------*/

if(ret==1){

pthread_mutex_lock(&lock);/*对资源上锁*/

printf("add\n");

smgnumber++;/*加1*/

if(smgnumber>=10000)

{

smgnumber=0;

}

char*pbuf;

char buf[DLCD_BUF_MAX];

strcpy(buf,DLCD_CHAR_TAG);

pbuf=buf+strlen(DLCD_CHAR_TAG);

setnumber(pbuf,smgnumber);/*int2char*/

ret=write(fd,buf,(strlen(DLCD_CHAR_TAG)+DLCD_NUM_MAX));/*实际数码管显示显示*/ emit send(smgnumber);/*屏幕显示(将数值发送给界面主线程)*/

if(ret>0){

//printf("Showkey:%c\n",_G_ucDownloadMap[i]);

}

else{

printf("writecharerror\n");

return;

}

pthread_mutex_unlock(&lock);/*对资源解锁*/

/*

*0.2s消抖处理

*/

usleep(200*1000);

}else{

break;

}

}

/*--------------关闭按键--------------*/

::close(fd);

exec();

}

/****************************************************************************** **类名称:MyThread

**函数名称:setfd

**功能描述:线程的信号槽函数,用来实现与主线程的信号对接

******************************************************************************/ void MyThread::setfd(int num)

{

fd=num;

}

/****************************************************************************** **类名称:MyThread_sub

**函数名称:MyThread_sub

**功能描述:构造函数

******************************************************************************/ MyThread_sub::MyThread_sub()

{

}

/****************************************************************************** **类名称:MyThread_sub

**函数名称:run

**功能描述:进程函数,实现实体按键减1功能

******************************************************************************/ void MyThread_sub::run()

{

int ret;

int fd_button;

fd_set fdset;

int gpio_in_num=38;

/*--------------申请打开按键--------------*/

fd_button=gpiofd(gpio_in_num,0,GPIO_FLAG_TRIG_FALL|GPIO_FLAG_TRIG_RISE);

if(fd_button<=0){

printf("gpiofdcreateerror!");

return;

}

FD_ZERO(&fdset);

/*--------------监督过程(死循环)--------------*/

while(1){

FD_SET(fd_button,&fdset);

/*--------------进入阻塞,等待按键被按下-------------*/

ret=select(fd_button+1,&fdset,NULL,NULL,NULL);

/*--------------按键被按下后,执行响应-------------*/

if(ret==1){

pthread_mutex_lock(&lock);/*对资源上锁*/

printf("sub\n");

if(smgnumber<=0)

{

smgnumber=10000;

}

smgnumber--;/*减1*/

char*pbuf;

char buf[DLCD_BUF_MAX];

strcpy(buf,DLCD_CHAR_TAG);

pbuf=buf+strlen(DLCD_CHAR_TAG);

setnumber(pbuf,smgnumber);/*int2char*/

ret=write(fd,buf,(strlen(DLCD_CHAR_TAG)+DLCD_NUM_MAX));/*实际数码管显示显示*/ emit send(smgnumber);/*屏幕显示(将数值发送给界面主线程)*/

if(ret>0){

//printf("Showkey:%c\n",_G_ucDownloadMap[i]);

}

else{

printf("writecharerror\n");

return;

}

pthread_mutex_unlock(&lock);/*对资源解锁*/

/*

*0.2s消抖处理

*/

usleep(200*1000);

}else{

break;

}

}

/*--------------关闭按键--------------*/

::close(fd);

exec();

}

/****************************************************************************** **类名称:MyThread_sub

**函数名称:setfd

**功能描述:线程的信号槽函数,用来实现与主线程的信号对接

******************************************************************************/ void MyThread_sub::setfd(int num)

{

fd=num;

}

/****************************************************************************** **类名称:MyThread_clear

**函数名称:MyThread_clear

**功能描述:构造函数

******************************************************************************/ MyThread_clear::MyThread_clear()

}

/****************************************************************************** **类名称:MyThread_clear

**函数名称:run

**功能描述:进程函数,实现实体按键清零功能

******************************************************************************/ void MyThread_clear::run()

{

int ret;

int fd_button;

fd_set fdset;

int gpio_in_num=39;

/*--------------申请打开按键--------------*/

fd_button=gpiofd(gpio_in_num,0,GPIO_FLAG_TRIG_FALL|GPIO_FLAG_TRIG_RISE);

if(fd_button<=0){

printf("gpiofdcreateerror!");

return;

}

FD_ZERO(&fdset);

/*--------------监督过程(死循环)--------------*/

while(1){

FD_SET(fd_button,&fdset);

/*--------------进入阻塞,等待按键被按下-------------*/

ret=select(fd_button+1,&fdset,NULL,NULL,NULL);

/*--------------按键被按下后,执行响应-------------*/

if(ret==1){

pthread_mutex_lock(&lock);/*对资源上锁*/

printf("clear\n");

smgnumber=0;/*清零*/

char*pbuf;

char buf[DLCD_BUF_MAX];

strcpy(buf,DLCD_CHAR_TAG);

pbuf=buf+strlen(DLCD_CHAR_TAG);

setnumber(pbuf,smgnumber);/*int2char*/

ret=write(fd,buf,(strlen(DLCD_CHAR_TAG)+DLCD_NUM_MAX));/*实际数码管显示显示*/ emit send(smgnumber);/*屏幕显示(将数值发送给界面主线程)*/

if(ret>0){

//printf("Showkey:%c\n",_G_ucDownloadMap[i]);

}

else{

printf("writecharerror\n");

return;

}

pthread_mutex_unlock(&lock);/*对资源解锁*/

/*

*0.2s消抖处理

*/

usleep(200*1000);

}else{

break;

}

}

/*--------------关闭按键--------------*/

::close(fd);

exec();

}

/****************************************************************************** **类名称:MyThread_clear

**函数名称:setfd

**功能描述:线程的信号槽函数,用来实现与主线程的信号对接

******************************************************************************/ void MyThread_clear::setfd(int num)

{

fd=num;

}

/****************************************************************************** **类名称:MainWindow

**函数名称:on_spinBox_editingFinished

**功能描述:修改数值框内数字的响应函数

******************************************************************************/ void MainWindow::on_spinBox_editingFinished()

{

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

嵌入式系统期末实验

一、实验要求 题目:支持消息驱动模式的实时软件框架 目的:在充分理解嵌入式处理器特点、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_ PRI_NORMAL) == ERROR ) { return (ERROR); } } return (OK); } 3. Task 启动同步功能; 由manager()创建的任务优先级最高,先创建timer()、server()、client()的任务,让他们都在等待信号量semSynStart而被阻塞,最后创建manager()的任务,占据CPU,等待其他所有任务都被阻塞,解锁所有等待信号量的任务,让它们同时启动。 /* progStart()启动实例程序*/ STATUS progStart(void) { int id; /* 用来区分不同的定时器或者客户任务 */ mallocPtr=&sysMalloc; mallocPtr->frontBlock = 0;

北邮 通信网实验报告

北京邮电大学实验报告通信网理论基础实验报告 学院:信息与通信工程学院 班级:2013211124 学号: 姓名:

实验一 ErlangB公式计算器 一实验内容 编写Erlang B公式的图形界面计算器,实现给定任意两个变量求解第三个变量的功能: 1)给定到达的呼叫量a和中继线的数目s,求解系统的时间阻塞率B; 2)给定系统的时间阻塞率的要求B和到达的呼叫量a,求解中继线的数目s,以实现网络规划; 3)给定系统的时间阻塞率要求B以及中继线的数目s,判断该系统能支持的最大的呼叫量a。 二实验描述 1 实验思路 使用MA TLAB GUITOOL设计图形界面,通过单选按钮确定计算的变量,同时通过可编辑文本框输入其他两个已知变量的值,对于不同的变量,通过调用相应的函数进行求解并显示最终的结果。 2程序界面 3流程图 4主要的函数 符号规定如下: b(Blocking):阻塞率; a(BHT):到达呼叫量;

s(Lines):中继线数量。 1)已知到达呼叫量a及中继线数量s求阻塞率b 使用迭代算法提高程序效率 B s,a= a?B s?1,a s+a?B(s?1,a) 代码如下: function b = ErlangB_b(a,s) b =1; for i =1:s b = a * b /(i + a * b); end end 2)已知到达呼叫量a及阻塞率b求中继线数量s 考虑到s为正整数,因此采用数值逼近的方法。采用循环的方式,在每次循环中增加s的值,同时调用B s,a函数计算阻塞率并与已知阻塞率比较,当本次误差小于上次误差时,结束循环,得到s值。 代码如下: function s = ErlangB_s(a,b) s =1; Bs = ErlangB_b(a,s); err = abs(b-Bs); err_s = err; while(err_s <= err) err = err_s; s = s +1; Bs = ErlangB_b(a,s); err_s = abs(b - Bs); end s = s -1; end 3)已知阻塞率b及中继线数量s求到达呼叫量a 考虑到a为有理数,因此采用变步长逼近的方法。采用循环的方式,在每次循环中增加a的值(步长为s/2),同时调用B s,a函数计算阻塞率并与已知阻塞率比较,当本次误差小于预设阈值时,结束循环,得到a值。 代码如下: function a = ErlangB_a(b,s)

北邮数字电路综合实验报告

数字电路综合实验报告 简易智能密码锁 一、实验课题及任务要求 设计并实现一个数字密码锁,密码锁有四位数字密码和一个确认开锁按键,密码输入正确,密码锁打开,密码输入错误进行警示。 基本要求: 1、密码设置:通过键盘进行4 位数字密码设定输入,在数码管上显示所输入数字。通过密码设置确定键(BTN 键)进行锁定。 2、开锁:在闭锁状态下,可以输入密码开锁,且每输入一位密码,在数码管上显示“-”,提示已输入密码的位数。输入四位核对密码后,按“开锁”键,若密码正确则系统开锁,若密码错误系统仍然处于闭锁状态,并用蜂鸣器或led 闪烁报警。 3、在开锁状态下,可以通过密码复位键(BTN 键)来清除密码,恢复初始密码“0000”。闭锁状态下不能清除密码。 4、用点阵显示开锁和闭锁状态。 提高要求: 1、输入密码数字由右向左依次显示,即:每输入一数字显示在最右边的数码管上,同时将先前输入的所有数字向左移动一位。 2、密码锁的密码位数(4~6 位)可调。

3、自拟其它功能。 二、系统设计 2.1系统总体框图 2.2逻辑流程图

2.3MDS图 2.4分块说明 程序主要分为6个模块:键盘模块,数码管模块,点阵模块,报警模块,防抖模块,控制模块。以下进行详细介绍。 1.键盘模块 本模块主要完成是4×4键盘扫描,然后获取其键值,并对其进行编码,从而进行按键的识别,并将相应的按键值进行显示。 键盘扫描的实现过程如下:对于4×4键盘,通常连接为4行、4列,因此要识别按键,只需要知道是哪一行和哪一列即可,为了完成这一识别过程,我们的思想是,首先固定输出高电平,在读入输出的行值时,通常高电平会被低电平拉低,当当前位置为高电平“1”时,没有按键按下,否则,如果读入的4行有一位为低电平,那么对应的该行肯定有一个按键按下,这样便可以获取到按键的行值。同理,获取列值也是如此,先输出4列为高电平,然后在输出4行为低电平,再读入列值,如果其中有哪一位为低电平,那么肯定对应的那一列有按键按下。由此可确定按键位置。

北邮通电实验报告

实验3 集成乘法器幅度调制电路 信息与通信工程学院 2016211112班 苏晓玥杨宇宁 2016210349 2016210350

一.实验目的 1.通过实验了解振幅调制的工作原理。 2.掌握用MC1496来实现AM和DSB的方法,并研究已调波与调制信号,载波之间的关系。3.掌握用示波器测量调幅系数的方法。 二.实验准备 1.本实验时应具备的知识点 (1)幅度调制 (2)用模拟乘法器实现幅度调制 (3)MC1496四象限模拟相乘器 2.本实验时所用到的仪器 (1)③号实验板《调幅与功率放大器电路》 (2)示波器 (3)万用表 (4)直流稳压电源 (5)高频信号源 三.实验内容 1.模拟相乘调幅器的输入失调电压调节。 2.用示波器观察正常调幅波(AM)波形,并测量其调幅系数。 3.用示波器观察平衡调幅波(抑制载波的双边带波形DSB)波形。 四.实验波形记录、说明 1.DSB信号波形观察

2.DSB信号反相点观察 3.DSB信号波形与载波波形的相位比较 结论:在调制信号正半周期间,两者同相;负半周期间,两者反相。

4.AM正常波形观测 5.过调制时的AM波形观察(1)调制度为100%

(2)调制度大于100% (3)调制度为30% A=260.0mv B=140.0mv

五.实验结论 我们通过实验了解振幅调制的工作原理是:调幅调制就是用低频调制信号去控制高频振荡(载波)的幅度,使其成为带有低频信息的调幅波。目前由于集成电路的发展,集成模拟相乘器得到广泛的应用,为此本实验采用价格较低廉的MC1496集成模拟相乘器来实现调幅之功能。 DSB信号波形与载波波形的相位关系是:在调制信号正半周期间,两者同相;负半周期间,两者反相。 通过实验了解到了调制度的计算方法 六.课程心得体会 通过本次实验,我们了解了振幅调制的工作原理并掌握了实现AM和DSB的方法,学会计算调制度,具体见实验结论。我们对集成乘法器幅度调制电路有了更好的了解,对他有了更深入的认识,提高了对通信电子电路的兴趣。 和模电实验的单独进行,通电实验增强了团队配合的能力,两个人的有效分工提高了实验的效率,减少了一个人的独自苦恼。

嵌入式实验报告

嵌入式实验报告 学院:信息工程学院 专业:计算机科学与技术班级:计算机班 姓名: 学号: 指导老师:

实验目录 实验一嵌入式系统开发环境实验 (2) 实验二系统节拍定时器实验 (12) 实验三 GPIO控制实验 (16) 实验四外部中断实验 (19) 实验五串口通讯实验 (23)

实验一嵌入式系统开发环境实验 【实验目的】 1.熟悉RealView MDK集成开发环境以及使用方法。 2.熟悉嵌入式系统软件设计方法和流程。 【实验内容】 1. 通过例程熟悉、掌握嵌入式系统的编辑、编译、调试、下载及运行过程。 2. 建立自己的工程文件,在开发板板上调试程序。 【实验步骤】 (一)程序安装 1. 建议在安装之前关闭所有的应用程序,双击安装文件,弹出如图对话框,Next 2.默认选择C盘文件下安装。

3.这样就在c盘底下出现keil文件夹。 4.单击选择菜单“File”-->"License Management" 将弹出下面一张图的界面:复制其中CID号,以便在粘贴到下一步中的破解软件。 5.复制CID

6.运行破解软件,将出现下面一张图的界面,把上步复制的CID号粘贴到相应位置,其他选项如图,然后点击“Generate”按钮,然后复制产生的序列号,粘贴到上一步的下面一张图的LIC输入框中,然后点击右侧的Add LIC,即可完成破解。 7.安装文件夹中的jlink驱动。 (二)工程创建、编译 使用Realview MDK创建、完成一个新的工程只需要以下几个环节: →创建工程并选择处理器→选择工具集→创建源文件→配置硬件选项→配置对应启动代码→编译链接→下载→调试。 1.创建工程并选择处理器 选择Project→New Project…,输入创建的新工程的文件名,即可创建一个新的工程。 2.创建一个新工程时,需要为工程选择一款对应处理器,在NXP 列表下选择LPC1768 芯片。然后点击OK。接下来出现的对话框选择“是或者也可以通过单击Project→Select Device for Target…在本次课程中,我们选择

北邮通信原理实验 基于SYSTEMVIEW通信原理实验报告

北京邮电大学实验报告 题目:基于SYSTEMVIEW通信原理实验报告 班级:2013211124 专业:信息工程 姓名:曹爽 成绩:

目录 实验一:抽样定理 (3) 一、实验目的 (3) 二、实验要求 (3) 三、实验原理 (3) 四、实验步骤和结果 (3) 五、实验总结和讨论 (9) 实验二:验证奈奎斯特第一准则 (10) 一、实验目的 (10) 二、实验要求 (10) 三、实验原理 (10) 四、实验步骤和结果 (10) 五、实验总结和讨论 (19) 实验三:16QAM的调制与解调 (20) 一、实验目的 (20) 二、实验要求 (20) 三、实验原理 (20) 四、实验步骤和结果 (21) 五、实验总结和讨论 (33) 心得体会和实验建议 (34)

实验一:抽样定理 一、 实验目的 1. 掌握抽样定理。 2. 通过时域频域波形分析系统性能。 二、 实验要求 改变抽样速率观察信号波形的变化。 三、 实验原理 一个频率限制在0f 的时间连续信号()m t ,如果以0 12S T f 的间隔进行等间隔均匀抽样,则()m t 将被所得到的抽样值完全还原确定。 四、 实验步骤和结果 1. 按照图1.4.1所示连接电路,其中三个信号源设置频率值分别为10Hz 、15Hz 、20Hz ,如图1.4.2所示。 图1.4.1 连接框图

图1.4.2 信号源设置,其余两个频率值设置分别为15和20 2.由于三个信号源最高频率为20Hz,根据奈奎斯特抽样定理,最低抽样频率应 为40Hz,才能恢复出原信号,所以设置抽样脉冲为40Hz,如图1.4.3。 图1.4.3 抽样脉冲设置 3.之后设置低通滤波器,设置数字低通滤波器为巴特沃斯滤波器(其他类型的 低通滤波器也可以,影响不大),截止频率设置为信号源最高频率值20Hz,如图1.4.4。

北邮微波实验报告整理版

北京邮电大学信息与通信工程学院 微波实验报告 班级:20112111xx 姓名:xxx 学号:20112103xx 指导老师:徐林娟 2014年6月

目录 实验二分支线匹配器 (1) 实验目的 (1) 实验原理 (1) 实验内容 (1) 实验步骤 (1) 单支节 (2) 双支节 (7) 实验三四分之一波长阻抗变换器 (12) 实验目的 (12) 实验原理 (12) 实验内容 (13) 实验步骤 (13) 纯电阻负载 (14) 复数负载 (19) 实验四功分器 (23) 实验目的 (23) 实验原理 (23) 实验内容 (24) 实验步骤 (24) 公分比为1.5 (25) 公分比为1(等功分器) (29) 心得体会 (32)

201121111x 班-xx 号-xx ——电磁场与微波技术实验报告 实验二 分支线匹配器 实验目的 1.熟悉支节匹配器的匹配原理 2.了解微带线的工作原理和实际应用 3.掌握Smith 图解法设计微带线匹配网络 实验原理 支节匹配器是在主传输线上并联适当的电纳(或者串联适当的电抗),用附加的反射来抵消主传输线上原来的反射波,以达到匹配的目的。 单支节匹配器,调谐时主要有两个可调参量:距离d 和由并联开路或短路短截线提供的电纳。匹配的基本思想是选择d ,使其在距离负载d 处向主线看去的导纳Y 是Y0+jB 形式。然后,此短截线的电纳选择为-jB ,根据该电纳值确定分支短截线的长度,这样就达到匹配条件。 双支节匹配器,通过增加一个支节,改进了单支节匹配器需要调节支节位置的不足,只需调节两个分支线长度,就能够达到匹配(但是双支节匹配不是对任意负载阻抗都能匹配的,即存在一个不能得到匹配的禁区)。 微带线是有介质εr (εr >1)和空气混合填充,基片上方是空气,导体带条和接地板之间是介质εr ,可以近似等效为均匀介质填充的传输线,等效介质电常数为 εe ,介于1和εr 之间,依赖于基片厚度H 和导体宽度W 。而微带线的特性阻抗与其等效介质电常数为εe 、基片厚度H 和导体宽度W 有关。 实验内容 已知:输入阻抗Z 75in ,负载阻抗Z (6435)l j ,特性阻抗0Z 75 ,介质基片 2.55r ,1H mm 。 假定负载在2GHz 时实现匹配,利用图解法设计微带线单支节和双支节匹配网络,假设双支节网络分支线与负载的距离114d ,两分支线之间的距离为21 8 d 。画出几种可能的电路图并且比较输入端反射系数幅度从1.8GHz 至2.2GHz 的变化。 实验步骤 1.根据已知计算出各参量,确定项目频率。 2.将归一化阻抗和负载阻抗所在位置分别标在Smith 圆上。 3.设计单枝节匹配网络,在图上确定分支线与负载的距离以及分支线的长度,根据给定的介质基片、特性阻抗和频率用TXLINE 计算微带线物理长度和宽度。此处应该注意电长度和实际长度的联系。 4.画出原理图,在用微带线画出基本的原理图时,注意还要把衬底添加到图中,将各部分的参数填入。注意微带 分支线处的不均匀性所引起的影响,选择适当的模型。 5.负载阻抗选择电阻和电感串联的形式,连接各端口,完成原理图,并且将项目的频率改为1.8—2.2GHz 。 6.添加矩形图,添加测量,点击分析,测量输入端的反射系数幅值。 7.同理设计双枝节匹配网络,重复上面的步骤。

北京邮电大学数字电路实验报告

北京邮电大学 数字电路与逻辑设计实验 实验报告 实验名称:QuartusII原理图输入 法设计与实现 学院:北京邮电大学 班级: 姓名: 学号:

一.实验名称和实验任务要求 实验名称:QuartusII原理图输入法设计与实现 实验目的:⑴熟悉用QuartusII原理图输入法进行电路设计和仿真。 ⑵掌握QuartusII图形模块单元的生成与调用; ⑶熟悉实验板的使用。 实验任务要求:⑴掌握QuartusII的基础上,利用QuartusII用逻辑 门设计实现一个半加器,生成新的半加器图像模 块。 ⑵用实验内容(1)中生成的半加器模块以及逻辑门 实现一个全加器,仿真验证其功能,并能下载到实 验板上进行测试,要求用拨码开关设定输入信号, 发光二级管显示输出信号。 ⑶用3线—8线译码器(74L138)和逻辑门实现要求 的函数:CBA F+ C + =,仿真验证其 + B C B A A A B C 功能,,并能下载到实验板上进行测试,要求用拨 码开关设定输入信号,发光二级管显示输出信号。二.设计思路和过程 半加器的设计实现过程:⑴半加器的应有两个输入值,两个输出值。 a表示加数,b表示被加数,s表示半加和, co表示向高位的进位。

⑵由数字电路与逻辑设计理论知识可知 b a s ⊕=;b a co ?= 选择两个逻辑门:异或门和与门。a,b 为异 或门和与门的输入,S 为异或门的输出,C 为与门的输出。 (3)利用QuartusII 仿真实现其逻辑功能, 并生成新的半加器图形模块单元。 (4)下载到电路板,并检验是否正确。 全加器的设计实现过程:⑴全加器可以由两个半加器和一个或门构 成。全加器有三个输入值a,b,ci ,两个输 出值s,co :a 为被加数,b 为加数,ci 为低 位向高位的进位。 ⑵全加器的逻辑表达式为: c b a s ⊕⊕= b a ci b a co ?+?⊕=)( ⑶利用全加器的逻辑表达式和半加器的逻 辑功能,实现全加器。 用3线—8线译码器(74L138)和逻辑门设计实现函数 CBA A B C A B C A B C F +++= 设计实现过程:⑴利用QuartusII 选择译码器(74L138)的图形模块

嵌入式实验报告

嵌入式技术 实验报告 系别:计算机与科学技术系 班级:计12-1班 姓名:刘杰 学号:12101020128 总成绩: 评语: 日期:

2.在弹出的对话框中依次选择“cedevice emulator emulator kdstub”。 3.选择“Build OS”菜单的“sysgen”开始构建平台。 1.1.4连接,下载和运行平台 1.选择“Target”菜单下的“Connection option”菜单项。 2.在新的对话框中,配置连接关系 3.选择“Target”菜单下的“attach”菜单项,开始下载。 ?实验结果 操作系统定制成功,能正常运行。 ?结果截图 ?问题总结 由于对实验平台了解不够,致使操作过程中添加和删除组件时不知道该如何下手,影响整个实验进度。 实验1.2: 1.打开Platform Builder,并且打开实验1的工程,在实验1的工程基础上做本实验。

进程显示 IE信息查看

报文监测 实验1.3使用Platform Builder开发应用程序 简单实验步骤 1.打开Platform Builder。 2.选择“File”菜单下的“Open Workspace…”,然后打开实验1中创建的平台,本实验要基于 上面的实验的基础上做。 3.选择“File”菜单下的“New Project or File…”,打开“New Project or File”对话框。 4.在“Projects”选项页中选择“WCE Application”;在“Project Name”中输入项目的名字,例 如“MyApp”。 5.在“New Project Wizard – step 1 of 1”中选择“A typical Hello World Application”,点击“Finish” 按钮。 6.选择“Build”菜单中的“Build MyApp.exe”来编译应用程序。

北邮《现代通信技术》实验报告一

现代通信技术实验报告 班级: 2012211110 学号: 2012210299 姓名:未可知

在学习现代通信技术实验课上,老师提到的一个词“通信人”警醒了我,尽管当初填报志愿时选择了通信工程最终也如愿以偿,进入大三,身边的同学忙着保研、考研、出国、找工作,似乎大家都为了分数在不懈奋斗。作为一个北邮通信工程的大三学生,我也不断地问自己想要学习的是什么,找寻真正感兴趣的是什么,通信这个行业如此之大,我到底适合什么。本学期,现代通信技术这本书让我了解到各种通信技术的发展和规划,也让我对“通信人”的工作有了更深刻的认识。 一、通信知识的储备 《现代通信技术》第一页指出,人与人之间通过听觉、视觉、嗅觉、触觉等感官,感知现实世界而获取信息,并通过通信来传递信息。所谓信息,是客观事物状态和运动特征的一种普遍形式,客观世界中大量地存在、产生和传递着以这些方式表示出来的各种各样的信息。信息的目的是用来“消除不可靠的因素”,它是物质运动规律总和。因此,我们通信人的任务就是利用有线、无线等形式来将信息从信源传递到信宿,在传输过程中保证通信的有效性和可靠性。 而具体来讲,要实现信息传递,通信网是必需的通信体系,其中通信网分层的结构形式需要不同的支撑技术,包括业务网技术,向用户提供电话、电报、数据、图像等各种电信业务的网络;介入与传送网技术,实现信息由一个点传递到另一个点或一些点的功能。对此,我们通信工程专业学习课程的安排让我们一步步打下基础,建立起知识储备。 知识树如下: 如知识树所述,通信工程课程体系可以大致分为一下6类基础:

数学基础:工科数学分析,线性代数,复变函数,概率论基础,随机过程; 电路基础:电路分析,模拟电子技术,数字逻辑电路,通信电子电路; 场与波基础:电磁场与电磁波,微波技术,射频与天线; 计算机应用能力:C 语言程序设计,微机原理与接口技术,计算机网络,数据结构,面向对象程序设计,实时嵌入式系统 信号处理类课程:信号与系统,信号处理,图像处理,DSP 原理及应用; 通信类课程:通信原理,现代通信技术,信息论基础,移动通信,光纤通信等。 从大一开始学习的工科数学分析,大学物理,大学计算机基础等课程为基础类课程,旨在培养我们的语言能力,数学基础,物理基础,计算机能力,然后逐步加大难度,细化课程,方向逐渐明朗详细。同时,课程中加入了各种实验,锻炼了我们的动手能力。 二、通信知识的小小应用 实验课上老师说过,以我们所学的知识已经可以制作简单通信的手机的草图了,我对此跃跃欲试。经过思考和调研,以下是我对于简单手机设计的原理框图和思考结果。 一部手机的结构包括接收机、发射机、中央控制模块、电源和人机界面部分,如下图 手机结构设计图 电路部分包括射频和逻辑音频电路部分,射频电路包括从天线到接收机的解调输出,与发射的I/O 调制到功率放大器输出的电路。其中,射频接收电路完成接收信号的滤波、信号放大、解调等功能;射频发射电路完成语音基带信号的调制、变频、功率放大等功能。要用到的超外差接收机、混频器、鉴相器等在《通信电子电路》书本中的知识。逻辑音频包括从接收解调到接收音频输出、送话器电路到发射I/O 调制器及逻辑电路部分的中央处理单元、数字语音处理及各种存储器电路。由核心控制模块CPU 、EEPROM 、 FLASH 、SRAM 等部分组成,一个基本 天线 接收机 发射机 频率合成 电源 逻 辑 音 频 人 机 交 互

北邮arduino实验报告

电子电路综合实验设计 实验名称: 基于 Arduino 的电压有效值测量电路设计与实现 学院: 班级: 学号: 姓名: 班内序号:

实验 基于Arduino 的电压有效值测量电路设计与实现 一. 摘要 Arduino是一个基于开放原始码的软硬件平台,可用来开发独立运作、并具互动性的电子产品,也可以开发与PC 相连的周边装置,同时能在运行时与PC 上的软件进行交互。为了测量正弦波电压有效值,首先我们设计了单电源供电的半波整流电路,并进行整流滤波输出,然后选择了通过Arduino设计了读取电压有效值的程序,并实现使用此最小系统来测量和显示电压有效值。在频率和直流电压幅度限定在小范围的情况下,最小系统的示数基本和毫伏表测量的值相同。根据交流电压有效值的定义,运用集成运放和设计的Arduino最小系统的结合,实现了运用少量元器件对交流电压有效值的测量。 关键字:半波整流整流滤波 Arduino最小系统读取电压有效值 二. 实验目的 1、熟悉Arduino 最小系统的构建和使用方法; 2、掌握峰值半波整流电路的工作原理; 3、根据技术指标通过分析计算确定电路形式和元器件参数; 4、画出电路原理图(元器件标准化,电路图规范化); 5、熟悉计算机仿真方法; 6、熟悉Arduino 系统编程方法。 三. 实验任务及设计要求 设计实现 Arduino 最小系统,并基于该系统实现对正弦波电压有效值的测量和显示。 1、基本要求 (1)实现Arduino 最小系统,并能下载完成Blink 测试程序,驱动Arduino 数字13 口LED 闪烁; (2)电源部分稳定输出5V 工作电压,用于系统供电; (3)设计峰值半波整流电路,技术指标要求如下:

嵌入式实验报告

实验报告(一) 第1学时跑第一个任务 一.实验目的 本实验的目的是了解嵌入式实时操作系统μCOS代码结构,将其跑起来得到直观的认识。 二.实验步骤 1.将包含全部实验代码的压缩文件解压缩 2.将VC6开发环境打开 3.打开experiment1目录下的ucos_vc.dsw 4.用全部编译(rebuild all)编译程序,运行程序,根据窗口提示输出,获得感性认识! 5.根据教材P206页图7.1及7.1.1和7.1.2的内容,写出文件目录结构的说明,说明嵌入式实时操作系统μCOS都由哪些部分组成 (1)与CPU无关的代码: 操作系统配置文件os_config.h 操作系统头文件ucos_ii.h 内核代码os_core.c 任务管理os_task.c 时间管理os_time.c 信息量管理os_sem.c 互斥信号量管理os_mutex.c 信息邮箱管理os_mbox.c 信息队列管理os_q.c 事件标志组管理os_flag.c 内存管理os_mem.c 定时器管理os_tmr.c (2)与CPU相关的代码: 处理器相关头文件os_cpu.h 处理器相关的C代码os_cpu.h 处理器相关汇编代码os_cpu_a.asm。

6.VC环境下,在工程上点鼠标右键,查看工程的设计 7.打开main.c, 使用REBUILD ALL 进行编译,找到可执行文件的输出目录,记录下来 experiment1\OUTPUT\Debug\ucos_vc.exe 8.使用菜单或快捷按钮再次执行编译好的程序。查看运行结果并记录,查看main.c及user.c,分析main.c及user.c代码,解释程序执行的功能。 (1) main.c初始化了操作系统,创建了用户任务usertask (2)user.c定义了用户任务 usertask,循环对一个变量进行加一,并且输出变量值 9.说明任务堆栈的定义位置,任务在什么时候被创建,任务在什么时候获得运行。 Main.c中CONSTANTS里定义了任务堆栈 任务创建: 在任务调度时,当任务在就续表中优先级最高时,任务获得运行 10.自己修改代码,减少延时时间,或将每次加1改为其他算法,查看效果! 第2学时调试模式跑第一个任务

北邮通信原理实验报告

北京邮电大学通信原理实验报告 学院:信息与通信工程学院班级: 姓名: 姓名:

实验一:双边带抑制载波调幅(DSB-SC AM ) 一、实验目的 1、了解DSB-SC AM 信号的产生以及相干解调的原理和实现方法。 2、了解DSB-SC AM 信号波形以及振幅频谱特点,并掌握其测量方法。 3、了解在发送DSB-SC AM 信号加导频分量的条件下,收端用锁相环提取载波的原理及其实现方法。 4、掌握锁相环的同步带和捕捉带的测量方法,掌握锁相环提取载波的调试方法。 二、实验原理 DSB 信号的时域表达式为 ()()cos DSB c s t m t t ω= 频域表达式为 1 ()[()()]2 DSB c c S M M ωωωωω=-++ 其波形和频谱如下图所示 DSB-SC AM 信号的产生及相干解调原理框图如下图所示

将均值为零的模拟基带信号m(t)与正弦载波c(t)相乘得到DSB—SC AM信号,其频谱不包含离散的载波分量。 DSB—SC AM信号的解调只能采用相干解调。为了能在接收端获取载波,一种方法是在发送端加导频,如上图所示。收端可用锁相环来提取导频信号作为恢复载波。此锁相环必须是窄带锁相,仅用来跟踪导频信号。 在锁相环锁定时,VCO输出信号sin2πf c t+φ与输入的导频信号cos2πf c t 的频率相同,但二者的相位差为φ+90°,其中很小。锁相环中乘法器的两个 输入信号分别为发来的信号s(t)(已调信号加导频)与锁相环中VCO的输出信号,二者相乘得到 A C m t cos2πf c t+A p cos2πf c t?sin2πf c t+φ =A c 2 m t sinφ+sin4πf c t+φ+ A p 2 sinφ+sin4πf c t+φ 在锁相环中的LPF带宽窄,能通过A p 2 sinφ分量,滤除m(t)的频率分量及四倍频载频分量,因为很小,所以约等于。LPF的输出以负反馈的方式控制VCO,使其保持在锁相状态。锁定后的VCO输出信号sin2πf c t+φ经90度移相后,以cos2πf c t+φ作为相干解调的恢复载波,它与输入的导频信号cos2πf c t 同频,几乎同相。 相干解调是将发来的信号s(t)与恢复载波相乘,再经过低通滤波后输出模拟基带信号 A C m t cos2πf c t+A p cos2πf c t?cos2πf c t+φ =A c 2 m t cosφ+cos4πf c t+φ+ A p 2 cosφ+cos4πf c t+φ 经过低通滤波可以滤除四倍载频分量,而A p 2 cosφ是直流分量,可以通过隔直

北京邮电大学电路实验报告-(小彩灯)

北京邮电大学电路实验报告-(小彩灯)

电子电路综合实验报告课题名称:基于运算放大器的彩灯显示电路的设计与实现 姓名:班级:学号: 一、摘要: 运用运算放大器设计一个彩灯显示电路,通过迟滞电压比较器和反向积分器构成方波—三角波发生器,三角波送入比较器与一系列直流电平比较,比较器输出端会分别输出高电平和低电平,从而顺序点亮或熄灭接在比较器输出端的发光管。 关键字: 模拟电路,高低电平,运算放大器,振荡,比较 二、设计任务要求: 利用运算放大器LM324设计一个彩灯显示电路,让排成一排的5个红色发光二极管(R1~R5)重复地依次点亮再依次熄灭(全灭→R1→R1R2→R1R2R3→R1R2R3R4→R1R2R3R4R5→R1R2R3R4→R1R2R3→R1R2→R1→全灭),同时让排成一排的6个绿色发光二极管(G1~G6)单光

三角波振荡电路可以采用如图2-28所示电路,这是一种常见的由集成运算放大器构成的方波和三角波发生器电路,图2-28中运放A1接成迟滞电压比较器,A2接成反相输入式积分器,积分器的输入电压取自迟滞电压比较器的输出,迟滞电压比较器的输入信号来自积分器的输出。假设迟滞电压比较器输出U o1初始值为高电平,该高电平经过积分器在U o2端得到线性下降的输出信号,此线性下降的信号又反馈至迟滞电压比较器的输入端,当其下降至比较器的下门限电压U th-时,比较器的输出发生跳变,由高电平跳变为低电平,该低电平经过积分器在U o2端得到线性上升的输出信号,此线性上升的信号又反馈至迟

滞电压比较器的输入端,当其上升至比较器的上门限电压U th+时,比较器的输出发生跳变,由低电平跳变为高电平,此后,不断重复上述过程,从而在迟滞电压比较器的输出端U o1得到方波信号,在反向积分器的输出端U o2得到三角波信号。假设稳压管反向击穿时的稳定电压为U Z,正向导通电压为U D,由理论分析可知,该电路方波和三角波的输出幅度分别为: 式(5)中R P2为电位器R P动头2端对地电阻,R P1为电位器1端对地的电阻。 由上述各式可知,该电路输出方波的幅度由稳压管的稳压值和正向导通电压决定,三角波的输 出幅度决定于稳压管的稳压值和正向导通电压以及反馈比R1/R f,而振荡频率与稳压管的稳压值和正向导通电压无关,因此,通过调换具有不同稳压值和正向 导通电压的稳压管可以成比例地改变方波和三角波的幅度而不改变振荡频率。 电位器的滑动比R P2/R P1和积分器的积分时间常数R2C的改变只影响振荡频率而 不影响振荡幅度,而反馈比R1/R f的改变会使振荡频率和振荡幅度同时发生变化。因此,一般用改变积分时间常数的方法进行频段的转换,用调节电位器滑动头 的位置来进行频段内的频率调节。

嵌入式系统实验报告

实验一系统认识实验 一、实验目的 学习Dais软件的操作,熟悉程序编写的操作步骤及调试方法。 二、实验设备 PC计算机一台,Dais-52PRO+或Dais-PRO163C实验系统一套。 三、实验内容 编写程序,将80h~8Fh共16 个数写入单片机内部RAM 的30h~3Fh空间。 四、实验步骤 1.运行Dais软件,进入集成开发环境,软件弹出设置通信端口对话框(如图2-1-1), 请确保实验装置与PC正确连接,并已打开实验装置电源,使其进入在待命状态。 这里选择与实验装置实际相连的通信端口,并单击“确定”。如通信正确则进入Dais 软件主界面,否则弹出“通信出错”的信息框(如图2-1-2),请检查后重试。 图2-1-1设置通信端口对话框图2-1-2通信错误信息框 2.通信成功后,单击菜单栏“设置”→“仿真模式”项打开对话框,选择需要设置型 号、程序/数据空间。这里我们将型号设置为“MCS-51实验系统”,外部数据区 设置为“系统RAM”,用户程序区设置为“片外(EA=0)”,如图2-1-3所示,最 后单击“确定”按钮保存设置。

图2-1-3设置工作方式对话框 3.工作方式设置完毕后,单击菜单栏“文件”→“新建”项或按Ctrl+N组合键(建 议单击工具栏“”按钮)来新建一个文件,软件会出现一个空白的文件编辑窗口。 4.在新窗口中输入程序代码(A51\2_1.ASM): ORG 0000H LJMP MAIN ORG 0100H MAIN: MOV R1,#30H ;片内RAM首地址 MOV A,#80H ;写入数据初值 MOV R7,#16 ;循环变量 LOOP1: MOV @R1,A ;写数据到片内RAM INC R1 ;地址增量 INC A ;数据+1 DJNZ R7,LOOP1 ;循环变量-1,不为0继续 SJMP $ ;结束 END 5.单击菜单栏“文件”→“保存”项(建议单击工具栏“”按钮)保存文件。若 是新建的文件尚未命名,系统会弹出文件保存对话框(如图2-1-4),提示用户选择文件保存的路径和文件名,再单击“保存”按钮。

北邮-电子电路综合设计实验(函数信号发生器)报告

电子电路综合设计实验报告 实验1 函数信号发生器的设计与实现 姓名:------ 学号:---------- 班内序号:--

一. 实验名称: 函数信号发生器的设计与调试 二.实验摘要: 采用运放组成的积分电路产生方波-三角波,可得到比较理想的方波和三角波。根据所需振荡频率的高低和对方波前后沿陡度的要求以及对所需方波、三角波的幅度可以确定合适的运放以及稳压管的型号、所需电阻的大小和电容的值。三角波-正弦波的转换是利用差分放大器来完成的,选取合适的滑动变阻器来调节三角波的幅度以及电路的对称性。同时利用隔直电容、滤波电容来改善输出正弦波的波形。 关键词: 方波三角波正弦波频率可调 三、设计任务要求 1.基本要求: (1)输出频率能在1-10KHz范围内连续可调,无明显失真; (2)方波输出电压Uopp=12V,上升、下降沿小于10us,占空比可调范围30%-70%; (3)三角波Uopp=8V; (4)正弦波Uopp错误!未找到引用源。1V. (5)设计该电路的电源电路(不要求实际搭建) 2.提高要求: (1)正弦波、三角波和方波输出波形的峰峰值Uopp均可在1V-10V内连续可调。 (2)三种输出波形的输出端口的输出阻抗小于100Ω。 (3)三种波形从同一端口输出,并能够显示当前输出信号的种类、大小和频率 (4)用CPLD设计DDS信号源 (5)其他函数信号发生器的设计方案 四、设计思路以及总体结构框图 本课题中函数发生器结构组成如下所示:由比较器和积分器组成方波—三角波产生电

路,比较器输出的方波经积分器得到三角波,三角波到正弦波的变换电路主要由差分放大器来完成。差分放大器具有工作点稳定,输入阻抗高,抗干扰能力较强等优点。特别是作为直流放大器时,可以有效地抑制零点漂移,因此可将频率很低的三角波变换成正弦波。波形变换的原理是利用差分放大器传输特性曲线的非线性。 图4-1 函数信号发生器的总体框图 五.分块电路和总体电路的设计 (1)方波——三角波产生电路 图5-1 方波-三角波产生电路

北邮程序设计实验报告

程序设计实践 设 计 报 告 课题名称:邮件客户端学生姓名: 班级: 2 班内序号:16 学号: 2 日期:2014.6.4

1.课题概述 1.1课题目标和主要内容 本课题主要通过MFC的方式,利用SOCKET以及SMTP相关知识,来实现邮件(可携带附件)的定向发送,借此来复习和巩固C++编程的基本思想;学习SOCKET以及SMTP的相关知识,了解复杂网络应用程序的设计方法,并独立完成一个网络应用。 1.2系统的主要功能 1.邮件的发送(不携带附件) 2.邮件的发送(携带附件) 3.邮件接收 2. 系统设计 2.1 系统总体框架 程序的功能由MyEmailClientDlg.cpp,SMTP.cpp,MailMessage.cpp,Base64.cpp, MIMECode.cpp,MIMEContentAgent.cpp,MIMEMessage.cpp,AppOctetStream.cpp, MyEmailClient.cpp,StdAfx.cpp,TextPlain.cpp来实现。其中MIMECode.cpp, MIMEContentAgent.cpp,MIMEMessage.cpp, AppOctetStream.cpp, TextPlain.cpp来对MIME 协议进行封装,Base64.cpp来对Base64编码进行封装,SMTP.cpp是对SMTP协议进行封装,MailMessage.cpp是利用MIME协议对邮件内容的一个处理,最终通过MyEmailClientDlg.cpp 来实现邮件的发送的功能。 2.2 系统详细设计 [1] 模块划分图及描述 协议模块:包括网络应用程序中的各种协议,包括STMP协议,MIME协议等。 处理模块:主要实现对数据的进行编码以及解码。 实现模块:主要内容为邮件发送的具体步骤,相关按钮操作。 [2] 类关系图及描述 协议类:CSMTP, CTEXTPlai, CMIMECode,C MIMEContentAgent,C MIMEMessage, CAppOctetStream, CTextPlain.主要为协议中信息处理的中作用 编码类:Base64, MailMessage.主要为对邮件信息的处理

嵌入式实验报告

《嵌入式系统导论》实验报告学院: 学号: 姓名: 上海工程技术大学 电子电气工程学院

实验一 GPIO(按键和LED)实验 一、实验要求 1 、掌握基于STM32F103微控制器的嵌入式系统、仿真器和开发用PC机之间的连接方法,能够搭建基于STM32F103微控制器的嵌入式系统交叉开发环境。 2 、熟悉常用的嵌入式开发工具KEIL MDK或IAR EWARM的操作环境和基本功能(包括编辑、编译、链接、调试和下载等),学会创建、配置和管理STM32工程,掌握嵌入式程序的基本调试方法,学会使用逻辑分析仪窗口和外设窗口等信息窗口调试嵌入式程序。 3 、理解LED和按键的构件原理,学会设计它们与微控制器间的接口电路 4 、掌握STM32F103微控制器GPIO的工作原理,熟悉STM32的GPIO库函数 5 、学会使用STM32的GPIO库函数在KEIL MDK或IAR EWARM下开发基于LED和按键的简单嵌入式应用程序 二、实验环境 1 、硬件: ALIENTEK STM32F103嵌入式开发板 2 、软件: KEIL MDK或IAR EWARM 三、实验内容 1 、流水灯实验一: 在KEIL MDK或IAR EWARM 中建立STM32工程,并使用GPIO库函数和延时循环设计基于无限循环架构的嵌入式应用程序,使开发板上的红色LED以一定周期闪烁。 采用软件仿真的方式调试程序,通过“Logic Analyzer”,观察程序模拟运行时连接红色LED的引脚PA8上的输出波形。 采用硬件下载的方式调试程序,观察程序下载硬件运行时红色LED的闪烁情况。 2 、按键控制LED实验:

相关文档
最新文档