题 目
单片机间串口通信设计
| 院 系: | 自动化学院 |
| 专业班级: | 智能0903班 |
| 小组成员: | |
| 指导教师: | |
| 日 期: | 2012.03.26-2012.04.06 |
近年来,单片机以其极高的性价比越来越多的在智能式仪表和工业过程控制中得到广泛的应用。但由于其本身资源有限,在一些复杂过程或功能较多的控制中就难以满足要求,需要将单片机的数据送到上一级的微机进行处理。因此实现上位机(PC机)与下位机(单片机)之间的数据可靠通信是必须解决的主要问题之一,在数据传输量不大的情况下,按照RS232标准进行串行通信越来越多的服务于各种应用系统中。实验要求利用简单的51单片机实现双机通信使得两片51都能够发送并接收信息。
2. 课程设计具体要求
2.1 了解单片机及其应用,明确课程学习内容及目标
2.2 学会仿真图的设计
2.3 选一个带有232接口的单片机,和电脑进行通信,或者两个都带有232接口的单片机,相互通信,一个做人机界面和通信程序.另外一个做采集程序和通信程序,通过人机界面获取命令,然后通过通信程序发送到另外一个单片机,另外一个单片机接收到命令后做相应的采集处理。
3.主要元器件
两片C52,两个11.0592晶振,烙铁,学生电源,104瓷片电容8个,22pf电容4个,4个LED灯,四脚开关两个,max232两个。
4.基本原理阐述
串行通信是指数据按位顺序传送的通信。串行数据传送的特点是:通信线路简单,最多只需一对传输线即可实现通信,成本低但速度慢,其通信线路既能传送数据信息,又能传送控制信息。它对信息的传送格式有固定要求,具体分为异步和同步两种信息格式.与此相应有异步通信和同步通信两种方式;在串行通信中,对信息的逻辑定义与TTL不兼容,需要进行逻辑电平转换:计算机与外界的数据传送大多是串行的,其传送的距离可以从几米到几千公里。单片机中使用的串行通信通常都是异步方式的。
5.实验方案
5.1:硬件设计
5.2 软件程序
甲机程序:
//说明:甲机向乙机发送字符,本身也完成相应动作
#include #define uchar unsigned char #define uint unsigned int sbit LED1=P1^0; sbit LED2=P1^3; sbit K1=P1^7; uchar Operation_No=0; //操作代码 uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; //数码管代码 void DelayMS(uint ms) //延时 { uchar i; while(ms--) for(i=0;i<120;i++); } //向串口发送字符 void Putc_to_SerialPort(uchar c) { SBUF=c; while(TI==0); //收到时中断 TI=0; //清除中断 } void main() //主程序 { LED1=LED2=1; P0=0xff; SCON=0x50; //串口模式1,允许接收 TMOD=0x20; //T1工作模式2 PCON=0x00; //波特率不倍增 TH1=0xfd; //设置计数初值 TL1=0xfd; TI=RI=0; TR1=1; //启动定时器 IE=0x90; //允许串口中断 while(1) { DelayMS(100); if(K1==0) //按下K1时选择操作代码0,1,2,3 { while(K1==0); //按键恢复时执行下面的 Operation_No=(Operation_No+1)%4; switch(Operation_No) //根据操作代码发送A/B/C或停止发送 { case 0: Putc_to_SerialPort('X'); LED1=LED2=1; break; case 1: Putc_to_SerialPort('A'); LED1=~LED1;LED2=1; break; case 2: Putc_to_SerialPort('B'); LED2=~LED2;LED1=1; break; case 3: Putc_to_SerialPort('C'); LED1=~LED1;LED2=LED1; break; } } } } void Serial_INT() interrupt 4 //甲机串口接收中断函数 { if(RI) { RI=0; if(SBUF>=0&&SBUF<=10) P0=DSY_CODE[SBUF]; else P0=0xff; } } 乙机程序: // 说明:乙机接收到甲机发送的信号后,根据相应信号控制LED完成不同闪烁动作。 #include #define uchar unsigned char #define uint unsigned int sbit LED1=P1^0; sbit K2=P1^7; sbit LED2=P1^3; uchar NumX=-1; void DelayMS(uint ms) //延时 { uchar i; while(ms--) for(i=0;i<120;i++); } void main() //主程序 { LED1=LED2=1; SCON=0x50; //串口模式1,允许接收 TMOD=0x20; //T1工作模式2 TH1=0xfd; //波特率9600 TL1=0xfd; PCON=0x00; //波特率不倍增 RI=0; TI=0; TR1=1; //启动定时器 IE=0x90; //允许中断 while(1) { DelayMS(100); if(K2==0) //按钮按下时发送数字到串行缓冲寄存器,否则等待 { while(K2==0); NumX=(NumX+1)%11; //产生0~10范围内的数字,其中10表示关闭 SBUF=NumX; while(TI==0); //等待中断 TI=0; //清除中断 } } } void Serial_INT() interrupt 4 { if(RI) //如收到则LED动作 { RI=0; switch(SBUF) //根据所收到的不同命令字符完成不同动作 { case 'X': LED1=LED2=1;break; //全灭 case 'A': LED1=0;LED2=1;break; //LED1亮 case 'B': LED2=0;LED1=1;break; //LED2亮 case 'C': LED1=LED2=0; //全亮 } } } 6.设计中的问题分析 硬件设计时,还是对不同的器件进行过一定的对比,还是选择了104的瓷片电容以及22pf的电容。焊接完成之后,发现与仿真时差异很大,进行检查之后,发现是甲机晶振处的22pf电容损坏,应该是当时电极接反引起的。修正之后,基本实现目标。 7.参考资料 《8051单片机彻底研究》 《PROTEUS与KEIL的联合仿真》 《51单片机应用从零开始》 8.实验总结 张三: 我们为期两个周的课程设计已经接近尾声,这两个周的时间内我们每个人都完成了自己的工作,使我们的实验得以成功。当然,鉴于时间的原因,我们仅仅是实现了一些简单的功能,而没有去进行更深层次的扩展功能,还是比较遗憾的。 课程项目刚刚分配下来的时候,我们组员还是比较担心的,因为听大家说:这个课题是有一定的难度的。当时我们就这个问题的细节简单讨论了一下,说明这个课题我们要完成的目标以及还有可能的扩展任务,希望大家下去积极的参与并且很好的动起手来。其实我们这组分工不是十分的明确,毕竟大家的专业知识还是在一个起跑线的,就是看看谁的手头资源比较充足,能够让大家很好的利用,到后期的软件设计,仿真图的设计都是有过讨论的,鉴于我是第一次使用这个仿真软件,所以没有太多的投入其中,只是以一个学习者的身份去观看队员如何的完成仿真,在这个过程当中,自己也学会了仿真。我们讨论了为什么要使用瓷片电容,11.0592的晶振,还有MAX232,让每个人都能够了解到所用器件的作用,方便以后的学习。 仿真图的设计以及软件设计还是花费了些许时间的。因为要考虑到板子的大小,还是没有做出其他的扩展功能,就这样,还是将整个板子基本利用,我们整体的布局还是十分美观的(当然只限于正面)。我们设计的是两块单片机的通信,即两片51的通信,由甲机向乙机发送信号是LED灯的变化,乙机向甲机发送信息实现数码管从0-9的循环变化。仿真是因为是互相通信,所以设计还是比较简单的,对称即可。所有准备工作完成之后,就是焊电路板。基于大一时期的电装实习,所以焊功还是可以的,没有花太多的时间。下来的工作就是调试电路,找出问题,因为实验就是在一次次的求证中得到完美。刚开始确实板子没有丝毫的反应,后来才知道是甲机的晶振处电容的问题,重新安装之后实现目标。 在设计仿真时,其实是有两套方案的,不过由于第一套有点简单,没有晶振电路,仿真可以实现,而且基于没有太多的实验器材,所以也没有采取这一套方案。而是重点着手第二套,加入晶振,给予脉冲。利用MAX232实现电频转化,将电源的5V转换到与计算机对应的12V。当然也会考虑到为什么不直接接通12V,我想着应该是害怕烧坏电路。当然试验中还有许多小的问题,不过都被直接的发现,没有太大的难处,总之这次课程设计还是较之简单的吧。 课程设计,就是能够加大同学的动手能力以及学习能力,能够很好地与同学讨论,求教,及时的发现问题,解决问题,达到预期的目标。在这之后,主要的是巩固自己,是自己对未知的东西有一定的了解,有一定的提升。 李四: 为期两周的课程实习结束了,和以往的实习经验相比,这一次最大的收获在于我真正用心体会了整个过程,用心思考很多问题,也收获很多的感悟。 刚开始知道题目时我开始迷茫了,因为这是我最弱的部分,甚至可以说不知道该从何处入手。所以我选用最简单的方法——上网查询。我开始在网站上找相关的资料,但是因为基础太差,即使在网站上找到很多的相关知识,对于很多的概念还不是很清楚,我把相关的器件功能都仔细看了,然后对照电路图研究其工作过程,也向周围的同学询问相关知识,但是尽管这样我还是没能够将这些知识很好的串连起来(最后是在同组同学的讲解下才理清楚的)。而同组的同学都比我强,在我开始串连这些星星点点的知识点儿时他们却能够掌握整个实验的原理并开始设计了。虽然和他们相比我有很多不会的地方,但是即使在旁边看着他们设计,听他们讨论,偶尔也加入一起讨论,即使出不了很大的力但是我却可以通过和他们讨论发现自己的不足,这也是一和好的学习机会,至少在讨论的时候我可以知道自己什么地方不懂,然后通过和组员的交流来加深对某一块知识点的理解。这样的学习方式的好处在于我们可以以一种我们都能理解的方式来互相学习。相比于以往的实习,这次实习有很大的不同,以往是自己做自己的,而这次是小组合作,我总是担心因为自己而妨碍到队友影响整个组的进度,但是看到大家一起讨论,一起皱眉,一起收获,我也会很开心,这就是团队的力量吧。即使在实验中遇到不少问题,但是大家一起发现问题,一起讨论,一起解决,在这个过程中也学到很多东西。 对于我个人而言,这并不是一次很成功的实习,但是我相信每一次的经验就是一种收获。虽然之前有接触过串口通信的部分知识,但是都很片面,当时只是学习怎样实现并不清楚其原理,但通过本次实验,在组员的帮助下我可以清楚的解释整个串口通信的原理,也对一些以前很少接触的器件有一些了解,特别是对其功能有更多了解,例如利用MAX232实现电频转化,利用11.0592晶体振荡器产生信号,利用89C52单片机的p3.0和p3.1实现串口通信等等。虽然以前学过但是并没有证实过,而通过实验让我加深对这些器件的认识。虽然在实验过程中遇到一些问题,但是还是被一一解决了。通过实验我更加清楚自己的分量,更加清楚自己应该学习的东西还有很多,也让我体会到团队的力量,看似很困难的问题在大家的努力下都解决了。最重要的是我认识到我们学的每一门学科都有其用途,虽然看似没有多大的用处,但是当运用到实际生活中时才发现这些学科之间有很大的联系。这也提醒我不论是专业知识还是选学知识,我都不可以放轻松,我必须把书本上的知识吃透才可以在进行实验时不那么费劲,而且可以节省实间。总的来说,通过这次实习让我对很多的问题有了新的认识,这对我以后的学习和生活都将是受益匪浅的。 王五: 这次实验中,我主要负责系统仿真的任务,用proteus仿真软件进行仿真,原件有08C51单片机2片,MAX232 2片,8段数码管 1个,触点开关 2个,LED发光二级管 2个,11.0592晶体振荡器 2个,以及各个型号电阻,电容若干,导线若干。 本系统要实现单片机之间的串口通信,最终要实现:两个单片机将串口连接在MAX232芯片上,将电平转化为RS232电平,两个MAX232芯片的输出端相连,形成两个单片机的通信。将数码管连接到甲机上,乙机的一个I/O口接触点开关,当触点开关接通时。乙机计数器加一,并把计数器的值通过串口传给甲机。让甲机驱动数码管显示计数器的值,以此来验证单片机通信成功。 当然实验中也遇到了很多困难:首先是多孔板太小,布置两个单片机最小系统比较拥挤,不得已采用双面布板的办法,空间小给焊接带来了很大麻烦,最后在组员的细致努力下,焊接的比较成功。第二就是再编写程序的过程中,由于需要利用串口中断,需要反复操作定时器,而定时器配置稍显复杂,中间出了很多错误,花了比较长的时间用来调试定时器。最后,严格按照定时器配置流程书写程序,操作成功。最后,由于使用了RS232电平,所以传输的波特率是比较关键的地方,波特率计算应该考虑晶振的频率严格计算。 经过这次实习,首先我学到了单片机最小系统的布局和焊接方法,并懂得了如何在最小系统上扩展其他功能。其次,了解了单片机定时器的各种使用方法和串口通信的流程。最后,明白了串口通信时波特率的计算以及其在通信中的重要性。 赵六: 我们组选的题目是两个单片机实现串口通信,分配好任务之后通过网上、图书馆查资料了解单片机的相关知识。我负责的是电路仿真和硬件设计,通过借鉴一些资料就开始做仿真电路,把问题模块化,最开始做的就是单片机的晶振电路,了解了关于波特率的问题,波特率是指数据信号对载波的调制速率,它用单位时间内载波调制状态改变的次数来表示。在信息传输通道中,携带数据信息的信号单元叫码元,每秒钟通过信道传输的码元数称为码元传输速率,简称波特率。波特率是传输通道频宽的指标。 每秒钟通过信道传输的信息量称为位传输速率,简称比特率。比特率表示有效数据的传输速率。了解到这些之后选择了一个合适的晶振原件,至于电容还是靠查资料来选取的。因为是两片单片机之间要实现串口通信,所以采取了相同的晶振电路,不然通信后会出现乱码问题。在两片单片机串口p3.0和p3.1的链接上遇到了一点问题,通过讨论串口间连接需要电平转换,电平转换是在单片机和pc通信因为电压不一样才转换的,而单片机直接串口电压应该是一致的,因此可以省略掉,但是为了给单片机下载程序方便,我们还是加上了这一部分,仿真电路做好之后还是有很多警告,在仔细检查很多遍之后发现原来是操作问题,因为是两片单片机,电路很对称,所以是对称设计,造成元器件命名重复,更改了之后就好了,给单片机装载好程序之后可以仿真。在硬件电路分布设计这块,因为在仿真阶段布局就比较合理,所以就直接根据仿真图焊接。自己也参与了一些电路焊接,电路弄好之后上电竟然没有反应,检查发现完全是操作问题,很多连接点都没有焊接,电路焊接好之后发现还是有问题,以为是甲乙单片机位置弄反了,调换了之后发现乙这边可以工作,但是电路两部分是对称的,我们又把乙的片子安到甲上,但是甲部分仍然没反应,通过分析确定是甲部分有问题,最后徐顺找到是一个电容坏了,换掉之后就正常了。在功能扩展方面曾考虑到串口加密,就是多个单片机串口通信是的安全问题,无奈自己的软件方面功底很差,就放弃了。通过这次实习我总结到不管什么问题,只要我们细心,努力不放弃的做就都会解决的。 胡七: 刚开始接到这个题目的时候,自己还是很迷茫的,不知道从何下手,因为虽说以前学习过单片机但是仅仅是理论,对他还是很模糊,比如说对定时器,计数器,晶振,机器周期,中断的概念总是一知半解,但是通过这两个周的搜集资料,自我学习,还是有一定成效的,通过读《8051单片机彻底研究》,我豁然开朗,以上的概念我基本上都了解了,并且在读程序的时候,基本上能够知道那些设置的意思,比如说串行通信的时候如何设置波特率,如何利用中断,例如说在串行通信的时候,首先要清除RI和TI,并设置REN=1,使接收和发送进入待命状态,当有数据进入时串口会一一接收,当所有的数据都接收完后,RI的标志会置1,此时程序可以用查询或中断的方式得到RI的状态,若RI=1时再做一个SBUF的读取,然后把数据转存到串行数据缓存区内,最后将RI清零。在接收的时候,首先要查询TI的状态是否为1,是的话说明上一个数据已经送出,这时只要把数据送到SBUF就可以完成数据的传输,然后把TI设成0,表明数据准备送出,等到TI又为1时,表明数据已经送出。在软件仿真的时候也遇到过很多问题,比如说数码管的选取,开始的时候我一直用的是共阴极数码管,但是我本身并没有这个概念,导致程序仿真时出现数码管数字显示不正常,经过一番仔细地检查,我才发现了这个问题,换上了共阳极数码管,结果正常,还有一个问题就是软件仿真的时候正常,而实际运行时却有问题,比如说按键抖动,实际过程中可以用一个延时函数来避开这个抖动。 一切理论和仿真都正确了,然后就是在电路板上焊接电路了,开始按照仿真图焊接了一遍后,不能正常运行,经过仔细地排查后才发现电容坏了,换了电容后正常了。这也让我明白了认真,细心的重要性。焊接好之后就是写程序了,这对我来说应该是一大难点,因为以前都是编一个简单的程序,然后运行,而这次要软硬结合,并且功能还不单一,这就需要整体的概念,如何把握全局,调试过程也是很重要的,每一步是怎样执行的,这都能很清楚的知道,总的来说,这次单片机实习对我来说收获还是很大的。下载本文