用AT89S51与PC机实现串口通讯.docx
- 文档编号:24212131
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:15
- 大小:135.31KB
用AT89S51与PC机实现串口通讯.docx
《用AT89S51与PC机实现串口通讯.docx》由会员分享,可在线阅读,更多相关《用AT89S51与PC机实现串口通讯.docx(15页珍藏版)》请在冰豆网上搜索。
用AT89S51与PC机实现串口通讯
桂林电子科技大学
单片机最小应用系统
设
计
报
告
指导老师:
吴兆华
学生:
林承德
学号:
092011221
机电工程学院
2010年6月
一、设计题目
用AT89S51与PC机实现串口通讯,单片机接收上位机发送的数字,并在最小系统板上的数码管上将其显示。
二、系统硬件电路图
系统硬件图包括单片机最小系统(复位电路、晶振电路和相关的控制信号)、串口通讯电路以及数字显示部分。
设计硬件电路图时,其基本思想:
先在proteus中搭建仿真电路,将编好的程序下载到仿真环境的51中,等可以达到预期要求后,最后在PROTEL中设计原理图与PCB,做出电路板。
图2.0系统硬件全局图
2.1单片机最小系统电路图
2.2串口通讯原理及其电路图
一、发送和接收的过程如下:
串行口的发送过程由指令MOVSBUF,A启动,即CPU由一条写发送缓冲器的指令把数据(字符)写入串行口的发送缓冲器SBUF(发)中,再由硬件电路自动在字符的始、末加上起始位(低电平)、停止位(高电平)及其它控制位(如奇偶位等),然后在移位脉冲SHIFT的控制下,低位在前,高位在后,从TXD端(方式0除外)一位位地向外发送。
串行口的接收与否受制于允许接收位REN的状态,当REN被软件置“1”后,允许接收器接收。
接收端RXD一位位地接收数据,直到收到一个完整的字符数据后,控制电路进行最后一次移位,自动去掉启始位,使接收中断标志RI置“1”,并向CPU申请中断。
CPU响应中断,用一条指令(MOVA,SBUF)把接收缓冲器SBUF(收)的内容读入累加器。
TI和RI是由硬件置位的,但需要用软件复位。
二、相关的寄存器
1、SBUF是两个在物理上独立的接收、发送缓冲器,可同时发送、接收数据。
两个缓冲器只用一个字节地址99H,可通过指令对SBUF的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。
串行口对外有两条独立的收发信号线RXD(P3.0)、TXD(P3.1),因此可以同时发送、接收数据,实现全双工。
2、SCON寄存器用来控制串行口的工作方式和状态,可按位寻址,其字节地址为98H。
3、PCON中的SMOD用来控制波特率加倍。
4、TMOD设置定时器1的工作方式,用来产生波特率
5、如果用到中断,则还需要用到中断相关的寄存器IE,IP等
2.3数码管显示电路
三、单片机和PC程序
3.1单片机程序
#include
#include
unsignedcharinbuf[4];
bitread_flag=0;
unsignedintcnt=3;
unsignedcharch=0;
unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x00};
voiddisplay();
voiddelay(intz);
voidinit_serialcomm(void)
{
SCON=0x50;//SCON:
serailmode1,8-bitUART,enableucvr
TMOD|=0x20;//TMOD:
timer1,mode2,8-bitreload
PCON|=0x80;//SMOD=1;
TH1=0xF4;//Baud:
4800fosc=11.0592MHz
TL1=0xF4;
IE|=0x90;//EnableSerialInterrupt
TR1=1;//timer1run
}
//向串口发送一个字符
voidsend_char_com(unsignedcharch)
{
SBUF=ch;
while(TI==0);
TI=0;
}
//向串口发送一个字符串,strlen为该字符串长度
voidsend_string_com(unsignedchar*str)
{
unsignedintk=0;
for(k=4;k>0;k--)
{
send_char_com(*(str+k-1));
}
}
//串口接收中断函数
voidserial()interrupt4using3
{
if(RI)
{
RI=0;
if(cnt>=0)
{
if((47 { inbuf[cnt]=SBUF; } else { inbuf[cnt]=0; } if(cnt>0) { --cnt; } elseif(cnt==0) { send_string_com(inbuf); cnt=3; } } } } main() { init_serialcomm();//初始化串口 while (1) { display(); delay(5); } } voidjudg(int*a,intb); voiddisplay() { unsignedintqian,bai,shi,ge; qian=inbuf[3]-48; judg(&qian,10); bai=inbuf[2]-48; judg(&bai,10); shi=inbuf[1]-48; judg(&shi,10); ge=inbuf[0]-48; judg(&ge,10); P2=0xf7;//位选,显示个位字码 P0=table[ge]; delay (1); P2=0xff;//消隐, P2=0xfb;//位选,显示十位字码 P0=table[shi];//送段码 delay (1); P2=0xff;//消隐 P2=0xfd;//位选,显示百位字码 P0=table[bai];//送段码 delay (1); P2=0xff;//消隐 P2=0xfe;//位选,显示千位字码 P0=table[qian];//送段码 delay (1); P2=0xff;//消隐 } voidjudg(int*a,intb) { if(*a==b) { *a=10; } } voiddelay(intz)//延时函数,约z毫秒(在晶振12MHZ时) { intx,y; for(y=z;y>0;y--) for(x=110;x>0;x--); } 3.2上位机软件 上位机软件在VC6.0上编写调试。 工程下的类及其函数、变量定义情况 工程下的文件列表 图3.1上位机通信软件界面 1.串口打开关闭切换按钮的处理函数 voidCSerialPortDlg: : OnBtnOpen() { //TODO: Addyourcontrolnotificationhandlercodehere if(! m_mymscom.GetPortOpen()) { m_mymscom.SetPortOpen(true); GetDlgItem(IDC_BTN_OPEN)->SetWindowText("关闭串口"); m_icon_open.ShowWindow(SW_SHOW); m_icon_close.ShowWindow(SW_HIDE); SetTimer(2,10,NULL); } else { m_mymscom.SetPortOpen(false); GetDlgItem(IDC_BTN_OPEN)->SetWindowText("打开串口"); m_icon_open.ShowWindow(SW_HIDE); m_icon_close.ShowWindow(SW_SHOW); KillTimer (2); } } 2.串口发送数据按钮的处理函数 voidCSerialPortDlg: : OnBtnSend() { //TODO: Addyourcontrolnotificationhandlercodehere intk; if(m_mymscom.GetPortOpen()) { UpdateData(true); if(m_sendstr.GetLength()>=4) { m_strsended=m_sendstr.Left(4); m_mymscom.SetOutput(COleVariant(m_strsended)); m_sendstr.Delete(0,4); } elseif(m_sendstr.GetLength()>0) { for(k=1;k<6;k++) { m_sendstr+=": "; } m_strsended=m_sendstr.Left(4); m_mymscom.SetOutput(COleVariant(m_strsended)); m_sendstr.Delete(0,m_sendstr.GetLength()); } m_streceiv=m_strsended; UpdateData(false); }else{MessageBox("串口已关闭,请先打开串口! ");} } 3.对话框初始化函数 BOOLCSerialPortDlg: : OnInitDialog() { CDialog: : OnInitDialog(); //Add"About..."menuitemtosystemmenu. m_slectport.AddString("COM1");//初始化下拉列表 m_slectport.AddString("COM2"); m_slectport.AddString("COM3"); m_slectport.SetCurSel(0); m_setband.AddString("300"); m_setband.AddString("600"); m_setband.AddString("1200"); m_setband.AddString("2400"); m_setband.AddString("4800"); m_setband.AddString("9600"); m_setband.AddString("19200"); m_setband.SetCurSel(4); if(m_mymscom.GetPortOpen()) { MessageBox("串口1已被占用! "); } else{ m_mymscom.SetCommPort (1);//选择串口1 m_mymscom.SetSettings("4800,N,8,1");//设置波特率、校验位、数据位等通信参数 m_mymscom.SetInputLen(4); m_mymscom.SetRThreshold(4); } …… } 4.定时器回调处理函数 voidCSerialPortDlg: : OnTimer(UINTnIDEvent) { //TODO: Addyourmessagehandlercodehereand/orcalldefault UpdateData(true); m_strsended=m_sendstr.Left(4); m_mymscom.SetOutput(COleVariant(m_strsended)); if(m_sendstr.GetLength()>=4) { m_sendstr.Delete(0,4); } else { m_sendstr.Delete(0,m_sendstr.GetLength()); } UpdateData(false); } 图3.2软件运行界面 四、设计体会 1、通过此次单片机最小系统的应用开发,增加了我对电路控制专业的兴趣,尤其是通过单片机进行自动控制方面,在设计及单片机最小系统中,我既掌握了新知识(主要是max232芯片在串口通讯中的的应用),又加深了对所学过的知识认识(主要是编程指令的灵活应用、单片机最小系统的理解和PROTELDXP软件的灵活使用),还提高了自己的分析问题和解决问题的能力和方法(主要是在调试程序时串口通讯上的控制上),最后提高了动手能力(主要是在电路板的制作上面),尤为可贵的是学会了查阅相关的资料,并进行独立的原理图设计,电路板的制作和程序的独立调整,以及出现问题时候,独立思考分析解决问题的能力。 虽然很辛苦,但是最终能够达到设计课题的要求。 2、初步学会了独立设计电路图的能力。 我首先在图书馆查找并综合与课题相关的资料(串口通讯和max232的应用),在头脑中形成一个感性的认识,并渐渐地用所学过的单片机指令(主要是C语言)编程以及上位机的VC编程,然后再借助试验台,将自己编好的程序一步一步地调试出来,用能够成功程序所需要的硬件电路来返回来设计自己的电路板。 初步养成了自己独立解决问题的方法与能力。 五、参考文献 [1]陈光东 赵性初单片微型计算机原理与接口技术.武汉: 华中理工大学出版社,1993.2 [2]马家辰孙玉德张颖.MCS-51单片机原理及接口技术[M].哈尔滨: 哈尔滨工业大学出版社,2001. [3]马光.单片机原理及应用[M].北京: 机械工业出版社,2006. [4]黎文模.ProtelDXP电路设计与实例精解[M].北京: 人民邮电出版社,2006. [5]秦曾煌电工学[M].北京: 高等教育出版社,1999. [6]赵景波 王劲松滕敦朋 Protel2004电路设计从基础到实践北京: 电子工业出版社,2007
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AT89S51 PC 实现 串口 通讯