单片机串口通讯设计

单片机串口通讯设计
单片机串口通讯设计

1、设计内容和要求

1.1设计内容

本设计采用AT89S52单片机以及MAX232通信芯片配合使用与上位机(计算机)进行串口通讯,根据上位机所发送的不同请求数据来判断计算机所要求单片机所返回的数据。上位机软件采用串口调试助手,在串口调试助手发送区输入相应字符,然后点击发送,串口调试助手软件将数据传送到计算机串口处,采用串口连接线将计算机串口信号传送至MAX232芯片,再通过电平转换将RS232信号转换为单片机所能识别的TTL信号,然后将该信号传输到单片机串行口,将数据传送到单片机内部寄存器进行相应处理。

1.2功能要求:

通过上位机串口调试软件给单片机发送命令,单片机接收到所发送的命令后,进行比较处理,确定上位机信息内容后,返回上位机所请求的数据。具体通信波特率和校验方法设置为:

通信波特率:9600bps;

校验方式:无校验;

数据位:8位;

停止位:1位。

具体发送和接收要求为:

首先上位机发送请求命令,当单片机接送到上位机的请求命令后,判断上位机是何数据,然后给出相应的返回数据,具体发送和接收的数据如下表所示:

2、系统总体结构

2.1功能模块描述

本设计为上位机与单片机通讯,单片机采用UART串行口,计算机采用串口,考虑到单片机串行口输出的是TTL电平信号,而计算机串口输出的是RS232信号,两种信号存在不兼容的问题,因此需要进行电平转换以达到电平兼容的目的,所以我们还需要选择另外一种具有TTL信号到RS232信号转换功能的芯片,本设计中要求采用交流9V电源供电,而我们单片机以及其他芯片工作所需要的电压为直流,因此这里我们必须将电压性质转化一下,否则芯片将不能正常工作。

整流的方法有半波整流和桥式整流两种方法,半波整流效率较低,只有输入电压的0.45倍,输入交流电压为9V,半波整流后输出的电压仅为4.05V,而我们单片机正常工作的电压为直流5V,不能满足要求,因此半波整流方式不可取。在本设计中我们选择桥式整流方式,其输出电压为输入电压的0.9倍,输入电压为交流9V时,输出电压为8.1V大于单片机工作电压,可以选择,整流后输出直流电压波动较严重,因此在整流输出端我们需要增加滤波

网络,进行稳定输出电压。

由于桥式整流电路输出电压大于我们芯片所能承受的最大电压,因此需要增加降压网络,将整流桥输出电压降低到芯片的工作电压5V。为保证电路板加电后能够有上电指示功能,因此在降压网络输出端增加发光二极管作为上电指示灯。

本设计中,当上位机下发请求数据时,下位机(单片机)能够识别下发数据并显示所下发的数据,正常下发请求命令为'1'、'2'、'3'、'4'或其他数据或字符,设计要求电路板能够正常显示'1'、'2'、'3'、'4',显示其他数据或字符时不必显示,因此这里我们需要选择一个8段数码管即可。

2.2功能模块框图

3、硬件设计

3.1硬件介绍

3.1.1单片机介绍

AT89S52 是一种低功耗、高性能CMOS8位微控制器,具有8K 在系统可编程Flash存储器。使用Atmel 公司高密度非易失性存储器技术制造,与工业80C51 产品指令和引脚完全兼容。片上Flash允许程序存储器在系统可编程,亦适于常规编程器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得AT89S52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。AT89S52具有以下标准功能:8k字节Flash,256字节RAM,

32 位I/O 口线,看门狗定时器,2 个数据指针,三个16 位定时器/计数器,

一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。另外,AT89S52 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲

模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。

掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。

端口0是一个8位宽的开路汲极(Open Drain)双向输出入端口,共有8

个位,P0.0表示位0,P0.1表示位1,依此类推。其他三个I/O端口(P1、P2、P3)则不具有此电路组态,而是内部有一提升电路,P0在当做I/O用时可以推动8个LS的TTL负载。端口1也是具有内部提升电路的双向I/O端口,其输出缓冲器可以推动4个LS TTL负载,同样地若将端口1的输出设为高电平,便是由此端口来输入数据。端口3也具有内部提升电路的双向I/O端口,其输出缓冲器可以推动4个TTL负载,同时还多工具有其他的额外特殊功能,包括串行通信、外部中断控制、计时计数控制及外部数据存储器内容的读取或写入控制等功能。端口2是具有内部提升电路的双向I/O端口,每一个引脚可以推动4个LS的TTL 负载,若将端口2的输出设为高电平时,此端口便能当成输入端口来使用。端口3也具有内部提升电路的双向I/O端口,其输出缓冲器可以推动4个TTL负载,同时还多工具有其他的额外特殊功能,包括串行通信、外部中断控制、计时计数控制及外部数据存储器内容的读取或写入控制等功能。

其引脚分配如下:

P3.0:RXD,串行通信输入。

P3.1:TXD,串行通信输出。

P3.2:INT0,外部中断0输入。

P3.3:INT1,外部中断1输入。

P3.4:T0,计时计数器0输入。

P3.5:T1,计时计数器1输入。

P3.6:WR:外部数据存储器的写入信号。

P3.7:RD,外部数据存储器的读取信号。

3.1.2 RS232芯片介绍

MAX232芯片是美信(MAXIM)公司专为RS-232标准串口设计的单电源电平转换芯片,使用+5v单电源供电。

管脚介绍:

第一部分是电荷泵电路。由1、2、3、4、5、6脚和4只电容构成。功能是产生+12v和-12v两个电源,提供给RS-232串口电平的需要。第二部分是数据转换通道。由7、8、9、10、11、12、13、14脚构成两个数据通道。其中13脚(R1IN)、12脚(R1OUT)、11脚(T1IN)、14脚(T1OUT)为第一数据通道。8脚(R2IN)、9脚(R2OUT)、10脚(T2IN)、7脚(T2OUT)为第二数据通道。TTL/CMOS数据从11引脚(T1IN)、10引脚(T2IN)输入转换成RS-232数据从14脚(T1OUT)、7脚(T2OUT)送到电脑DB9插头;DB9插头的RS-232数据从13引脚(R1IN)、8引脚(R2IN)输入转换成TTL/CMOS数据后从12引脚(R1OUT)、9引脚(R2OUT)输出。第三部分是供电。15脚GND、16脚VCC(+5v)。

3.2电路介绍

3.2.1电源电路

为满足实物能够兼容交流和直流9V电压输入,在输入网络中增加整流桥,后级电路中增加滤波电容,来满足不论直流还是交流电压输入,输出端均能得到稳定的直流电压,而且直流电压输入时不受电压正负极限制,可以任意接入。考

虑到芯片正常工作时所需要的电压为DC5V,因此需要增加降压网络,将输出电压稳定在5V,而且需要具有一定的输出功率,本设计中我们选择L7805三端稳压芯片,该芯片最大输出电流为1A,输出电压为DC5V,完全满足本设计要求。为了能够显示外部电压是否正常接入,因而在电压输出端增加电源指示功能,该功能由发光二极管和限流电阻组成。电路如下图所示:

3.2.2单片机最小系统

本设计使用的单片机为AT89S52单片机,封装形式为DIP40。单片机能够正常工作需要满足一下硬件条件:

1、单片机所需要的工作电压需要正常接入(DC5V)。

2、单片机工作所需要的时钟需要正常接入(一般采用晶体振荡器产生)。

3、单片机上电后须有复位信号产生后方能正常工作,因此复位电路必不可少。以上三点为单片机能够正常工作的必要条件,也即单片机最小系统。本设计中由于所需处理的数据量比较少,因此编译后产生的机器码文件比较小,单片机本身具有8K的ROM存储空间,足够本设计需求。因此无需外扩ROM存储单元,使用内部ROM即可,因此在硬件设计上面不必考虑外扩ROM,即P0口和P2口无需增加锁存器来锁存外部寻址所需要的数据存储地址,减少比必要元器件的使用,节省布板空间,从而简化了设计。AT89S51单片机规定使用外部存储空间(即外扩ROM)时,单片机使能信号(即EA管脚)必须下拉,当使用内部存储空间时该引脚必须上拉,由于被设计中采用内部ROM,因此,需要将该引脚上

拉。电路如下图所示:

3.2.3 RS232通信电路

本设计中RS232通讯采用MAX232芯片,该芯片输入电压为DC5V,由于RS232输出端为±12V电压,因此需要升压,该芯片借助外接4个0.1uF电路实现升压功能。该芯片为双通道,本设计中只需要选择其一即可。

4、软件设计

4.1单片机I/O口分配

4.2程序流程图

主函数流程图中断函数流程图

5、系统调试

根据原理图焊接电路,焊接时注意元器件以及连接导线之间不能有短路或开路现象。用万用表测试已经焊接完毕的电路板,检验是否有短路现象,特别是电源模块,确保没有短路现象后,给电路板上电9V,同时在电路中串接电流表,观察工作电流,若工作电流远大于20mA,应立即断电,查找原因。具体查找电源模块有无短路现象、元器件参数是否焊接错误、芯片是否焊接反等现象。代问题解决后,开始根据软件流程图编写程序。

程序编辑过程中需要不断调试,在线监测数据变化。待程序编辑完成后,将编译后产生的机器码文件即HEX文件通过程序下载软件,下载到单片机ROM中。给电路板上电,观察单片机工作,若数码管没有显示切无产行数据接收,考虑单片机有没有正常工作;主要检查晶体振荡器有没有正常工作,可使用示波器观察晶振波形,能观察到正弦波信号且频率在11MHZ左右,说明晶体振荡器已经正常工作,下一步检查复位电路是否正常,查看电路是否接错,电路参数能不能足以让单片机正常复位,最后检查使能信号端EA是否对电源地之间有5V电压,待硬件故障排除以后,开始软件调试,反复修改程序,并下载到单片机ROM中,观察程序运行情况,直至正常为止。

6、实验小结

这次实习让我受益匪浅,无论从知识上还是其他的各个方面。上课的时候的学习从来没有见过真正的单片机,只是从理论的角度去理解枯燥乏味。

但在实习中见过甚至使用了单片机及其系统,能够理论联系实际的学习,开阔了眼界,提高了单片机知识的理解和水平。

在做本次课程设计的过程中,我感触最深的当属查阅大量的设计资料了。为了让自己的设计更加完善,查阅这方面的设计资料是十分必要的,同时也是必不可少的。我们是在做单片机课程设计,但我们不是艺术家,他们可以抛开实际尽情在幻想的世界里翱翔,而我们一切都要有据可依,有理可寻,不切实际的构想永远只能是构想,永远无法升级为设计。

其次,在这次课程设计中,我们运用到了以前所学的专业课知识,如:CAD制图、汇编语言、模拟和数字电路知识等。虽然过去从未独立应用过它们,但在学习的过程中带着问题去学我发现效率很高,这是我做这次课程设计的又一收获。要做好一个课程设计,就必须做到:在设计程序之前,对所用单片机的内部结构有一个系统的了解,知道该单片机内有哪些资源;要有一个清晰的思路和一个完整的的软件流程图;在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便;在设计课程过程中遇到问题是很正常德,但我们应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题的课程设计结束了,但是从中学到的知识会让我受益终身。

发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。设计过程,好比是我们人类成长的历程,常有一些不如意,但毕竟这是第一次做,难免会遇到各种各样的问题。在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。

在本次课程设计过程中也遇到了许多问题,有些问题在自己查找资料中解决了,还有一些问题无从下手,通过我们的指导老师庄老师的悉心指导,耐心的讲解使我茅塞顿开,瞬时豁然开朗,令人心情舒畅。在设计中收获了不少乐趣,最重要的是学到的许多的知识,在今后的工作和学习中一定大有用处!在此向我们的指导老师庄老师表示感谢!

7、参考文献

附录:

①元器件清单

②原理图

③程序清单

#include

#include

#define uchar unsigned char

#define uint unsigned int

uchar code str1[]="what do you plan to do this Friday?"; uchar code str2[]="I playn to go to cencert.";

uchar code str3[]="what are you ding next week?";

uchar code str4[]="i'm thingking of going to my Grandma's."; uchar code str5[]="please select a character '1','2','3','4'!"; uint flag,flag1=0,num;

void sendString(uchar *ucString);

main()

{

EA=1; //开总中断中断

ES=1; //开串口中断

REN=1;//开允许串口接收

SM0=0;//设置串口工作方式

SM1=1;

TR1=1; //开定时器T1

TMOD=0X20; //设置定时器工作方式

TH1=0XFD; //设定定时器自动重载值

TL1=0XFD; //设定定时器初值

while(1)

{

if(flag1==1) //允许进入主函数

{

switch(num)

{

case 1:

{

if(flag==0)

{

sendString(str1);

P2=0xf2;

}

}

break;

case 2:

{

if(flag==0)

{

sendString(str2);

P2=0x88;

}

}

break;

case 3:

{

if(flag==0)

{

sendString(str3);

P2=0xa0;

}

}

break;

case 4:

{

if(flag==0)

{

sendString(str4);

P2=0x32;

}

}

break;

default:

{

if(flag==0)

{

sendString(str5);

P2=0xbe;

}

}

break;

}

flag1=0;

}

}

}

void sendString(uchar *ucString) //发送字符串函数

{

uchar i,stringLength=strlen(ucString); //定义变量并接收字符串长度REN=0;

for(i=0;i

{

SBUF=ucString[i];

while(TI==0);

TI=0;

}

SBUF=0x0d; while(TI==0); TI=0;//REN=1; //发送回车命令

SBUF=0x0a; while(TI==0); TI=0;//REN=1; //发送换行命令

REN=1; //打开串口

flag=1; //数据接收完毕停止接收

}

void timer() interrupt 4 //串口中断函数

{

if(RI==1)

{

RI=0;

flag=0;

flag1=1;

num=SBUF;

}

相关主题
相关文档
最新文档