华科 微机接口 课程设计 报告

更新时间:2023-09-06 09:03:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

《微机接口技术》课程设计报告

指导老师: 周功业 学生姓名: 李中亚 学生学号: U200814238 所在班级: 计算机0803班 同组成员: 崔泽波、扈泓达、傅强

设计题:货物计费计数运输系统

设计时间:2011.9.5至2011.9.9

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

一、 课程设计目的

学习并行接口、步进电机、开关量接口、声光系统、并行通讯、8253定时/计数器、波特率时钟、串行通信接口、A/D,D/A转换器、数据采集程序的设计原理与方法,掌握其控制程序的编写。

1. 掌握接口硬件开发平台的使用方法,利用现有的实验平台和PC机,组成一个微机模拟应用系统;

2. 掌握基本接口电路的综合应用

3. 掌握接口电路的驱动程序和界面软件的设计与编制,学会调试与测试接口软 件的一般方法;

二、 课程设计任务

结合实际应用,设计一微机应用系统,要求该系统综合应用并行接口、串行接口,定器接口、中断接口、模拟接口等等,实现主控中心微机与下位机实现远距离传送,以及远程控制、监测功能。

三、 课程设计要求

由一个主控机监控和若干个下位机组成,主控机负责数据处理,下位机负责访问接口。

主控机:在显示屏上用数字、图形、表格、曲线等直观数据处理的过程。 下位机:在显示屏上或用实验台的声光描述当前监控的工作状态。

四、 课程设计内容

(一) 选题及题目要求

设计方案选择:货物计费计数运输系统

下位机模拟运输系统:上/下货时产生货物类型/编号和累计数量,传到上位机。 上位机模拟控制系统向下位机发出下货命令或接收上货请求。用LED显示货物量,用声音提示上货下货

1. 用实验台上的开关信号模拟上货请求信号。

2. 用实验台上的LED和扬声器模拟上/下货时状态信息。 3. 用实验台上的步进电机的正反转模拟运输动作。 4. 上位机实现图形监控。(模拟)

(二) 设计功能说明

1. 上货过程:在下位机通过键盘输入货物类型、数量,按上货按钮SW2开始请

求上货,这时下位机向上位机发送一个上货请求和货物类型、数量,上位机

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

接收到上货请求后通过界面显示请求的货物类型和数量,按下SW2按钮允许上货,下位机接收到允许命令,扬声器响起,开始上货,LED计数器由零开始加1,步进电机开始正转,直到上货结束,此时下位机LED灯显示的数字为货物数量;

2. 下货过程:在下位机通过键盘输入货物类型、数量,按下货按钮SW3开始请

求下货,这时下位机向上位机发送一个下货请求和货物类型、数量,上位机接收到下货请求后通过界面显示请求的货物类型和数量,按下SW4按钮允许下货,下位机接收到允许命令,扬声器响起,开始下货,LED计数器由零开始加1,步进电机开始反转,直到下货结束,此时下位机LED灯显示的数字为货物数量;

3. 当上/下货结束时,由主机计算费用,将费用数据传给下位机并显示,下位

机按下交费按钮SW4表示交费结束,上位机和下位机均回到初始状态。 4. 下位机:C口控制音乐发生器和接收按钮信号;

B口控制步进电机正/反转表示上/下货; A口控制LED灯显示货物数量;

上位机:C口控制音乐发生器和接收按钮信号。

(三) 组员及组内分工

组员:李中亚、崔泽波、傅强、扈泓达

李中亚负责:整体功能设计、程序结构、双机通讯 崔泽波负责:下位机程序代码、双机通讯、处理bug 傅强负责:上位机程序代码、功能测试、处理bug 扈泓达负责:上位机程序代码、连线及功能测试

(四) 系统总体结构

1. 系统硬件由主控机(其中一台微机)、下位机(另一台位微机)和执行部件

组成。主控机与下位机通过串行通信线连接。

2. 执行部件:由接口电路等组成,将接收的数据送入到下位机或将下位机输出

的数据送到执行部件。

3. 下位机:与主控机通信,控制执行部件。 4. 主控机:与所有下位机进行数据交换,必要时需建数据库,进行数据处理等。 5. 主控机程序:串行(RS232/RS485)通信程序,数据处理程序等。 6. 下位机程序:串行(RS232/RS485)通信程序,执行部件控制程序。

(五) 系统接口框图

硬件跳线配置:

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

接线说明:只需连接8255与步进电机、LED灯、音乐发生器、按钮,无需连

接8251和8253,因为实验台内部已经连接好了。

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

(六) 程序清单及源码

见附件。

五、 课程设计感想

经过4天的奋战,终于完成了接口课程设计,一种成就感油然而生。大三下学期微机接口考试后就再也没有看过接口的书,很多知识都有些生疏了,做了课程设计后,很多知识又被捡起来了,而且记得更加牢固了。

开始做课设时,在测试实验台RS232通信功能的时候,两个实验台都能正常自发自收,但是实验台之间无法正常通信,通信功能可是基础,无法通信课设就做不下去了。我们一开始怀疑是串口线的问题,换了两根,倒是能够通信了,但是一台发送普通的字母和数字时,另一台收到的却是乱码,这也是不正常的。我们又怀疑是电脑和实验台间的排线有问题,换了一根排线,状况好了很多,能够收到正确的字符,但是很不稳定,时不时出现收到乱码的情况。我们跟其他组要来一个实验台,换上后,发现连接非常稳定,始终能收到正确字符,看来我们组原来那个实验台本身有点小问题。

我负责整体设计,也就是具体有那些功能,每个功能具体实现的步骤,俩实验台之间怎么通讯(如怎么让上位机知道下位机要干什么,怎么让下位机知道来自上位机的信息是什么)。还有程序结构,我们组内要商讨如何写程序代码,程序结构如何等等。

最终测试时看到两个实验台按我设计的步骤一步步完成上/下货,心里感觉很是欣慰,觉得这些天的奋斗没有白费。

六、 附件(程序源码)

上位机程序:main.cpp

#include <conio.h> #include <stdio.h> #include <dos.h> #include <stdlib.h> #include <string.h> #include <math.h>

#define factor 16//波特率因子16

unsigned long int clk = 1919828; //8251输入时钟频率(十六进制表示) int bps=2400;

char cargoKind,cargoCount[10],cost[20],s='s',x='x'; int price_table[9]={

5, 2, 3,

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

};

int stock_table[9]={ };

void init8251(void)//初始化8251 { }

void set_bps(int bps)//8253设置波特率 { }

void stock(void) {

clrscr();

printf("Stock in the warehouse:\n\n"); int i,sendhigh,sendlow; i=clk/bps;

i=i/factor;//计算计数初值=ckk/(factor*bps) sendhigh = (i>>8)&0x00ff; sendlow = i & 0x00ff;

outportb(0x307,0xb6);//10110110B

outportb(0x306,sendlow);//装计数初值低字节 outportb(0x306,sendhigh);//装计数初值高字节 outportb(0x309,0x00);//8251 命令口 空操作 0000 0000 delay(100);

outportb(0x309,0x40);//8251 命令口 内部复位 0100 0000 delay(100);

outportb(0x309,0x4E);//8251 命令口 方式命令 0100 1110 delay(100);

outportb(0x309,0x27);//8251 命令口 工作命令 0010 0111 delay(100); 100, 100, 100, 100, 100, 100, 100, 100, 100 1, 6, 1, 1, 3

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

}

void price(void) { }

void shanghuo(void) {

int i=0,a=0,cargoAmount=0,totalcost=0; char c,receive; clrscr();

outportb(0x303,0x0d);//置PC6=1,打开8253-5的GATE2,开始输出方波 while( 1 ) { }

a=cargoKind-0x30; while( 1 ) {

c=inportb(0x309);//8251 命令口/状态口 读状态 if(0x38 & c ) { }

cargoKind=inportb(0x308);//8251 数据口接收允许命令 break;

printf("data is bad !\n");//8251 命令口/状态口 接收数据有误 else if( 0x02 & c ) //RxRDY clrscr();

printf("Prize of load/dismount cargo table\n\n"); printf(" Fridge: $%d\n",price_table[0]); printf(" Television: $%d\n",price_table[1]); printf(" Washing Machine: $%d\n",price_table[2]); printf(" Desktop PC: $%d\n",price_table[3]); printf(" Laptop PC: $%d\n",price_table[4]); printf(" Air Conditioner: $%d\n",price_table[5]); printf(" Microwave Oven: $%d\n",price_table[6]); printf(" Fan: $%d\n",price_table[7]); printf(" Others: $%d\n",price_table[8]); printf(" Television: %d\n",stock_table[1]); printf(" Washing Machine: %d\n",stock_table[2]); printf(" Desktop PC: %d\n",stock_table[3]); printf(" Laptop PC: %d\n",stock_table[4]); printf(" Air Conditioner: %d\n",stock_table[5]); printf(" Microwave Oven: %d\n",stock_table[6]); printf(" Fan: %d\n",stock_table[7]); printf(" Others: %d\n",stock_table[8]);

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

if(0x38 & c )

printf("data is bad !\n");//8251 命令口/状态口 接收数据有误 else if( 0x02 & c ) {

receive=inportb(0x308); //8251 数据口接收字符,装入 {

cargoCount[i]='\0';

if(receive=='\0')

break; } else

{

cargoCount[i]=receive;

i++; } }

}

cargoAmount=atoi(cargoCount);

printf("Subsystem ask for Loading %d ",atoi(cargoCount)); switch(a) { }

printf(".\n\nPress \'SW2\' to permit."); do{

receive = inportb(0x302); case 1:printf("Fridge");break; case 2:printf("Televison");break; case 3:printf("Washing Machine");break; case 4:printf("Desktop PC");break; case 5:printf("Laptop PC");break; case 6:printf("Air Conditioner");break; case 7:printf("Microwave Oven");break; case 8:printf("Fan");break; case 9:printf("Others");break;

}while((0x02&receive)!=0);//查SW2按下

printf("\n\nYou Permited."); while(1) {

c=inportb(0x309);//8251 命令口/状态口 读状态 if(0x01 & c ) {

delay(100);

outportb(0x308,s);//8251 数据口 发送's'

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

delay(100);

break; }

}

totalcost=cargoAmount*price_table[a-1]; stock_table[a-1]+=cargoAmount; itoa(totalcost,cost,10); while( 1 ) { } i=0; while(1) {

c=inportb(0x309); //8251 命令口/状态口 读状态 if(0x01 & c ) {

if( cost[i]!='\0' )

{ //8251 数据口 发送

c=inportb(0x309); //8251 命令口/状态口 读状态 if(0x38 & c ) { }

receive=inportb(0x308); //8251 数据口接收允许命令 if(receive==s)break;

printf("data is bad !\n"); //8251 命令口/状态口 接收数据有误 else if( 0x02 & c )

outportb(0x308,cost[i]); delay(100); i++; } else

{

outportb(0x308,'\0');

delay(100); break; } } } }

void xiahuo(void) {

int i=0,a,cargoAmount=0,totalcost=0; char c,receive;

printf("\n\nLoad Over\n\nThe total cost is:%s.",cost); delay(5000);

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

outportb(0x303,0x0d); //置PC6=1,打开8253-5的GATE2,开始输出方波 while( 1 ) { }

a=cargoKind-0x30; while( 1 ) {

c=inportb(0x309);//8251 命令口/状态口 读状态 if(0x38 & c )

printf("data is bad !\n");//8251 命令口/状态口 接收数据有误 else if( 0x02 & c ) {

receive=inportb(0x308); //8251 数据口接收字符,装入 {

cargoCount[i]='\0';

c=inportb(0x309); //8251 命令口/状态口 读状态 if(0x38 & c ) { }

cargoKind=inportb(0x308); //8251 数据口接收允许命令 break;

printf("data is bad !\n"); //8251 命令口/状态口 接收数据有误 else if( 0x02 & c )

if(receive=='\0')

break; } else

{

cargoCount[i]=receive;

i++; } }

}

cargoAmount=atoi(cargoCount);

printf("Subsystem ask for Dismounting %d ",atoi(cargoCount)); switch(a) {

case 1:printf("Fridge");break; case 2:printf("Televison");break; case 3:printf("Washing Machine");break; case 4:printf("Desktop PC");break; case 5:printf("Laptop PC");break; case 6:printf("Air Conditioner");break;

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

}

printf(".\n\nPress \'SW4\' to permit."); do{

receive = inportb(0x302);

case 8:printf("Fan");break; case 9:printf("Others");break;

}while((0x08&receive)!=0);//查SW2按下

printf("\n\nYou Permited."); while(1) {

c=inportb(0x309);//8251 命令口/状态口 读状态 if(0x01 & c ) {

delay(100);

outportb(0x308,x);//8251 数据口 发送'x' delay(100);

break; }

}

totalcost=cargoAmount*price_table[a-1]; stock_table[a-1]-=cargoAmount; itoa(totalcost,cost,10); while( 1 ) { } i=0; while(1) {

c=inportb(0x309); //8251 命令口/状态口 读状态 if(0x01 & c ) {

if( cost[i]!='\0' )

{ //8251 数据口 发送

c=inportb(0x309); //8251 命令口/状态口 读状态 if(0x38 & c ) { }

receive=inportb(0x308); //8251 数据口接收允许命令 if(receive==x)break;

printf("data is bad !\n"); //8251 命令口/状态口 接收数据有误 else if( 0x02 & c )

outportb(0x308,cost[i]); delay(100);

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

i++; } else

{

outportb(0x308,'\0');

delay(100); break; } } } }

void main(void) {

char receive,inchar; char c;

//建立连接阶段开始

printf("Start testing connection.\nPress \'Esc\' to quit testing.\n\n"); set_bps(bps);//设置波特率 init8251();//初始化8251

outportb(0x303,0x81);//置PC6=1,打开8253-5的GATE2,开始输出方波 outportb(0x303,0x0d); for(;;)//判断是否Esc键 {

if (kbhit())

{ } {

c=inportb(0x309); if((c & 0x02)!=0)

//已准备好,即有数据传送过来,则接收1个字符

{ } else { }

c=inportb(0x309); //获取8253 TXRDY 状态

if((c & 0x01)!=0) //已准备好,则将键入的字符发送出去 { }

outportb(0x308,inchar); outport(0x303,0x0c); break;

//c6=0,关闭8253

//若无键按下,则转接收

if((inchar=getche())==0x1b)//是ESC?是,则退出

printf("\n\nDismount Over\n\nThe total cost is:%s.",cost); delay(5000);

else

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

{

clrscr();

printf("Please take your choice:\n\n"); printf(" 1,Stock\n"); printf(" 2,Price\n");

printf("\n\nPress Esc to quit."); outportb(0x303,0x0d); for(;;)//判断是否Esc键 {

if (kbhit())//有键按下

{ } {

c=inportb(0x309);//已准备好,即有数据传送过来,则接收1个字符 if((c & 0x02)!=0)

inchar=getche();

if((inchar)==0x1b)//是ESC?是,则退出 { }

else if(inchar==0x31)//选1 { }

else if(inchar==0x32)//选2 { }

price();

printf("\nPress any key to go back home."); getche(); break; stock();

printf("\nPress any key to go back home."); getche(); break;

outport(0x303,0x0c); return;

//c6=0,关闭8253

}

//建立连接阶段结束

}

}

inchar=inportb(0x308); printf("%c",inchar);

while(1)

else//若无键按下,则转接收

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

} }

}

}

}

inchar=inportb(0x308);

if(inchar==s){shanghuo();break;} else if(inchar==x){xiahuo();break;}

下位机程序:sub.cpp

#include <conio.h> #include <stdio.h> #include <dos.h> #include <stdlib.h> #include <string.h>

#define factor 16//波特率因子16

unsigned long int clk = 1919828;//8251输入时钟频率(十六进制表示) int bps=2400;

int xu[8]={0x05,0x15,0x14,0x54,0x50,0x51,0x41,0x45};//正转相序表 int xu1[8]={0x45,0x41,0x51,0x50,0x54,0x14,0x15,0x05};//反转相序表 char cargoCount[10];//货物量 void init8251(void)//初始化8251 { }

void set_bps(int bps)//设置波特率 {

int i,sendhigh,sendlow; i=clk/bps;

i=i/factor;//计算计数初值 sendhigh = (i>>8)&0x00ff; sendlow = i & 0x00ff; outportb( 0x307 ,0xb6);

outportb(0x306,sendlow);//装计数初值低字节 outportb(0x306,sendhigh);//装计数初值高字节

outportb(0x309,0x00);//8251 命令口 空操作 0000 0000 delay(100);

outportb(0x309,0x40);//8251 命令口 内部复位 0100 0000 delay(100);

outportb(0x309,0x4E);//8251 命令口 方式命令 0100 1110 delay(100);

outportb(0x309,0x27);//8251 命令口 工作命令 0010 0111 delay(100);

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

void shanghuo(char cargoKind); void xiahuo(char cargoKind); void main(void) {

char inchar;//键盘输入 char point; //发送字符 char receive; //接收字符 char c; //8251状态 int i=0;

int temp=0;//货物类型号:整数 int getvalue=0;//货物类型号:字符 unsigned char recv;

//建立连接阶段开始

printf("Start testing connection.\nPress \'Esc\' to quit testing.\n\n"); set_bps(bps);//设置波特率 init8251();//初始化8251

outportb(0x303,0x81);//置PC6=1,打开8253-5的GATE2,开始输出方波 outportb(0x303,0x0d); for(;;)//判断是否Esc键 {

if (kbhit())

{ } {

c=inportb(0x309); if((c & 0x02)!=0) {

inchar=inportb(0x308);

//已准备好,即有数据传送过来,则接收1个字符

{ } else { }

c=inportb(0x309); //获取8251 TXRDY 状态

if((c & 0x01)!=0) //已准备好,则将键入的字符发送出去 { }

outportb(0x308,inchar); outport(0x303,0x0c); break;

//c6=0,关闭8253

//若无键按下,则转接收

if((inchar=getche())==0x1b)//是ESC?是,则退出

else

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

}

//建立连接阶段结束 while(1) {

clrscr();

printf(" ************************************************\n"); printf(" *******welcom to stocking goods system !********\n"); printf(" ************************************************\n\n\n");

printf(" Pess Enter to start the system.\n Press ESC to exit.\n\n\n\n"); outportb(0x303,0x81);//8255串口初始化,1000 0001 口A、B、C4到C7 输出 C0到C3输入 outportb(0x300,0x00); //8255口A置零,熄灯.

outportb(0x303,0x0c); //8255 C6置0,关喇叭 0000 1100 outportb(0x303,0x09); //置PC4=1关闭74LS373 for(;;) { }

delay(100);

for(;;)//从货物列表选择货物类型 {

clrscr(); gotoxy(10,4);

printf("Please choose the kind of cargo !\n"); gotoxy(10,6);

printf("1---Fridge\n") ; gotoxy(10,7);

printf("2---Televison\n") ; gotoxy(10,8);

printf("3---Washing Machine\n") ; gotoxy(10,9);

printf("4---Desktop PC\n") ; gotoxy(10,10);

printf("5---Laptop PC\n") ; inchar=getche();

if((inchar)==0x1b)//是ESC?是,则退出 { }

else if((inchar)==0x0d) { }

break; return;

//判断是否Esc键

}

}

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

}

temp = getvalue - '0'; gotoxy(10,16);

printf("You choose %d.",temp); delay(1000); clrscr(); gotoxy(10,5);

printf("Please input the amount of cargo:");//输入货物数量 gotoxy(10,6);

scanf("%s",cargoCount); clrscr(); gotoxy(10,5);

printf("Press 'sw2' to Load Cargo;Press 'sw3' to Dismount Cargo."); while(1) {

recv = inportb(0x302); if((0x02&recv)==0) { }

else if((0x04&recv)==0) { }

xiahuo(getvalue); break;

shanghuo(getvalue); break; printf("6---Air Conditioner\n") ; gotoxy(10,12);

printf("7---Microwave Oven\n") ; gotoxy(10,13); printf("8---Fan\n"); gotoxy(10,14);

printf("9---Others\n"); gotoxy(10,16); getvalue=getch();

if((getvalue<'1') || (getvalue>'9')) { }

else break;

gotoxy(10,16);

printf(" Input error! try again please! "); getch(); continue;

//error message

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

}

/**********************************************/ void shanghuo(char cargoKind) {

char c,startchar='s',cost[20],receive; int i,k;

set_bps(bps); //设置波特率 init8251(); //初始化8251

outportb(0x303,0x0d); //置PC6=1,打开8253-5的GATE2,开始输出方波 while(1) { } i=0; while(1) {

c=inportb(0x309); //8251 命令口/状态口 读状态 if(0x01 & c ) {

if( cargoCount[i]!='\0' ) { //8251 数据口 发送

c=inportb(0x309); //8251 命令口/状态口 读状态 if(0x01 & c ) { }

delay(100);

outportb(0x308,startchar); //8251 数据口 发送's' delay(100);

outportb(0x308,cargoKind); delay(100);

}

break;

outportb(0x308,cargoCount[i]); delay(100); i++; } else

{

outportb(0x308,'\0');

delay(100); break; } } }

clrscr();

华科微机接口课程设计(货物计费计数运输系统) 完整 报告 源码

while( 1 ) { }

outportb(0x303,0x08); //置PC4=0,打开74LS373 for(i=0;i<500;i++) //上货发声一 { }

clrscr();

printf("loading......... \n "); k=0; i=0; do{

k++; //步进电机正转,模拟上货

outportb(0x303,0x0d); //8255 C6置1,喇叭发声 0000 1101 delay(1);

outportb(0x303,0x0c); //8255 C6置0,关喇叭 0000 1100 delay(1);

c=inportb(0x309); //8251 命令口/状态口 读状态 if(0x38 & c ) { }

c=inportb(0x308); //8251 数据口接收允许命令 }

{

printf("Loading Cargo is permitted."); break;

printf("data is bad !\n"); //8251 命令口/状态口 接收数据有误 else if( 0x02 & c )

if(c=='s')

outportb(0x301,xu[i]); //送相序代码到PB口 i++;

if(i==8) { }

delay(100); //延时

i=0;

outportb(0x300,(0xff-k/8));//货物量LED显示

}while(k<=(8*atoi(cargoCount))); //转十次

//outportb(0x303,0x09); //置PC4=1,关闭74LS373 clrscr();

outportb(0x303,0x0d);//置PC6=1,打开8253-5的GATE2,开始输出方波 printf("Load Success.\nCargo Amount:%d\nCost:",atoi(cargoCount)); while(1)

本文来源:https://www.bwwdw.com/article/j4yh.html

Top