VC与c51串口通讯程序
51单片机的串口通信程序(C语言)
51单片机的串口通信程序(C语言) 51单片机的串口通信程序(C语言)在嵌入式系统中,串口通信是一种常见的数据传输方式,也是单片机与外部设备进行通信的重要手段之一。
本文将介绍使用C语言编写51单片机的串口通信程序。
1. 硬件准备在开始编写串口通信程序之前,需要准备好相应的硬件设备。
首先,我们需要一块51单片机开发板,内置了串口通信功能。
另外,我们还需要连接一个与单片机通信的外部设备,例如计算机或其他单片机。
2. 引入头文件在C语言中,我们需要引入相应的头文件来使用串口通信相关的函数。
在51单片机中,我们需要引入reg51.h头文件,以便使用单片机的寄存器操作相关函数。
同时,我们还需要引入头文件来定义串口通信的相关寄存器。
3. 配置串口参数在使用串口通信之前,我们需要配置串口的参数,例如波特率、数据位、停止位等。
这些参数的配置需要根据实际需要进行调整。
在51单片机中,我们可以通过写入相应的寄存器来配置串口参数。
4. 初始化串口在配置完串口参数之后,我们需要初始化串口,以便开始进行数据的发送和接收。
初始化串口的过程包括打开串口、设置中断等。
5. 数据发送在串口通信中,数据的发送通常分为两种方式:阻塞发送和非阻塞发送。
阻塞发送是指程序在发送完数据之后才会继续执行下面的代码,而非阻塞发送是指程序在发送数据的同时可以继续执行其他代码。
6. 数据接收数据的接收与数据的发送类似,同样有阻塞接收和非阻塞接收两种方式。
在接收数据时,需要不断地检测是否有数据到达,并及时进行处理。
7. 中断处理在串口通信中,中断是一种常见的处理方式。
通过使用中断,可以及时地响应串口数据的到达或者发送完成等事件,提高程序的处理效率。
8. 串口通信实例下面是一个简单的串口通信实例,用于在51单片机与计算机之间进行数据的传输。
```c#include <reg51.h>#include <stdio.h>#define BAUDRATE 9600#define FOSC 11059200void UART_init(){TMOD = 0x20; // 设置定时器1为模式2SCON = 0x50; // 设置串口为模式1,允许接收TH1 = 256 - FOSC / 12 / 32 / BAUDRATE; // 计算波特率定时器重载值TR1 = 1; // 启动定时器1EA = 1; // 允许中断ES = 1; // 允许串口中断}void UART_send_byte(unsigned char byte){SBUF = byte;while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志位}unsigned char UART_receive_byte(){while (!RI); // 等待接收完成RI = 0; // 清除接收完成标志位return SBUF;}void UART_send_string(char *s){while (*s){UART_send_byte(*s);s++;}}void main(){UART_init();UART_send_string("Hello, World!"); while (1){unsigned char data = UART_receive_byte();// 对接收到的数据进行处理}}```总结:通过以上步骤,我们可以编写出简单的51单片机串口通信程序。
VC编程实现串口通信软件
一、VC编程实现串口通信软件首先,我们来大概的回忆一下单片机的串口通信。
8051单片机的串行接口由数据缓冲寄存器SBUF、移位寄存器、串行控制寄存器SCON组成。
8051单片机的串行接口是一个可编程的全双工通信接口,通过软件编程可以作为通用异步接收和发送器使用,也可作为同步移位寄存器,还可实现多机通信。
其帖格式有8位、10位和11位,通过T1或T2设置各种波特率。
1.1 串行口工作原理在发送和接收数据前,先对串行口进行初始化设置,要明确串行口的工作方式、波特率等。
1.发送数据发送数据,由累加器A送入发送缓冲寄存器SBUF,在发送控制器控制下组成帧结构,并自动以串行方式从TXD输出,每发送完一帧TI置位,可以通过中断方式或查询方式来了解数据的发送情况。
值得注意的是TI只能用软件复位。
2.接收数据单片机每接收完一帧数据,RI置位,通过中断或查询方式来了解数据的接收情况,然后用MOV A,S BUF指令,将接收缓冲寄存器(SBUF)的值送累加器A。
RI与TI一样,也只能用软件复位。
1.2串行口工作方式8051单片机通过编程可选择4种串行通信工作方式。
1.方式0在方式0下,串行口用作同步移位寄存器,以8位数据为1帧,先发送或接收最低位,每个机器周期发送或接收1位,其波特率为fosc/12。
串行数据由RXD端输入或输出,同步移位脉冲由TXD端送出。
方式0数据发送与接收是无起始位和停止位,先发送或接收最低位,数据格式为:—D0 D1 D2 D3 D4 D5 D6 D72.方式1在方式1下,串行口为10位通用异步接口,数据格式为:——0 D0 D1 D2 D3 D4 D5 D6 D7 1 ——发送数据:当执行MOV SBUF,A指令,CPU将1字节的数据写入发送缓冲寄存器SBUF,数据从引脚TXD端输出,当发送完1帧数据后,TI标志置1,可用中断或查询方式来了解数据发送情况,TI只有通过软件复位。
接收数据:接收时,先使REN置1,使串行口处于允许接收状态,RI标志为0,串行口采样到RXD由1到0时,确认是起始位0,就开始接收1帧数据。
用VC实现PC机与单片机串口通讯
用VC实现PC机与单片机串口通讯梁伯福PC机与单片机串口通讯可以通过多种方式来实现,在这里只介绍使用MSCOMM控件进行通讯。
PC机与单片机进行串口通讯的电路如下:因为单片机输入输出的是TTL电平,而PC机串口输入输出的是RS232电平,其与TTL 电平不兼容,所以要通过RS232接口进行电平转换,这可通过集成电路MAX232来实现。
在这里,我们的通讯采用主从方式,即PC机做主机,单片机作从机,PC机控制单片机发送或者接收数据,单片机没有主动发起通讯的权力。
PC机程序。
我们首先在VC中通过appWizard生成一个基于对话框的程序,接着在对话框中添加MSCOMM控件。
方法是:右击对话框-> insert activeX control -> MSCOMM32.OCX。
添加MSCOMM控件后,我们需要在头文件中定义一个类型为CMScomm的变量。
CMSComm m_msComm;// CMSComm是添加控件后VC自动生成的类接着我们使用此变量对串口进行初始化操作(可在对话框初始化时或通讯前调用此函数)。
void InitComm(){m_msComm.SetCommPort(1); // 设置通讯的串口,可为1,2,….,N//(如你的PC机有N个串口的话)m_msComm.SetInputMode(1); //设置接收模式,0为文本,1为二进制,要想能接收//值为0的数据,一定要设置为二进制模式m_msComm.SetInputLen(0); // 设置读取方式,0为读取接收缓冲区的全部数据m_msComm.SetSettings("4800, n, 8, 1"); //设置串口的波特率为4800,//无校验位,8数据位, 1位停止位m_msComm.SetPortOpen(true); // 打开串口,准备通讯}为了方便,我们这里假定PC机一次只接收或发送一个数据。
C51编写 串口通信程序
异步通信的数据格式 :
一个字符帧 空 闲 起 始 位 数据位 校 验 位 停 止 位 空 闲
下一字符 起始位
LSB
MSB
异步通信的特点:不要求收发双方时钟的 严格一致,实现容易,设备开销较小,但 每个字符要附加2~3位用于起止位,各帧 之间还有间隔,因此传输效率不高。
2、同步通信
同步通信时要建立发送方时钟对接收方时钟的直接控制, 使双方达到完全同步。此时,传输数据的位之间的距离均 为“位间隔”的整数倍,同时传送的字符间不留间隙,即 保持位同步关系,也保持字符同步关系。发送方对接收方 的同步可以通过两种方法实现。
串行通信是将数据字节分成一位一位的形 式在一条传输线上逐个地传送。
接 收 设 备
D0 D7
8位顺次传送
发 送 设 备
串行通信的特点:传输线少,长距离传送时 成本低,且可以利用电话网等现成的设备, 但数据的传送控制比并行通信复杂。
7.1.1 串行通信的基本概念
一、异步通信与同步通信
1、异步通信 异步通信是指通信的发送与接收设备使用各自的时钟 控制数据的发送和接收过程。为使双方的收发协调,要求 发送和接收设备的时钟尽可能一致。
面向位的同步格式 :
8位 01111110 8位 地址场 8位 控制场 ≥0位 信息场 16位 校验场 8位 01111110
此时,将数据块看作数据流,并用序列01111110作为开始 和结束标志。为了避免在数据流中出现序列01111110时引起 的混乱,发送方总是在其发送的数据流中每出现5个连续的1 就插入一个附加的0;接收方则每检测到5个连续的1并且其后 有一个0时,就删除该0。 典型的面向位的同步协议如ISO的高级数据链路控制规程 HDLC和IBM的同步数据链路控制规程SDLC。 同步通信的特点是以特定的位组合“01111110”作为帧的 开始和结束标志,所传输的一帧数据可以是任意位。所以传 输的效率较高,但实现的硬件设备比异步通信复杂。
串口通讯vc源程序
串口通讯vc源程序串口通讯vc源程序摘要:探讨在使用Visual C++编程时利用Microsoft Communications Control控件编写串行通信程序的方法,并给出了例程,具有一定的实用意义。
关键词:Visual C++ 串行通信 ActiveX在开发微机控制系统的过程中,我们经常需要通过RS-232串行接口与外部设备进行通信。
例如分级控制系统中上位机与下位机的数据交换以及数据采集系统中计算机与数字仪表的通信等。
在DOS时代,编写串行通信程序是一件相当复杂的工作,程序员需要具备相当的硬件知识,对可编程串行通信接口芯片的内部寄存器定义、工作方式、指令字等相关内容有所了解,才有可能着手编写程序,大量的时间和精力都花在了如何与硬件打交道上,而不是花在我们的主要目的——获取与处理数据上;在Windows下,Win32API提供了使用CreateFile/WriteFile 等文件I/O函数进行串行口操作的方法,但是在实现上仍然是相当烦琐的。
幸运的是,Windows 平台先进的ActiveX技术使我们在对串行口编程时不再需要处理烦琐的细节。
利用已有的ActiveX控件,我们只需要编写少量的代码,就可以轻松高效地完成任务。
本文以Windows 98下用Visual C++6.0开发PT650C秤重显示器的通信模块为例,探讨了使用Microsoft Communications Control控件进行串行通信的方法。
1 ActiveX控件介绍ActiveX是Windows下进行应用程序开发的崭新技术,它的核心内容是组件对象模型COM(Component Object Model)。
ActiveX控件包括一系列的属性、方法和事件,使用ActiveX 控件的应用程序和ActiveX控件之间的工作方式是客户/服务器方式,即应用程序通过ActiveX 控件提供的接口来访问ActiveX控件的功能。
Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。
VC++串口通信编程
在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信。
串口通信方便易行,应用广泛。
一般情况下,工控机和各智能仪表通过RS485总线进行通信。
RS485的通信方式是半双工的,只能由作为主节点的工控PC机依次轮询网络上的各智能控制单元子节点。
每次通信都是由PC机通过串口向智能控制单元发布命令,智能控制单元在接收到正确的命令后作出应答。
在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX控件,这种方法程序简单,但欠灵活。
其二是调用Windows的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活。
本文我们只介绍API串口通信部分。
串口的操作可以有两种操作方式:同步操作方式和重叠操作方式(又称为异步操作方式)。
同步操作时,API函数会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而重叠操作方式,API函数会立即返回,操作在后台进行,避免线程的阻塞。
无论那种操作方式,一般都通过四个步骤来完成:(1)打开串口(2)配置串口(3)读写串口(4)关闭串口(1)打开串口Win32系统把文件的概念进行了扩展。
无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的。
该函数的原型为:HANDLE CreateFile( LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDistribution,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);•lpFileName:将要打开的串口逻辑名,如“COM1”;•dwDesiredAccess:指定串口访问的类型,可以是读取、写入或二者并列;•dwShareMode:指定共享属性,由于串口不能共享,该参数必须置为0;•lpSecurityAttributes:引用安全性属性结构,缺省值为NULL;•dwCreationDistribution:创建标志,对串口操作该参数必须置为OPEN_EXISTING;•dwFlagsAndAttributes:属性描述,用于指定该串口是否进行异步操作,该值为FILE_FLAG_OVERLAPPED,表示使用异步的I/O;该值为0,表示同步I/O操作;•hTemplateFile:对串口而言该参数必须置为NULL;同步I/O方式打开串口的示例代码:HANDLE hCom; //全局变量,串口句柄hCom=CreateFile("COM1",//COM1口GENERIC_READ|GENERIC_WRITE, //允许读和写0, //独占方式NULL,OPEN_EXISTING, //打开而不是创建0, //同步方式NULL);if(hCom==(HANDLE)-1){AfxMessageBox("打开COM失败!");return FALSE;}return TRUE;重叠I/O打开串口的示例代码:HANDLE hCom; //全局变量,串口句柄hCom =CreateFile("COM1", //COM1口GENERIC_READ|GENERIC_WRITE, //允许读和写0, //独占方式NULL,OPEN_EXISTING, //打开而不是创建FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式NULL);if(hCom ==INVALID_HANDLE_VALUE){AfxMessageBox("打开COM失败!");return FALSE;}return TRUE;(2)、配置串口在打开通讯设备句柄后,常常需要对串口进行一些初始化配置工作。
51单片机与PC机串口通信的仿真与实现
51单片机与PC机串口通信的仿真与实现作者:李健来源:《电脑知识与技术》2018年第32期摘要:介绍了利用几种常见软件实现的51单片机与PC机串口通信的仿真过程,可以在单片机课程的理论教学中加以应用,具有效率高、成本低等优点,有助于教师的教学和学生对知识的掌握和应用。
关键词:51单片机;PC机;串口通信;仿真中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2018)32-0038-02在实际应用中,单片机与PC机间的通信非常普遍[1]。
这时单片机主要完成现场数据采集和设备监控[2],PC机接收单片机发来的数据进行分析、处理,并对结果再次发送单片机进行现场控制等。
笔者在单片机课程的理论教学中,由于课堂上受到条件的约束,采用了纯软件的方法对单片机串口通信进行仿真和演示,便于实现和让学生理解。
下面通过一个实例来介绍51单片机与PC机之间串口通信的仿真与实现过程。
1 所需软件使用到的软件有:VSPD、Proteus、Keil和串口助手[3]。
VSPD是一个虚拟串口小软件,可以虚拟出一对串行接口用于仿真;Proteus是一款流行的单片机仿真软件,用于建立串口通信仿真电路;Keil是用于编写单片机程序的软件;串口助手是用于上位机即PC机的软件,用来向单片机发送数据,或者接收单片机发送来的数据并进行显示。
2 设计与仿真过程预期实现的功能为:PC机通过串口助手向单片机发送一个字节数据,单片机接收到后将数据的二进制形式通过八个数码管的亮灭显示出来,接收的“1”对应的灯亮,接收的“0”对应的灯灭。
同时单片机将接收的数据发回给PC机,PC机将数据在串口助手中再显示出来。
2.1 利用Proteus设计仿真电路如图1所示,在Proteus软件中选用AT89C51单片机、COMPIM、电阻和发光二极管组成仿真电路。
COMPIM在仿真中相当于PC机上配置的RS232标准串行接口,为D型九针插座[4]。
在实际中,单片机和PC机之间需要通过MAX232芯片进行电平转换才能连接,但在仿真图中可以直接将两者的RXD(接收数据)和TXD(发送数据)连接起来进行串行通信。
如何实现VC应用程序与PLC的数据交换
如何实现VC应用程序与PLC的数据交换当今,随着工业自动化的广泛应用,越来越多的工业企业开始采用可编程逻辑控制器(PLC)来控制和管理生产过程。
而随着信息技术的不断发展,将计算机技术与工业控制相结合,实现VC应用程序与PLC的数据交换,已经成为很多企业提高生产效率、提升产品质量的一种重要手段。
本文将从硬件和软件两个角度来介绍如何实现VC应用程序与PLC的数据交换。
硬件层面:在实现VC应用程序与PLC的数据交换之前,首先需要确保计算机和PLC之间能够进行可靠的通信。
一般而言,可以通过以下几种方式来实现计算机和PLC之间的连接和通信。
1.串口通信:串口通信是最常见的一种方式,通过串口线将计算机的串口与PLC的COM口相连接。
在VC应用程序中,通过编程方式来读写串口数据,从而实现与PLC的数据交互。
2.以太网通信:在以太网通信方式下,计算机和PLC通过以太网进行连接。
可以使用TCP/IP协议来实现数据的传输。
在VC应用程序中,可以使用套接字编程来实现与PLC的通信。
B通信:有些PLC具备USB接口,可以通过USB线将计算机和PLC进行连接。
在VC应用程序中,可以通过USB编程来与PLC进行数据交互。
软件层面:在硬件连接完成之后,下一步就是通过软件来实现VC应用程序与PLC的数据交换。
以下是一些常用的软件开发工具和编程语言,可以帮助我们实现这个目标。
1.Visual Studio:Visual Studio是一个功能强大的集成开发环境,可以用于开发各种类型的应用程序,包括VC应用程序。
在VC应用程序中,可以通过编写相应的代码来与PLC进行数据交换。
2.C#编程语言:C#是一种简单、现代化的编程语言,广泛应用于Windows平台的应用程序开发。
在VC应用程序中,可以使用C#编写代码来实现与PLC的数据交互。
3.编程库:PLC通常配备有相关的编程库,包括DLL、API等,可以用于编写与PLC通信的代码。
在VC应用程序中,可以引用这些编程库,从而实现与PLC的数据交换。
vc++_串口上位机编程实例 附vc串口通信(接收)
VC++串口上位机简单例程(源码及详细步骤)VC++编写简单串口上位机程序串口通信,MCU跟PC通信经常用到的一种通信方式,做界面、写上位机程序的编程语言、编译环境等不少,VB、C#、LABVIEW等等,我会的语言很少,C语言用得比较多,但是还没有找到如何用C语言来写串口通信上位机程序的资料,在图书管理找到了用VC++编写串口上位机的资料,参考书籍,用自己相当蹩脚的C++写出了一个简单的串口上位机程序,分享一下,体验一下单片机和PC通信的乐趣。
编译环境:VC++6.0操作系统:VMWare虚拟出来的Windows XP程序实现功能:1、PC初始化COM1口,使用n81方式,波特率57600与单片机通信。
PC的COM口编号可以通过如下方式修改:当然也可以通过上位机软件编写,通过按钮来选择COM端口号,但是此次仅仅是简单的例程,就没有弄那么复杂了。
COM1口可用的话,会提示串口初始化完毕。
否则会提示串口已经打开Port already open,表示串口已经打开,被占用了。
2、点击开始转换,串口会向单片机发送0xaa,单片机串口中断接收到0xaa后启动ADC 转换一次,并把转换结果ADCL、ADCH共两个字节的结果发送至PC,PC进行数值转换后在窗口里显示。
(见文章末尾图)3、为防止串口被一只占用,点击关闭串口可以关闭COM1,供其它程序使用,点击后按钮变为打开串口,点击可重新打开COM1。
程序的编写:1、打开VC++6.0建立基于对话框的MFC应用程序Test,2、在项目中插入MSComm控件:工程->增加到工程->Components and Controls->双击Registered ActiveX Controls->选择Microsoft Communications Control, version 6.0->Insert,按默认值添加,你会发现多了个电话图标,这是增加后串口通信控件。
用串口类实现VC与MCS51单片机之间的通信
u lC + + a d RS一23 a n 2.t e a v na e o e a l s sc a fe h d a t g fs r lc a si lri d.An h o g h k n i i d t ru h t e ma i g
p o e so i l ii ls v b e o i o r p r c s f mp e d gt a a l s lg a h,t e p o e so lme t g t e c mmu i ai n s a l h r c s fi e n i h o mp n nc t o
导致 程 序 的 执 行 速 率 相 对 较 慢. 者 曾 经 用 笔
MS o m控 件 和 串 口类 两种 方 法 编 制 简 易 数 字 示 Cm
波器的程序 , 结果前者的数据采集速率明显低于后
作者简介 : 代明军(9 2一) 男, 18 , 硕士 , 研究方向 :iu Ln x嵌入式技术 , 计算机通信 网络及管理
种广泛使用的单片机之间的通信很有意义.
1 串 口通 信 方 式
编制串口通信的程序有很多软件 , Vsa 而 i l u c++由于具有 M C类库的强大支持 , F 以及强大的 可视化编程能力与高效 的代码执行速 率而受到许
vc串口通讯控件MSComm编程详解
vc串口通讯控件MSComm编程详解在mfc中进行串口通讯最简单的方法莫过于在对话框中使用MSCOMM控件了,MSComm通信控件提供了一系列标准通信命令的接口,它允许建立串口连接,可以连接到其他通信设备(如Modem).还可以发送命令、进行数据交换以及监视和响应在通信过程中可能发生的各种错误和事件,从而可以用它创建全双工、事件驱动的、高效实用的通信程序。
一、用MSComm控件通信1.串口通信基础知识一般悦来,计算机都有一个或多个串行端口,它们依次为com1、Com2、…,这些串口还提供了外部设备与pC进行数据传输和皿信的通道。
这些串口在CPU和外设之间充当解释器的角色。
当字符数据从CPU 发送给外设时,这些字符数据将被转换成串行比特流数据;当接收数据时,比特流数据被转换为字符数据传递给CPU,再进一步说,在操作系统方面,Windows用通信驱动程序(COMM.DRV)调用API函数发送和接收数据,当用通信控件或声明调用API函数时,它门由COMM. DRV解释并传递给设备驱动程序,作为一个vB程序员,要编写通信程序.只需知道通信控件提供给Windows通信AP1函数的接口即可.换句话说,只需设定和监视通信控件的属性和事件即可。
2.使用Mscomm控件在开始使用MSComm控件之前。
需要先了解其属性、事件或错误属性描述CommPort 设置或返回通信端口号Settings 以字符串的形式设置或返回波特率、奇偶校验、数据位和停止位PortOpen 设置或返回通信端口的状态。
也可以打开和关闭端口Input 返回和删除接收缓冲区中的字符Output 将字符串写入发送缓冲区CommEvent属性为通信事件或错误返回下列值之一。
在该控件的对象库中也可以找到这些常量。
常量值描述ComEventBreak 1001 收到了断开信号ComEventCTSTO 1002 Clear To Send Timeout。
单片机端采用C51实现_单个单片机与PC串口通信任务
单个单片机与PC串口通信:1)测试通信状态先在文本框中输入字符串“Hello”,单击“测试”按钮,将字符串“Hello”发送到单片机,若PC与单片机通信正常,在PC程序的文本框中显示字符串“OK!”,否则显示字符串“ERROR!”。
2)循环计数单击“开始”按钮,文本框中数字从0开始累加,0、1、2、3…,并将此数发送到单片机的显示器上显示;当累加到10时,回到0重新开始累加,依次循环;任何时候,单击“停止”按钮,PC程序中和单片机显示器都停止累加,再单击“开始”按钮,接着停下的数继续累加。
3)控制指示灯在单片机继电器接线端子的2个通道上分别接上2个指示灯,在PC程序画面上选择指示灯号,如1号灯,单击画面“打开”按钮,单片机上1号灯亮,同时蜂鸣器响;单击画面“关闭”按钮,1号灯灭,蜂鸣器停止响;同样控制2号灯的亮灭(蜂鸣器同时动作)。
#include <reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit a1=P0^0;sbit a2=P0^1;sbit a3=P0^2;sbit a4=P0^3;sbit a5=P0^4;sbit a6=P0^5;sbit a7=P0^6;sbit a8=P0^7;void delay(uint x) //延时{uchar i;while(x--)for(i=0;i<120;i++);}void uart(void) interrupt 4 //把接收到的数据写入ucReceiveData(){TI=0;RI=0;if(SBUF=='h')//接收到'H'字符发送'OK'{SBUF='o';while(TI==0);TI=0;}else if(SBUF=='1') a1=0;else if(SBUF=='2') a1=1;else if(SBUF=='3') a2=0;else if(SBUF=='4') a2=1;else if(SBUF=='5') a3=0;else if(SBUF=='6') a3=1;else if(SBUF=='7') a4=0;else if(SBUF=='8') a4=1;else if(SBUF=='9') a5=0;else if(SBUF=='a') a5=1;else if(SBUF=='b') a6=0;else if(SBUF=='c') a6=1;else if(SBUF=='d') a7=0;else if(SBUF=='e') a7=1;else if(SBUF=='f') a8=0;else if(SBUF=='g') a8=1;}void main(void){uchar b=0xfe;TMOD=0x20; //定时器1--方式2IE=0x12; //中断控制设置,串口、T2开中断PCON=0x80; //电源控制SCON=0x50; //方式1TL1=0xFa;//0xF4; //12MHZ晶振,波特率为4800 0xf3 4800TH1=0xFa;//0xF4; //11.0592MHZ晶振,波特率为4800 0xf4 9600 0xfa 19200 0xfdTR1=1; //启动定时ES=1;EA=1;// P0=0;while(1){P1=0;}}using System;using System.Collections.Generic; using ponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Drawing.Drawing2D;namespace lsd1{public partial class Form1 : Form {int a = 0,b=2,c=0,d=0;int m;int sur = 0;int su = 0, sf = 0;public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){this.skinEngine1.SkinFile = "WaveColor1.ssk";GraphicsPath gp = new GraphicsPath();gp.AddEllipse(pictureBox1.ClientRectangle);Region region = new Region(gp);pictureBox1.Region = region;pictureBox2.Region = region;pictureBox3.Region = region;pictureBox4.Region = region;pictureBox5.Region = region;pictureBox6.Region = region;pictureBox7.Region = region;pictureBox8.Region = region;gp.Dispose();region.Dispose();label5.ForeColor = Color.Red;timer1.Enabled = false;timer2.Enabled = false;}private void button8_Click(object sender, EventArgs e) {if (textBox1.Text != ""){if (serialPort1.IsOpen){pictureBox1.BackColor = Color.DarkSeaGreen; serialPort1.Write("2");pictureBox2.BackColor = Color.RosyBrown; serialPort1.Write("4");pictureBox3.BackColor = Color.DarkSeaGreen; serialPort1.Write("6");pictureBox4.BackColor = Color.RosyBrown; serialPort1.Write("8");pictureBox5.BackColor = Color.DarkSeaGreen; serialPort1.Write("a");pictureBox6.BackColor = Color.RosyBrown; serialPort1.Write("c");pictureBox7.BackColor = Color.DarkSeaGreen; serialPort1.Write("e");pictureBox8.BackColor = Color.RosyBrown; serialPort1.Write("g");sur = 20;serialPort1.Close();button8.Text = "打开串口";textBox1.Enabled = true;}else{sur = 0;serialPort1.PortName = comboBox1.Text;serialPort1.BaudRate =Convert.ToInt32(comboBox2.Text);try{serialPort1.Open();button8.Text = "关闭串口";textBox1.Enabled = false;comboBox2.Enabled = false;comboBox1.Enabled = false;timer1.Interval =Convert.ToInt32(textBox1.Text);timer1.Enabled = true;timer2.Enabled = true;}catch{MessageBox.Show("串口打开失败了!\n\n可能是串口已补占用。
vc串口通信编程详解
vc串口通信编程详解
串口通信简介
串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件。
一般完成这种功能的电路,我们称为串行接口电路。
串口通信结构
串口通信是指外设和计算机间,通过数据信号线、地线、控制线等,按位进行传输数据的一种通讯方式。
这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低。
串口是计算机上一种非常通用的设备通信协议。
大多数计算机(不包括笔记本电脑)包含两个基于RS-232的串口。
串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。
同时,串口通信协议也可以用于获取远程采集设备的数据。
RS-232(ANSI/EIA-232标准)是IBM-PC及其兼容机上的串行连接标准。
可用于许多用途,比如连接鼠标、打印机或者Modem,同时也可以接。
单片机C语言第6章串行口的C51编程3课件
•
SBUF=i;
•
while(TI==0);
•
TI=0;
•}
•}
• //单片机2的C51源程序: • #include<reg51.h> • #define uint unsigned int • #define uchar unsigned char • void main( ) • { uchar i=0; • TMOD=0x20; • TH1=TL1=0xff; • SCON=0x50; • PCON=0x80; • TR1=1; • while(1) • { while(RI==0); • RI=0; • i=SBUF; • P1=i; •} •}
• #define uchar unsigned char
• void main( )
• { uchar i;
• TMOD=0x20;
• TH1=TL1=0xff;
• SCON=0x50;
• PCON=0x80;
• TR1=1;
• P1=0xff;
• while(1)
• { P1=0xff;
•
i=P1;
• while(TI==0);
• TI=0;
• RI=0;
• while(RI==0);
• i=SBUF;
//读取接收数据
• RI=0;
• P1=i;
• i=~i;
• for(j=0;j<12500;j++); //延时
•}
•}
【例6-12】两个单片机串行通信
•
在某控制系统中有甲、乙两个单片机,甲单
• TH1=256–fosc/(波特率×12×32/2SMOD) • =256-2SMOD×13 • 当SMOD=0时:TH1=256–13=243=0F3H。 • 当SMOD=1时:TH1=256–2×13=230=0E6H。
C51串口通讯
#include <C8051F060.h> // SFR declarations#include <stdio.h>//----------------------------------------------------------------------------- // 16-bit SFR Definitions for 'F06x//-----------------------------------------------------------------------------sfr16 RCAP2 = 0xCA; // Timer2 capture/reloadsfr16 TMR2 = 0xCC; // Timer2//----------------------------------------------------------------------------- // Global Constants//-----------------------------------------------------------------------------#define BAUDRATE 4800 // Baud rate of UART in bps#define BAUDRATE1 9600#define SYSTEMCLOCK 3062500//----------------------------------------------------------------------------- // Function Prototypes//-----------------------------------------------------------------------------void OSCILLATOR_Init (void);void PORT_Init (void);void UART0_Init (void);void UART1_Init (void);//----------------------------------------------------------------------------- // Global Variables//-----------------------------------------------------------------------------#define UART0_BUFFERSIZE 8unsigned char UART0_Buffer[UART0_BUFFERSIZE];unsigned char UART0_Buffer_Size = 0;unsigned char UART0_Input_First = 0;unsigned char UART0_Output_First = 0;unsigned char isfirstdata,k,k1;unsigned char UART0_R_Buf[UART0_BUFFERSIZE];unsigned char check1(void);unsigned char check2(void);void SendMesUart0(unsigned char adr);void delay(unsigned long tim){while (tim!=0)tim--;}unsigned char u1bufre[8];unsigned char u1REpnt;unsigned char u1buftr[8];unsigned char u1TRpnt;unsigned char resend;unsigned char resend1;//----------------------------------------------------------------------------- // main() Routine//-----------------------------------------------------------------------------void main (void){SFRPAGE = CONFIG_PAGE;WDTCN = 0xDE; // Disable watchdog timerWDTCN = 0xAD;OSCILLATOR_Init (); // Initialize oscillatorPORT_Init (); // Initialize crossbar and GPIOUART0_Init (); // Initialize UART0UART1_Init ();EA = 1;u1buftr[0]=0x31;u1buftr[1]=0x32;u1buftr[2]=0x33;u1buftr[3]=0x34;u1buftr[4]=0x35;u1buftr[5]=0x36;u1buftr[6]=0x37;u1buftr[7]=check1();SFRPAGE = UART0_PAGE;// SendMesUart0(0x80);while (1){// SFRPAGE = UART0_PAGE;// SendMesUart0(0x01);if (resend==1){SFRPAGE = UART0_PAGE;// SendMesUart0(0x80);resend=0;}if (resend1==1){resend1=0;SFRPAGE = UART1_PAGE;u1TRpnt=0;SBUF1=u1buftr[u1TRpnt];u1TRpnt++;}}}//----------------------------------------------------------------------------- // Initialization Subroutines//-----------------------------------------------------------------------------//----------------------------------------------------------------------------- // OSCILLATOR_Init//----------------------------------------------------------------------------- //// Return Value : None// Parameters : None//// This function initializes the system clock to use an external 22.1184MHz// crystal.////----------------------------------------------------------------------------- void OSCILLATOR_Init (void){char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR pageSFRPAGE = CONFIG_PAGE; // Set SFR page// OSCICN = 0x80; // Set internal oscillator to run// at its slowest frequencySFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE}//----------------------------------------------------------------------------- // PORT_Init//-----------------------------------------------------------------------------//----------------------------------------------------------------------------- void PORT_Init (void){char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR pageSFRPAGE = CONFIG_PAGE; // Set SFR pageSFRPAGE = CONFIG_PAGE;XBR0 = 0x04;XBR2 = 0xC4;P0MDOUT = 0x05;SFRPAGE = SFRPAGE_SAVE; // Restore SFR page}//----------------------------------------------------------------------------- // UART0_Init Variable baud rate, Timer 2, 3//----------------------------------------------------------------------------- void UART0_Init (void){char SFRPAGE_SAVE;SFRPAGE_SAVE = SFRPAGE; // Preserve SFRPAGESFRPAGE = TMR2_PAGE;//TMR2CF = 0x08; //19200//RCAP2L = 0xF6;//RCAP2H = 0xFF;TMR2CN = 0x00; // Timer in 16-bit auto-reload up timer mode TMR2CF = 0x08; // SYSCLK is time base; no output;// up count onlyRCAP2 = - ((long) SYSTEMCLOCK/BAUDRATE/16);TMR2 = RCAP2;TR2= 1; // Start Timer2SFRPAGE = UART0_PAGE;SCON0 = 0xD0;SCON0 &= 0xFC; //将TI0和RI0清零SSTA0 = 0x5; // Clear all flags; DISable baud rate doubler Use Timer2 as RX and TX baud rate source;ES0 = 1;SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE}//----------------------------------------------------------------------------- // Interrupt Service Routines//-----------------------------------------------------------------------------//----------------------------------------------------------------------------- // UART0_Interrupt//----------------------------------------------------------------------------- //// This routine is invoked whenever a character is entered or displayed on the // Hyperterminal.////-----------------------------------------------------------------------------void UART0_Interrupt (void) interrupt 4{SFRPAGE=0x00;if(SCON0&0x01){UART0_R_Buf[k1]=SBUF0;k1++;SCON0&=0xfe;if(k1>=8){k1=0;if (UART0_R_Buf[7]==check2()){//if (UART0_R_Buf[5]=0xff){u1buftr[0]=UART0_R_Buf[0];u1buftr[1]=UART0_R_Buf[1];u1buftr[2]=UART0_R_Buf[2];u1buftr[3]=UART0_R_Buf[3];u1buftr[4]=UART0_R_Buf[4];u1buftr[5]=UART0_R_Buf[5];u1buftr[6]=UART0_R_Buf[6];u1buftr[7]=UART0_R_Buf[7];resend1=1;// return error from io resend}}}}if(SCON0&0x02){if(isfirstdata){SCON0&=0xf7;isfirstdata=0;k1=0;}if(k<8){SBUF0=u1bufre[k];k++;}else{k=0;}SCON0&=0xfd;}}void UART1_Init (void){char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR pageSFRPAGE = UART1_PAGE;SCON1 = 0x10; // SCON1: mode 0, 8-bit UART, enable RXSFRPAGE = TIMER01_PAGE;TMOD &= ~0xF0;TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reloadif (SYSTEMCLOCK/BAUDRATE1/2/256 < 1) {TH1 = -(SYSTEMCLOCK/BAUDRATE1/2);CKCON |= 0x10; // T1M = 1; SCA1:0 = xx} else if (SYSTEMCLOCK/BAUDRATE1/2/256 < 4) {TH1 = -(SYSTEMCLOCK/BAUDRATE1/2/4);CKCON &= ~0x13; // Clear all T1 related bits CKCON |= 0x01; // T1M = 0; SCA1:0 = 01} else if (SYSTEMCLOCK/BAUDRATE1/2/256 < 12) {TH1 = -(SYSTEMCLOCK/BAUDRATE1/2/12);CKCON &= ~0x13; // T1M = 0; SCA1:0 = 00} else {TH1 = -(SYSTEMCLOCK/BAUDRATE1/2/48);CKCON &= ~0x13; // Clear all T1 related bits CKCON |= 0x02; // T1M = 0; SCA1:0 = 10}TL1 = TH1; // init Timer1TR1 = 1; // START Timer1EIE2 = 0x40; // Enable UART1 interrupts SFRPAGE = UART1_PAGE;SFRPAGE = SFRPAGE_SAVE; // Restore SFR page}void UART1_Interrupt (void) interrupt 20{SFRPAGE = UART1_PAGE;if(RI1){ ///if (u1REpnt<8){u1bufre[u1REpnt]=SBUF1;u1REpnt++;RI1=0;}if (u1REpnt>=8){u1REpnt=0;RI1=0;if (u1bufre[7]==check1()){SFRPAGE = UART0_PAGE;k=1;SendMesUart0(u1bufre[0] & 0x0f); //SBUF0=u1bufre[0];}else{u1buftr[0]=u1bufre[0];u1buftr[5]=0xff;u1buftr[6]=0xff;u1buftr[7]=0xff;}}} ///if(TI1){SFRPAGE=1;if (u1TRpnt<8){SBUF1=u1buftr[u1TRpnt];u1TRpnt++;}else{u1TRpnt=0;}TI1=0;}}void SendMesUart0(unsigned char adr){SFRPAGE=0x00;SCON0|=0x08;isfirstdata=1;。
运用VC_实现微机与MCS51单片机的串行通信
收稿日期:2005-12-02作者简介:袁 杰(1957-),男,江苏南通人,南通广播电视大学讲师,主要从事计算机科学与技术研究.文章编号:1671-8127(2006)02-0068-04运用VC++实现微机与MCS51单片机的串行通信袁 杰(南通市广播电视大学,江苏南通226007)摘 要:在工业分布式控制系统中,利用VC ++中的Cse ria,l 是实现微机与M CS51单片机系统之间串行通信的好方法.关键词:VC++;Cserial 类;串行通信;单片机中图分类号:TP311113 文献标识码:A0 引言现代的工业控制现场,常常采用分布式控制系统.分布式控制系统主要由上位机和下位机组成.M CS51单片机具有指令系统丰富、性价比高、抗干扰能力强且便于实时处理,常常用于下位机.而分布式控制系统一般需要对现场数据进行统计、分析、制表、打印、绘图、报警等,因此上位机常采用普通微机作为集中管理的中心机器.由单片机完成数据的采集及对装置的控制,由微机完成各种复杂的数据处理及对单片机的控制.组成以上系统的关键是如何实现微机与MCS51单片机之间的数据通讯.利用VC ++软件便可实现微机与MCS51单片机的串行通讯.1 串行通信实现过程微机计算机与外部设备的通信方式有多种,有并行和串行等交换方式,并行方式主要进行短距离的数据传送,传送速率较快,通常其并行口用作打印机的输出.而长距离的数据传输只能采用串行方式,它只需一对数据线进行数据传送,传送距离较长,投资较少,但传送速率较低.1.1 串行通信原理串行通信的原理是:在数据输入过程中,数据一位一位地从外设进入接口的/接收移位寄存器0,当/接收移位寄存器0中已接收完一个字符的各位后,数据就从/接收移位寄存器0进入/数据输入寄存器0.CPU 从/数据输入寄存器0中读取接收到的字符(并行读取,即D7~D0同时被读至CP U 累加器中)./接收移位寄存器0的移位速度由/接收时钟0确定.在数据输出过程中,CP U 把要输出的字符(并行地)送入/数据输出寄存器0,/数据输出寄存器0的内容传输到/发送移位寄存器0,然后由/发送移位寄存器0移位,把数据一位一位地送到外设./发送移位寄存器0的移位速度由/发送时钟0确定.这样就完成了系统内部数据的并行变串行输出,串行数据变并行输入的转换过程.接口中的/控制寄存器0用来存放CP U 送给该接口的各种控制信息,这些控制信息决定接口的工作方式./状态寄存器0的各位称为/状态位0,每一个状态位都可以用来指示数据传输过程中的状态或某种错误.例如,用状态寄存器的D 5位为/l 0表示/数据输出寄存器空0,用D 0位表示/数据输入寄存器满0,用D 2位表示/奇偶检验错0等.1.2微机的RS232串行接口现在的计算机主板上都带有2~4个串行通信端口,设备号为COM 1-CO M 4.主板上能够完成上述/串-并0转换功能的电路,通常称为/通用异步收发器0(UART :Un i v ersal A synchronous R eceiver and Trans m i-t ter).其通信标准通常采用RS-232标准,RS-232标准接口的每一个引脚都有它的作用,也有它信号流动的方向,其引脚位定义为:RXD:负责将传送过来的远程信息进行接收;TXD:负责将计算机打算送出去的信息传送出去;DSR:表示数据就绪;RTS:表示要求传送;CTS:表示清除传送.2006年第2期第5卷(总第23期) 商丘职业技术学院学报J OURNA L O F S HANGQ I U VOCAT IONAL AND TECHN ICAL COLLEGE V o1.5,N o .2Apr .,20061.3MCS)51的串行口M CS-51系列单片机提供一个全双工的串行口,[1]它有四种工作方式:方式0,串行接口为移位寄存器I/O方式;方式1,串行接口被控制为8位的异步通信接口传送,一帧信息为10位,其中1位为起始位,8位为数据位,1位停止位,波特率可变;方式2和方式3,则被定义为9位的异步通信接口,传送一帧信息为11位,其中1位为起始位,8位为数据位,1位是附加的可程控为0或1的第9位数据,1位停止位.这几种方式的选择由片内的特殊功能寄存器SCON(串行口控制寄存器)的设置完成.2硬件设计系统中采用80C31单片机作为下位机,PC机为上位机,二者通过RS232串行口接收或上传数据.接线如图1.由于RS232信号的电平为:逻辑1(MARK)=-3~-15V;逻辑0(SPACE)=+3~+15V;而单片机串口信号电平为TTL电平:逻辑1为大于3.6V;逻辑0为小于0.3V;为了能使微机与单片机之间实现通信,所以必须进行二者之间的电平转换.可在它们之间加入一电平转换器(见图2).图1RS232连接电缆图图2微机与单片机串口通信接口转换电路图3软件设计3.1通信协议通信协议是指通信双方的一种约定.在PC机与单片机通信中,PC机承担主控任务,负责控制参数的设定,单片机接收PC机指令,并根据指令信息上传数据或控制被控对象.通信协议是:采用RS232串口异步通信模式,1位起始位,8位数据位,1位停止位,无奇偶校验位.波特率为9600b/s.传输数据采用二进制传输模式.以一个数据包为例,其帧头字符/~0,字符值为7E H(十六进制),然后是数据串,帧尾是字符值为2A的/*0字符,则整个数据包为/~XXXX*0.其中/XXXX0就是已经约定好的指令码.每个/X0表示一个十六进制数.根据通信协议,结合VC++的特点,提出了如下的编程方法.3.2微机部分在使用W i n do w s操作系统的微机VC++环境中,串行通信实现的方法有多种:一是调用API(Application Progra m I nterface)函数实现,但这种方法使用起来需要许多底层设置,较为繁琐,难以理解;另一种是使用A ctive X的M SCo mm控件,这种方法虽较为简便,但仍不能满足使用多个串口进行复杂处理的需要.本文采用VC++的C sera il类,它可以支持多线程的处理,功能较强.Cserial是由M u M ega Techno l o g ies公司提供的一个免费的VC++类,可方便地实现串行通信.该类定义的说明为.class CSerial{public:CSeria l();~CSerial();BOOL Open(i n t nPort=2,i n t nB aud=9600);BOOL C lose(void);i n t ReadData(void*,int);i n t SendData(const char*,i n t);i n t ReadData W a iti n g(vo id);BOOL Is Opened(void){return(m_bOpened);}Protected:BOOL W riteCo mm Byte(unsigned char);HANDLE m_hI DCo mDev;OVERLAPPED m_OverlappedR ead,m_Overlapped W rite;BOOL m_bOpened;}Cserial成员函数简介(1)CSeria:l:Cserial是类构造函数,不带参数,负责初始化所有类成员变量.(2)C seria:l:Open成员函数打开通信端口.带两个参数,第一个是串口号,有效值是1到4,第二个参数是波特率,返回一个布尔量.(3)C seria:l:C l o se函数关闭通信端口.类析构函数调用这个函数,所以可不用显式调用这个函数.(4)C seria:l:SendData函数把数据从一个缓冲区写到串行端口.它所带的第一个参数是缓冲区指针,其中包含要被发送的资料;这个函数返回已写到端口的实际字节数.(5)C seria:l:ReadDa ta W a iti n g函数返回等待在通信端口缓冲区中的数据,不带参数.(6)CSeria:l:ReadData函数从端口接收缓冲区读入数据.第一个参数是vo i d*缓冲区指针,资料将被放入该缓冲区;第二个参数是个整数值,给出缓冲区的大小.具体程序代码如下vo id Cco mmD l g::OnSend(){CSeria l Seria;l//构造串口类,初始化串行口if(Seria.l Open(2,9600))//打开串行口2,波特率为9600bps{static char sz M essage[]=/00;//命令码(可定义各种命令码)i n t nBytesSen;ti n t count=0;resend:nBytesSen t=Seria.l SendData(sz M essage,strlen(sz M essage));//发送命令码char r d M essage[20];if(Seria.l ReadData W a iting()){Seria.l ReadData(r d M essage,88);//r d M essage定义接收字节存储区,为全局变量//if((rd M essage[0]!=0x7f)&&(count<3)){count++;go to resend}if(count>=3)M essageBox(/发送命令字失败0);}elseM essageBox(/接收数据错误0);}else M essageBox(/串行口打开失败0);}4.3单片机部分单片机的波特率设置与微机一致,定时器T1作为波特率发生器,设置为工作方式2,串口设置为工作方式1,数据的传送格式为10位(异步模式),采用中断方式发送、接收数据.[2]具体程序如下:ORG0000HLJ M PMA I NORG0023HLJ M P SRI N T;串行口中断入口MA I N:MOV SP,#60HMOV T MOD,#20H;设T1为方式2,作波特率发生器MOV TH1,#0FDH;波特率=9600MOV TL1,#0FDHMOV SCON,#50H;串口方式1,RE N=1MOV PCON,#80HSETB TR1;启动定时器T1CLR T1;禁止T1中断SETB EA;开中断SETB ES;允许串口中断,,;主程序其它处理SRI NT:CLR E A;关中断CLR R IPUS H DP HPUS H DPLPUS H ACCRECE I V E:MOV A,SB UF;接收数据,,;接收数据处理SEND:MOV SB UF,A;发送数据WA I T:J NB T I,WA I T;未发送完,等待CLR T I(下转91页)嵌补.楼板出现裂缝的面积较大时,应对楼板进行静载试验,检验其结构安全性,必要时可在楼板上增做一层钢筋网片,以提高板的整体性.通长、贯通的危险结构裂缝,裂缝宽度大于30mm的,采用结构胶粘扁钢加固补强.板缝用灌缝胶高压灌胶.参考文献:[1]建筑工业出版社.现行建筑施工规范大全[M].北京:中国建筑工业出版社,2002.[2]杭有声.建筑施工技术[M].北京:高等教育出版社,2000.[责任编辑冯喜忠]Concrete Slab C racks of H igh-R isesCHEN M i ng-j un(Shangqi u Vocationa l and Tec hn ic a l Collag e,Shangqi u476000,Ch i na)Abstract:W ith t h e rap i d devel op m en t of real estate,t here are more and m ore h i gh-ri ses.H o w erer,concrete s l ab cracks pou ri ng h i gh-ri ses con-stru cti on,has been a m aj or t h reat t o t he qualit y,and a ma i n ob staclew h i ch i s hard t o overco m e.W ith an abundance of experi en ce and m any les son s learn-ed fro m constru cti on practice,t h e author has cl arified how to preven t t he cracks i n reinforced con crete s l abs i n ter m s of desi gn,constructi on and m aterial s.K ey w ords:cracks;f eatures;reas on s;m et hods(上接71页)POP ACC;恢复现场POP DPLPOP DP HSETB EA;开中断RETI4结束语在工业分布式控制系统中,微机与单片机通信的这一方法在实际运行中,运行可靠、稳定,效果良好,解决了上位机与下位机之间通信的问题.参考文献:[1]李华.M CS-51系列单片机实用接口技术[M].北京:北京航空航天大学出版社,1999.[2]翁桂荣,等.单片微型计算机接口技术[M].苏州:苏州大学出版社,2002.[责任编辑冯喜忠]A M et hod of Ser i a lP ort Co mm unication be t w een M icrocom puterandMCS-51Single-chip C o m puter t y U sing VC++YU AN Jie(Nan t ong R ad io&TV Universit y,N an tong226006,Ch ina)Abstract:In the paper,w e i ntroduced am et h od of seri al port co mmun icati on bet w een m i croco mpu ter and M CS-51s i ngle-ch ip co m puter i n Indus-trys'd i stri bu ted con trol syste mK ey w ords:VC++;C serial class;seri al co mm un i cati on;si ng l e-ch i p co m puter。
C51单片机和电脑串口通信电路图
C51单片机和电脑串口通信电路图与源码51单片机有一个全双工的串行通讯口,所以单片机和电脑之间可以方便地进行串口通讯。
进行串行通讯时要满足一定的条件,比如电脑的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,我们采用了专用芯片MAX232进行转换,虽然也可以用几个三极管进行模拟转换,但是还是用专用芯片更简单可靠。
我们采用了三线制连接串口,也就是说和电脑的9针串口只连接其中的3根线:第5脚的GND、第2脚的RXD、第3脚的TXD。
这是最简单的连接方法,但是对我们来说已经足够使用了,电路如下图所示,MAX232的第10脚和单片机的11脚连接,第9脚和单片机的10脚连接,第15脚和单片机的20脚连接.串口通讯的硬件电路如上图所示在制作电路前我们先来看看要用的MAX232,这里我们不去具体讨论它,只要知道它是TTL和RS232电平相互转换的芯片和基本的引脚接线功能就行了。
通常我会用两个小功率晶体管加少量的电路去替换MAX232,可以省一点,效果也不错,下图就是MAX232的基本接线图。
按图7-3加上MAX232就可以了。
这大热天的拿烙铁焊焊,还真的是热气迫人来呀:P串口座用DB9的母头,这样就可以用买来的PC串口延长线进行和电脑相连接,也可以直接接到电脑com口上。
为了能够在电脑端看到单片机发出的数据,我们必须借助一个WINDOWS软件进行观察,这里我们利用一个免费的电脑串口调试软件。
本串口软件在本网站可以找到软件界面如上图,我们先要设置一下串口通讯的参数,将波特率调整为4800,勾选十六进制显示。
串口选择为COM1,当然将网站提供的51单片机实验板的串口也要和电脑的COM1连接,将烧写有以下程序的单片机插入单片机实验板的万能插座中,并接通51单片机实验板的电源。
#include <reg51。
h〉#define BUFFERLEGTH 10//-—---———-—-——————--——-----—--——--——------—-—--—-—--—--——-———-—--—void UART_init();//串口初始化函数void COM_send(void);//串口发送函数char str[20];char j;//——-----————---——-—--—--—-—-—-———-———-—-——-—--—-—-——————--———-—--———void main(void){unsigned char i;UART_init();j=0; //初始化串口for(i = 0;i < 10 ;i++){COM_send(); //首先发送一次数据作为测试用};while(1);}//-——-——-——---------———-——-—-—-——--—---—---—--—-—--——---—---—--//——-——--——--—-—-—--———————---—-——-——-———-—-----——--—---——————-—-—-—-—————-—--—-—---—--———-——---——-- // 函数名称:UART_init()串口初始化函数// 函数功能: 在系统时钟为11.059MHZ时,设定串口波特率为9600bit/s// 串口接收中断允许,发送中断禁止//—-——--—-----———---—-——-—-——————-————-—-————---——-———————--———-———----—-—--—---——-—---—-————-———---void UART_init(){//初始化串行口和波特率发生器SCON =0x50; //选择串口工作方式1,打开接收允许TMOD =0x20; //定时器1工作在方式2,定时器0工作在方式1TH1 =0xfA; //实现波特率9600(系统时钟11。
89C51单片机的串口通信编程1
89C51单片机的串口通信编程1一、pc机上的串口通信编程过程如下:1.建立项目打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest(与我源代码一致,等会你会方便一点);2.在项目中插入MSComm控件选择Project菜单下Add To Project子菜单中的Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX 控件出现在列表框中。
选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。
(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX一项选上,重新安装VC6,选上ActiveX 就可以了),这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。
3.利用ClassWizard定义CMSComm类控制对象打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1添加控制变量:m_ctrlComm,这时你可以看一看,在对话框头文件中自动加入了//{{AFX_INCLUDES() #include "mscomm.h" //}}AFX_INCLUDES (这时运行程序,如果有错,那就再从头开始)。
4.在对话框中添加控件向主对话框中添加两个编辑框,一个用于接收显示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为IDC_BUTTON_MANUALSEND。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
跟着步骤学习1.建立项目:打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest2.在项目中插入MSComm控件选择Project菜单下Add To Project子菜单中的 Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX控件出现在列表框中。
选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。
(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX一项选上,重新安装VC6,选上ActiveX就可以了),这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw 文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。
3.利用ClassWizard定义CMSComm类控制对象打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1添加控制变量:m_ctrlComm,这时你可以看一看,在对话框头文件中自动加入了//{{AFX_INCLUDES() #include "mscomm.h" //}}AFX_INCLUDES(这时运行程序,如果有错,那就再从头开始)。
4.在对话框中添加控件向主对话框中添加两个编辑框,一个用于接收显示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为IDC_BUTTON_MANUALSEND。
别忘记了将接收编辑框的Properties->Styles中把Miltiline和Vertical Scroll属性选上,发送编辑框若你想输入多行文字,也可选上Miltiline。
再打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_EDIT_RXDATA 添加CString变量m_strRXData,为IDC_EDIT_TXDATA添加CString变量m_strTXData。
说明:m_strRXData和m_strTXData分别用来放入接收和发送的字符数据。
5.添加串口事件消息处理函数OnComm()打开ClassWizard->Message Maps,选择类CSCommTestDlg,选择IDC_MSCOMM1,双击消息OnComm,将弹出的对话框中将函数名改为OnComm,(好记而已)OK。
这个函数是用来处理串口消息事件的,如每当串口接收到数据,就会产生一个串口接收数据缓冲区中有字符的消息事件,我们刚才添加的函数就会执行,我们在OnComm()函数加入相应的处理代码就能实现自已想要的功能了。
请你在函数中加入如下代码:void CSCommTestDlg::OnComm(){// TODO: Add your control notification handler code hereVARIANT variant_inp;COleSafeArray safearray_inp;LONG len,k;BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.CString strtemp;if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符{ ////////以下你可以根据自己的通信协议加入处理代码variant_inp=m_ctrlComm.GetInput(); //读缓冲区safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量len=safearray_inp.GetOneDimSize(); //得到有效数据长度for(k=0;k<len;k++)safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组for(k=0;k<len;k++) //将数组转换为Cstring型变量{BYTE bt=*(char*)(rxdata+k); //字符型strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放m_strRXData+=strtemp; //加入接收编辑框对应字符串}}UpdateData(FALSE); //更新编辑框内容}到目前为止还不能在接收编辑框中看到数据,因为我们还没有打开串口,但运行程序不应该有任何错误,不然,你肯定哪儿没看仔细,因为我是打开VC6对照着做一步写一行的,运行试试。
没错吧?那么做下一步:6.打开串口和设置串口参数你可以在你需要的时候打开串口,例如在程序中做一个开始按钮,在该按钮的处理函数中打开串口。
现在我们在主对话框的CSCommTestDlg::OnInitDialog()打开串口,加入如下代码:// TODO: Add extra initialization hereif(m_ctrlComm.GetPortOpen())m_ctrlComm.SetPortOpen(FALSE);m_ctrlComm.SetCommPort(1); //选择com1if( !m_ctrlComm.GetPortOpen())m_ctrlComm.SetPortOpen(TRUE);//打开串口elseAfxMessageBox("cannot open serial port");m_ctrlComm.SetSettings("9600,n,8,1"); //波特率9600,无校验,8个数据位,1个停止位m_ctrlComm.SetInputMode(1); //1:表示以二进制方式检取数据m_ctrlComm.SetRThreshold(1);//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据现在你可以试试程序了,将串口线接好后(不会接?去看看我写的串口接线基本方法),打开串口调试助手,并将串口设在com2,选上自动发送,也可以等会手动发送。
再执行你编写的程序,接收框里应该有数据显示了。
7.发送数据先为发送按钮添加一个单击消息即BN_CLICKED处理函数,打开ClassWizard->Message Maps,选择类CSCommTestDlg,选择IDC_BUTTON_MANUALSEND,双击BN_CLICKED添加OnButtonManualsend()函数,并在函数中添加如下代码:void CSCommTestDlg::OnButtonManualsend(){// TODO: Add your control notification handler code hereUpdateData(TRUE); //读取编辑框内容m_ctrlComm.SetOutput(COleVariant(m_strTXData));//发送数据}运行程序,在发送编辑框中随意输入点什么,单击发送按钮,啊!看看,在另一端的串口调试助手(或别的调试工具)接收框里出现了什么。
如果你真是初次涉猎串口编程,又一次成功,那该说声谢谢我了,因为我第一次做串口程序时可费劲了,那时网上的资料也不好找。
开开玩笑,谢谢你的支持,有什么好东西别忘了给我寄一份。
最后说明一下,由于用到VC控件,在没有安装VC的计算机上运行时要从VC中把mscomm32.ocx、msvcrt.dll、mfc42.dll拷到Windows目录下的System子目录中(win2000为System32)并再进行注册设置,请参考如何手工注册MSComm控件。
什么是VARIANT数据类型?如何使用VARIANT数据类型?怎么以十六进制或二进制发送和接收?如果还想再深入了解,请看:8.发送十六进制字符在主对话框中加入一个复选接钮,ID为IDC_CHECK_HEXSEND Caption: 十六进制发送,再利用ClassWizard为其添加控制变量:m_ctrlHexSend;在ClassView中为SCommTestDlg类添加以下两个PUBLIC成员函数,并输入相应代码;//由于这个转换函数的格式限制,在发送框中的十六制字符应该每两个字符之间插入一个空隔//如:A1 23 45 0B 00 29//CByteArray是一个动态字节数组,可参看MSDN帮助int CSCommTestDlg::String2Hex(CString str, CByteArray &senddata){int hexdata,lowhexdata;int hexdatalen=0;int len=str.GetLength();senddata.SetSize(len/2);for(int i=0;i<len;){char lstr,hstr=str[i];if(hstr==' '){i++;continue;}i++;if(i>=len)break;lstr=str[i];hexdata=ConvertHexChar(hstr);lowhexdata=ConvertHexChar(lstr);if((hexdata==16)||(lowhexdata==16))break;elsehexdata=hexdata*16+lowhexdata;i++;senddata[hexdatalen]=(char)hexdata;hexdatalen++;}senddata.SetSize(hexdatalen);return hexdatalen;}//这是一个将字符转换为相应的十六进制值的函数//好多C语言书上都可以找到//功能:若是在0-F之间的字符,则转换为相应的十六进制字符,否则返回-1char CSCommTestDlg::ConvertHexChar(char ch){if((ch>='0')&&(ch<='9'))return ch-0x30;else if((ch>='A')&&(ch<='F'))return ch-'A'+10;else if((ch>='a')&&(ch<='f'))return ch-'a'+10;else return (-1);}再将CSCommTestDlg::OnButtonManualsend()修改成以下形式:void CSCommTestDlg::OnButtonManualsend(){// TODO: Add your control notification handler code hereUpdateData(TRUE); //读取编辑框内容if(m_ctrlHexSend.GetCheck()){CByteArray hexdata;int len=String2Hex(m_strTXData,hexdata); //此处返回的len可以用于计算发送了多少个十六进制数m_ctrlComm.SetOutput(COleVariant(hexdata)); //发送十六进制数据}elsem_ctrlComm.SetOutput(COleVariant(m_strTXData));//发送ASCII字符数据}现在,你先将串口线接好并打开串口调试助手V2.1,选上以十六制显示,设置好相应串口,然后运行我们这个程序,在发送框中输入00 01 02 03 A1 CC等十六进制字符,并选上以十六进制发送,单击手动发送,在串口调试助手的接收框中应该可以看到00 01 02 03 A1 CC了。