
课 程 设 计 报 告
课程设计名称:单片机系统综合课程设计
课程设计题目:单片机与PC机串行通讯设计
院(系):
专 业:
班 级:
学 号:
姓 名:
指导教师:
完成日期:
目 录
第1章 总体设计方案………………………………………………………………1
1.1 课程设计的内容和要求………………………………………………………..1
1.2 课程设计原理…………………………………………………………………..1
1.3 课程设计思路…………………………………………………………………..2
1.4 实验环境………………………………………………………………………..2
第2章 详细设计方案………………………………………………………………3
2.1 实现方法………………………………………………………………………..3
2.2 模块设计………………………………………………………………………..3
2.2.1主函数流程图……………………………………………………………...3
2.2.2功能1模块………………………………………………………………...4
2.3 程序连线图……………………………………………………………………..7
第3章 调试及结果分析……………………………………………………………8
3.1 调试步骤及方法………………………………………………………………..8
3.2 实验结果及分析………………………………………………………………..8
参考文献………………………………………………………………………………9
附 录A(源程序)………………………………………………………………10
附 录B(原理图)………………………………………………………………13
附 录C(元器件清单)…………………………………………………………14
第1章 总体设计方案
1.1 课程设计的内容和要求
(1)、课程设计内容:
利用南京伟福公司的LAB6000通用微控制器仿真实验系统开发单片机与PC机串行通讯系统,实现单片机与PC机的通讯。要求实现数据收发功能。具要求容如下:
①.通过LAB6000的小键盘选择功能;
②.功能1:接收PC机发送的数据,并将其回发给PC机;
③.功能2:从LAB6000的小键盘输入数据,发送给PC机。
(2)、课程设计要求:
①.认真完成课程设计任务;
②.通过老师现场验收;
③.交出完整的课程设计报告。
1.2 课程设计原理
根据题目要求,要完成LAB6000的小键盘选择,接收并且回发数据,小键盘可以输入并发送数据等功能,在本次设计中主要使用了MCS-51芯片以及部分连线来完成串行通讯的模拟。
采用MCS-51芯片实现不同模式串行通讯,通过延时程序控制串行通讯的频率。将键盘选择功能、PC机发送及接收数据功能、小键盘发送功能等通过不同的子程序实现,然后在程序中调用不同的子程序来实现不同的功能。
因为需要实现小键盘输入数据,所以必须实现键盘扫描功能及按键检测功能。按键的扫描方法有扫描法和线反转法,因为小键盘按键不是非常多,所以本设计采用行列扫描法来进行小键盘扫描。
1.3 课程设计思路
(1).提出方案
设计键盘扫描函数函数和按键检测函数,通过MCS-51芯片,实现键盘扫描。通过小键盘设置17个键位选择键,输入“1”时在LED灯显示并选择功能1(接收和发送PC机发送的数据);输入“2”时在LED灯显示并选择功能2(从小键盘输入数据并发送给PC机)。
小键盘选择功能:首先设置定时器及波特率,然后再设计键盘扫描函数和按键检测函数,使之能实现小键盘选择功能。输入不同的数实现调用不同的函数,从而实现不同的功能。
功能1:设计PC发送函数,此功能还需要有串行口中断处理函数。目的是实现单片机可以接受PC机发送的数据,并将其回发给PC机。设置一个返回键,如按键“1”时返回小键盘选择功能,可以重新选择功能1还是功能2。
功能2:设计小键盘发送程序,需调用键盘扫描函数及按键检测函数,若有键按下,将键值发送到LED灯上,并将其转为ASCII码发送回PC机。同样设置一返回键,如按键“NEXT”(右数第一列,下数第一行)时返回小键盘选择功能。使函数能循环使用。
(2).方案论证
从实际应用的角度,用户可以任意选择事先设计好的2种状态,当选择完一种状态时,它可以无限的按照这种方案循环的运行下去,在此过程中,用户可以选择退出这种工作状态,从而实现对当前进行状态的控制,即可以令程序重新开始。在整个串行口输入过程中可随时做出不同的输入方式,对输入数据的工作状态进行控制。
1.4 实验环境
·硬件环境:MCS-51实验箱,PC机。
·软件环境:WAVE2000应用软件
第2章 详细设计方案
2.1 实现方法
开始运行程序时数码管初始化显示6个数字0,然后选择一种模式(1和2),若输入的数不是“1”或“2”,只在LED灯上显示该数,等待重新输入一工作状态。此处在扫描键盘并按键检测后需将扫描到的段码发送到LED灯上。
若选择“1”,即要实现功能1则调用PC机发送函数,用串行口中断函数来保存断点(防止计数器溢出)。使之能实现接收PC机发送的数据后再将其回发给PC机。设置一全局变量flag,当用户输入一个数(例如“1”的ASCII码)时flag置1使之跳出while语句死循环,从而达到返回小键盘选择功能的目的。
若选择“2”,即要实现功能2需调用小键盘扫描函数和按键检测函数,将小键盘输入的数据发送到LED灯上,同时然后将该数据转换成ASCII码的形式通过串行口发送到PC机上。同小键盘选择功能一样该功能也要调用小键盘扫描函数和按键检测函数。由于要实现按键返回的目的,在小键盘扫描函数中设置了“NEXT”键(变量kk=100时),同样利用了while语句来跳出死循环。
2.2模块设计
2.2.1主函数流程图
主程序用于控制个功能子程序的调用和相应的芯片及内存、寄存器、变量的初始化,协调整个程序的运行。由于本课设只用了8031芯片,小键盘和LED灯来显示模拟结果,而且所有的功能都是用软件实现的,所以主程序要能很好的组织程序的运行。
主函数模块首先设置定时器及波特率的选择,根据标志位k1的值选择是PC模式发送数据还是小键盘模式发送数据,并根据功能选择模块中对各模式的信息的进行相应的初始设置。通过小键盘选择功能控制数据的输出方式,还能接受新的键值来执行相应的功能。读取的键值要先判断是否是无效键,是无效键要执行死循环程序,按下“1”或“2”键才能继续显示。如果是停止键(指程序设计功能1中的“1”键和功能2中的“NEXT”键),应立刻清空数码管的显示内存并将其重新初始化。如下页图2. 1所示。
图2.1 主函数模块流程图
2.2.2功能1模块
功能1模块利用单片机的串行口,实现PC机的串行通讯。启动功能1时开启定时器,调用串行中断函数,通过while(!flag)语句实现循环发送的功能,在串行中断子函数中先将PC机中输入的内容发送到单片机上,执行while(!RI) (即RI=1单片机接收完数据跳出该循环) 语句。在单片机将其内容回发给PC机之前需要进行是否返回小键盘选择功能的判定,通过if(temp==49)flag=1语句,判断是否是数1的ASCII码49,若是则将flag置1,达到跳出该循环的目的。如图2.2所示。
8031的RXD、TXD接线柱在POD51仿真板上,8086的TXD、RXD在POD8086仿真板上的8031芯片旁边。通讯双方的RXD、TXD信号本应经过电平转换后再行交叉连接,本设计中为减少连线可将电平转换略去,而将双方的RXD、TXD直接交叉连接。
图2.2 功能1模块流程图
2.2.3功能2模块
功能2模块实现小键盘发送数据的功能,需调用小键盘扫描函数和按键检测函数,将小键盘输入的数据发送到LED灯上。启动功能2时同功能1一样先启动定时器工作,扫描小键盘使之能够在小键盘输入数据,对输入的数据进行判定,若为返回键(NEXT)则跳出该函数重新进行小键盘选择功能,使之能够循环使用;若为基本键,将扫描到的按键的键值通过查表的方式转为ASCII码,好发送回PC机中。如图2.3。
图2.3 功能2模块流程图
2.3程序连线图
本设计提供了一个6*4的小键盘,向列扫描地址(0X002H)逐列输出低电平,然后从行码地址(0X001H)读回。如果有键按下,则对应行的值应为低电平;如果无键按下,由于上拉的作用,行码为高。这样就可以通过输出的列码和读取的行码来判断按下的是什么键。地址中的X是由KEY/LED CS决定,做键盘和LED相连时,需将KEY/LED CS接到相应的地址译码上,以便用相应的地址来访问。例如将KEY/LED CS信号接CS0上,则列扫描地址为08002H,行码地址为08001H。列扫描码还可以分时用作LED的位选通信号。如图2.4所示。
图2.4 键盘图
第3章 调试及结果分析
3.1 调试步骤及方法
编译并连接程序后全速运行,在数码管上显示六个LED灯都初始化为0,然后按下小键盘键中的任意一个键,若为3—F中的任意一键在LED的6个灯都显示该数,此时并没有选择执行功能1和2;若为1则执行功能1,即可以在PC机上输入数据并且可以回发,此时在右数第2个LED灯上始终显示1;若为2则执行功能2,即实现小键盘发送数据功能,此时在右数第2个LED灯上始终显示2。
3.2 实验结果及分析
本程序满足课程设计要求,在程序运行时,一共有17个按键,“1”和“2”键即为功能选择键,又为输入数据键,NEXT为复位键其他键为普通数据键,各个按键均能实现其所拥有的功能,程序能很好的模拟串行发送功能。
功能1模式切换时,按下PC机大键盘的“1”键后,返回功能选择模块,可以重新选择工作方式;同样功能2模式切换时,按下小键盘的“NEXT”键也可以返回功能选择模块,从而实现程序循环使用的功能。
参考文献
[1] 张毅刚.刘杰.MCS-51单片机原理及应用 [M].哈尔滨:哈尔滨工业大学出版社,2008
[2] 王忠民.微型计算机原理 [M].西安:西安电子科技大学出版社,2003
[3] 高峰.单片微型计算机原理与接口技术 [M].北京:科学出版社,2007
[4] 郑初华.汇编语言、微机原理及接口技术[M].北京:电子工业出版社,2006
[5] 谢瑞和.微型计算机原理与接口技术 [M].北京:高等教育出版社,2004
[6] 胡汉才.单片机原理及接口技术 [M].北京:清华大学出版社,2007
附 录A(源程序)
#include #include #define uchar unsigned char #define uint unsigned int xdata uchar key _at_ 0x8001;//定义键盘行地址 xdata uchar led _at_ 0x8002;//定义键盘列地址并定义段码显示所在列 xdata uchar dat _at_ 0x8004;//定义段码输出地址 uchar ascii[]={48,49,50,51,52,53,54,55,56,57,0x41,0x42,0x43,0x44,0x45,0x46}; uchar ledmap[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uint k1; uchar flag; uchar temp; void pcsend(); void keysend(); int i,j,p; void delay() { for(i=0;i<100;i++) for(j=0;j<100;j++) for(p=0;p<100;p++) ; } unsigned char testkey() //数码管显示函数 { led = 0; return (~key&0x0f); } uint getkey() //键盘扫描函数 { uint k; led=0xfb; //扫描左数第四列 switch(key) { case 0x0e:k=13; while(testkey());return (k); //下数第一行d case 0x0d:k=12; while(testkey());return (k); //下数第二行c case 0x0b:k=11; while(testkey());return (k); //下数第三行b case 0x07:k=10; while(testkey()); return (k); //下数第四行a default:break; } led=0xf7; //扫描左数第三列 switch(key) { case 0x0e:k=14; while(testkey());return (k); case 0x0d:k=3; while(testkey());return (k); case 0x0b:k=6; while(testkey());return (k); case 0x07:k=9; while(testkey());return (k); default:break; } led=0xef; //扫描左数第二列 switch(key) { case 0x0e:k=15; while(testkey());return (k); case 0x0d:k=2; while(testkey());return (k); case 0x0b:k=5; while(testkey());return (k); case 0x07:k=8; while(testkey());return (k); default:break; } led=0xdf; //扫描左数第一列 switch(key) { case 0x0e:k=0; while(testkey());return (k); case 0x0d:k=1; while(testkey());return (k); case 0x0b:k=4; while(testkey());return (k); case 0x07:k=7; while(testkey());return (k); default:break; } led=0xfe; switch(key){case 0x0e: k=100; while(testkey());return(k); default: return(-1); break;} } void main()//主函数 { TMOD=0x20; TH1=0xF3; TL1=0xF3; SCON=0x50; PCON=0x80; while(1){ k1=getkey(); //k1=1; led=2; flag=0; dat=ledmap[k1]; if(k1==1||k1==2) { switch(k1) { case 1: pcsend();IE=0x00;k1=0; break; case 2: keysend();k1=0; break; } } } } void pcsend()//PC发送函数 { TR1=1; IE=0x90; while(!flag); } void keysend()//小键盘发送函数 { uint kk=0; uchar knum; TR1=1; kk=getkey(); while(kk!=100) { kk=getkey(); if(kk==-1) continue; led=2; knum=ascii[kk]; SBUF=knum; while(!TI); TI=0; } } void Int1() interrupt 4//串行口中断函数 { while(!RI); temp=SBUF; RI=0; SBUF=temp; while(!TI); TI=0; if(temp==49) flag=1; } 附 录B(原理图) 附 录C(元器件清单) 课程设计总结: 经过这次课程设计,我对汇编语言、C语言及单片机芯片8031有了进一步的了解,并且巩固了对芯片功能的理解和应用,增加了我的动手能力和实践能力。并且在与老师和同学的交流过程中,开阔了自己的想法,通过使用更好的方法,程序变得更加高效。 本次课程设计是用硬件实现串行口通讯的设计。在刚开始实验中遇到了很多问题,其中很多是因为自己的粗心大意导致程序的功能不能正确实现,还有一些是在编写程序时出现的错误。刚接触这些功能时,我还不能真正理解如何实现串行口通讯的功能,从汇编语言来实现小键盘扫描功能无法实现到采用C语言实现,虽然最后的键盘扫描功能不尽人意,但是我认为在这次课程设计后我真的学到了很多东西,在老师和同学的帮助下能完成课程设计的要求我认为很激励我的学习兴趣。 指导教师(签字): 年 月 日编号 名称 型号 数目 U1 单片机 8051 1 D1 译码器 74LS138 1 U5 8路总线收发器 74LS245 1 U2、U6 8上升沿D触发器 74LS374 2 U7 串行口芯片 MAX232 1 U3 LED灯 RES2 1 U4 达林顿管阵列反向驱动器 MC1413-6 1 J1 串行口接口 DB9 1 S1 按键 SW-PB 1 Y1 晶振 6MHz 1 R1、R2、R3、R4、R5 电阻 10K 5 C1、C2 无极性电容 22pF 2 C3、C4、C5、C6、C7 无极性电容 10uF 5 通过本次课程设计让我更加深刻的理解了MCS-51单片机原理及其应用。同时也认识到自己在书本上所学习到的知识还远远不足,需要亲自动手实践来充实自己在书本上的所学,并且应用到具体的语句实现上。所以我会在以后的学习中更加虚心努力,增加自己的编程能力。 指导教师评语: 课程设计成绩
