武汉理工大学基于C语言的上下位机通信设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
任务书
学生姓名:专业班级:信息工程1004班指导教师:郑林工作单位:信息工程学院题目: 基于C语言的上下位机通信设计
初始条件:
1.计算机及WINDOWS 7操作系统
2.VC++6.、Keil uVision4、STC_ISP等软件
3.开发语言:C++ /C语言
4.HL—1型综合单片机开发板、DS18B20温度传感器
要求完成的主要任务:
设计一个基于C语言的上下位机通信设计。
功能如下:
(1)上位PC机与下位单片机模块通信
(2)上位机能通过下位机控制板块上的指示灯;
(3)下位机可把温度等信息传给上位机
要求:
1. 按《武汉理工大学课程设计工作规范》要求撰写课程设计说明书
2. 根据设计任务,能够讲解及显示自己的设计
3. 最终完成内容包括设计说明书和交程序备份
时间安排:
2013年6月 11号—— 12号选题及调研
2013年6月 13号—— 19号软件设计及编程调试
2013年6月 20号—— 21号撰写设计说明书
2013年6月22号答辩
指导教师签名:年月日系主任(或责任教师)签名:年月日
目录
摘要 (1)
1 设计任务 (3)
2方案选择 (4)
2.1硬件方案选择 (4)
2.2软件方案选择 (4)
2.2.1 上位机编程方案选择 (4)
2.2.2 单片机编程方案选择 (5)
2.3 总体方案选择 (5)
3 详细设计 (6)
3.1 单片机部分 (6)
3.1.1下位机硬件设计 (6)
3.1.2下位机程序设计 (8)
3.2 PC机部分 (9)
4 调试与运行 (13)
5 总结 (14)
参考文献 (15)
附录
摘要
随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便也是不可否定的,要为现代人工作、科研、生活、提供更好的更方便的设施就需要从单片机技术入手,一切向着数字化控制,智能化控制方向发展。
现代化集中管理需要对现场数据进行统计、分析、制表、打印、绘图、报警等,同时,又要求对现场装置进行实时控制,完成各种规定操作,达到集中管理的目的。
加之单片机的计算能力有限,难以进行复杂的数据处理。
因此在功能比较复杂的控制系统中,通常以PC机为上位机,单片机为下位机,由单片机完成数据的采集及对装置的控制,而由上位机完成各种复杂的数据处理及对单片机的控制。
本文主要描述了利用PC机与STC89C52单片机之间的通信程序设计实现温度显示。
并详述了在VC6.0环境下,上位机利用串口调试程序与单片机之间串口通信实现温度显示。
由单片机采集一个温度信号,将采集到的温度信号传送给PC机显示,PC机用VC6.0编写程序,单片机程序用C语言编写。
通常PC机和单片机之间的通信是通过串行总线RS-232实现的。
因此采用一种以MAX232为核心的通信接口电路。
该接口电路适用于由一台PC机与多个STC89C52单片机串行通信的设计,其原理和方法同样适用于PC机与其它单片机之间的串行数据通信。
关键词:单片机串口通信VC6.0 STC89C52温度显示DS18B20
1.设计任务
在当今的工业控制系统中,各种数据的采集和执行机构的控制都是由下位机或探测站来完成。
由于单片机具有体积小、价格低廉、可应用于恶劣工业环境的特点,在分布式控制系统中大多采用单片机作为下位机来进行数据采集和现场控制。
在这些应用中,单片机只是直接面向被控对象底层。
而对采集到的数据进行进一步分析和处理的工作是由功能强大的主控PC机来完成的。
因此,PC机和单片机之间就有着大量的数据交换。
51单片机与PC机之间的通信协议
在许多场合的测控系统中,约定PC机和8051单片机的通信协议为:
Number+Command+Length+Data+Check
Number:下位机的机号,若设计中有3台下位机,即Number 取01H,02H,03H,分别代表:#1,#2,#3号下位机;
Command:本次命令的代码;Length:本次发送数据段的字节数;
Data:要发送的数据段;
Check:1字节的校验码。
本设计只考虑一个8051单片机,故可对上述通信协议进行简化。
具体任务要求:基于C语言的上下位机通信设计
主要功能:
(1)上位PC机与下位单片机模块通信
(2)上位机能通过下位机控制板块上的指示灯;
(3)下位机可把温度等信息传给上位机
系统环境:
Windows xp / windows 7
软件:
VC++6.0、Keil uVision4、STC官方烧录工具(STC-ISP)
2方案选择
2.1硬件方案选择
本设计采用的是STC89C52单片机,STC89C52是一种带8K字节闪存可编程可擦除只读存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压、高性能CMOS 8位微处理器,俗称单片机。
STC89C52使用经典的MCS-51内核,它是一种高效微控制器,因为它更经济实惠,用起来灵活方便,而且习惯了用这种型号的单片机,所以选择STC89C52单片机。
本设计采用MAX232芯片进行电平转换,MAX232芯片是美信公司专门为电脑的RS-232标准串口设计的接口电路,使用+5V单电源供电,它的作用就是完成TTL电平与RS-232电平的转换。
PC机的串行口采用的是标准的RS-232接口,单片机的串行口电平是FTL电平,而TTL电平特性与RS-232的电气特性不匹配,因此为了使单片机的串行口能与RS-232接口通信,必须将串行口的输入/输出电平进行转换。
通常用MAX232芯片来完成电平转换。
MCS-51单片机有一个全双工的串行通讯口UART。
利用其RXD和TXD与外界进行通信,其内部有2个物理上完全独立的接收、发送缓冲器SBUF,可同时发送和接收数据。
所以单片机和PC机之间可以方便地进行串口通讯。
单片机串口有3条引线:TXD(发送数据)、RXD(接收数据)和GND(信号地)。
因此在通信距离较短时可采用零MODEM方式,简单三连线结构。
IBM—PC机有两个标准的RS-232串行口,其电平采用的是EIA电平,而MCS-51单片机的串行通信是由TXD(发送数据)和RXD(接收数据)来进行全双工通信的,它们的电平是TTL 电平;为了PC机与MCS-51机之间能可靠地进行串行通信,需要用电平转换芯片,我们采用了MAXIM公司生产的专用芯片MAX232进行转换。
2.2软件方案选择
2.2.1 上位机编程方案选择
本设计采用VC6.0++来实现编程,上位机与单片机进行通信的程序编写可用VB、VC等软件。
由于VB作为面向对象的编程工具不够完全,效率比VC低,提供的命令语言环境较弱,通过串口设备一次最多只能交换16B的数据,对较大数据量的传输存在很大的局限性,很难实现较为复杂的数据处理,VC6.0++是一种功能强大的面向对象的Windows编程开发平台。
VC6.0的优点是界面简洁,
占用资源少,操作方便。
所以本设计采用VC作为串口编程工具。
2.2.2 单片机编程方案选择
本设计单片机的编程选择C语言编写,因为它简洁紧凑、灵活方便、运算符丰富、数据结构丰富、C是结构式语言、C语法限制不太严格,程序设计自由度大、C语言允许直接访问物理地址,可以直接对硬件进行操作、C语言程序生成代码质量高,程序执行效率高,一般只比汇编程序生成的目标代码效率低10へ20%、C语言适用范围大,可移植性好C语言有一个突出的优点就是适合于多种操作系统, 如DOS、UNIX,也适用于多种机型。
C语言具有绘图能力强,可移植性,并具备很强的数据处理能力,因此适于编写系统软件,三维,二维图形和动画它是数值计算的高级语言。
所以我选用C语言来编写此程序。
2.3 总体方案选择
温度传感器测量出来的温度值由单片机采集出来,然后单片机再将采集出的温度数据处理后,通过串行口发送给上位机。
图2.3—1总体设计方案流程图
自习观察上图可发现,该框图中起着重要作用的是RS-232C通信接口电路。
它是上位机和下位机之间信息传递的枢纽,一切数据的传输必需由它完成,上位机直接利用它的RS-232串行口,为此,采用了RS-232串行通信来接收或上传数据和指令。
但RS-232信号的电平和单片机串口信号的电平不一致,必须进行二者之间的电平转换。
在此电路中,采用MAX232实现TTL逻辑电平和RS-232电平之间的相互转换。
MAX232由单一的+5V电源供电,只需配接5个高精度10μF/50V的钽电容即可完成电平转换。
因此,避免了用1488和1489时必需两路电源的麻烦。
转换后的串行信号TXD、RXD直接与PC机的串行口连接。
如此设计,既可发挥出PC机强大的计算和显示功能,又可以体现出单片机灵活的控制功能,有利于对现场信号的实时采集、处理和监控。
3 详细设计
通过综合分析,本系统至少应具备如下功能:
(1)PC机与单片机51单片机都可发送和接收数据,进行可以异步串行通信;(2)PC机键盘输入发送给单片机51单片机,单片机接收PC机发来的数据并送LED显示;
(3)单片机51单片机每次采集的温度数据送给单片机的LED显示,单片机发送的数据即实时温度信号的二进制码组,发送时作为一个队列发送,PC机接收单片机发送来的数据并送窗口显示;
(4)上位机程序即PC端程序采用VC++6.0制作,人机界面友好,界面简洁,功能完善,下位机程序即单片机端采用C语言进行开发。
综上所述,本次设计主要分为两个部分:单片机部分和PC机部分,单片亦称为下位机,PC机为上位机。
二者之间的通信通过RS-232接口电路连接串口来实现。
其中,单片机部分主要完成:温度的采集与显示、接收上位机所发来的相应信号并同步点亮相应指示灯、通过串口将温度信息传给上位机。
上位机(PC)则主要完成向下位单片机发送指令,并实时显示单片机说传送过来的温度信息,并显示在相应的界面显示区内,还要承担串口的选择,及传送信号数制的选择。
3.1 单片机部分
单片机即下位机,其主要完成的工作为:
温度的采集与转换;
温度的数码显示;
响应响应上位机给出的中断;
将温度信息传送给上位机等。
3.1.1下位机硬件设计
下位机主要完成的是温度的采集、处理与显示,同时负责显示采集自上位机的亮灯信号。
其核心部件为STC89C52单片机,它是整个下位机的核心控制、运算器件。
承担着处理温度传感器DS18B20所采集来得温度数据,传送到七段数码管予以显示,同时又要处理来自于上位机的相关命令信号。
但此次设计是以上下位机的通信为重点,且单片机的相关特性也已熟悉,故在此不再冗述。
关于温度传感器DS18B20在这里做一下简单的介绍:温度采集模块主要有
DS18B20温度传感器构成,DS18B20的数字温度计提供9至12位(可编程设备温度读数)。
信息被发送到/从DS18B20 通过1线接口,所以中央微处理器与DS18B20只有一个一条口线连接。
为读写以及温度转换可以从数据线本身获得能量,不需要外接电源。
同时DS18B20因为自身带有存储和AD转换功能,故不需任何外接辅助芯片即可完成温度的采集与AD转换。
DS18B20的相关技术参数为:
温度传感器DS18B20
温度灵敏度:0.0625
测温范围:-55℃~+125℃
测温误差:±0.5℃
工作电压:3~5V/DC
特点:测量结果以9~12位数字量方式串行传送,不需要任何外文扩展器件。
图3.1.1-1 DS18B2内部结构图
图3.1.1—2 DS18B20实物图
3.1.2下位机程序设计下位机流程图
温度采集与处理
温度显示
串行口初始化
串行口通信
3.2 PC机部分
上位机程序即PC端程序采用VC++6.0制作,人机界面友好,界面简洁,功
能完善,下位机程序即单片机端采用C语言进行开发。
最终界面图如下所示:
图3.2—1PC端用户界面
上位机程序流程图
串口打开/发送按钮:
此该部分的功能为,打开串口使得PC端开始接收来自于下位单片机的温度信息等,也可以通过此按钮像下文单片机发送相应的数据信息,以控制单片机上相应的指示灯点亮。
串口消息处理:
当串口打开,并且接收到来自于串口的下位单片机信息时,会产生一个缓冲区字符事件信息,在通过对其的相应处理,并且将相应的结果一十进制形式输出到接收区文本编辑框内,以实现上下位机的同步显示。
通信波特率选择菜单:
通过此选择菜单可以选择相应的通信波特率,已达到下位机的传输波特率与上位机的接收波特率相匹配,从而完成通信。
串口选择菜单:
此菜单可选择相应的通信串口。
暂停/继续按钮:
可实现上位机数据接收文本框区数据更新的暂停与继续。
4 调试与运行
经过上下位机的联机调试,最终调试结果如下图所示:
图4—1人机界面运行图
经过测试可知,该程序能完成基本的功能,即:
(1)PC机与单片机51单片机都可发送和接收数据,进行可以异步串行通信;(2)PC机键盘输入发送给单片机51单片机,单片机接收PC机发来的数据并送LED显示;
(3)单片机51单片机每次采集的温度数据送给单片机的LED显示,单片机发送的数据即实时温度信号的二进制码组,发送时作为一个队列发送,PC机接收单片机发送来的数据并送窗口显示;
(4)上位机程序即PC端程序采用VC++6.0制作,人机界面友好,界面简洁,功能完善,下位机程序即单片机端采用C语言进行开发。
故此次设计基本完成,但也有诸多不足之处,比如:当暂停按钮按下时,接收区的数据接收并未停止而只是暂时停止了显示,当按下继续时所有之前存储的数据就会全部跳显出来。
5 总结
上位机与下位机通讯是一个应用性广,适用性强的基础设计,可以应用在变频器上。
要真正做好一个具有良好人机界面及交互性,使上位机和下位机能正常高效的通讯,需要设计人员具有很强的VC和单片机编程的驾驭能力。
同时,需要相当程度的设计经验,这样才能对设计中出现的问题采取行之有效的解方案。
本文主要详述了STC89C52单片机与PC机的串行通信的实现的设计和内容,STC89C52是一种带8K字节闪烁可编程可擦除只读寄存器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压,高性能CMOS 8位微处理器。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合
在单个芯片中,ATMEL的STC89C52是一种高效微控制器,所以它的使用前景会是相当广泛与受欢迎。
因此我们有必要来学习它与PC机的通信。
主要论述内容总结如下:
1. 介绍了单片机的在现实生活中的使用情况与应用环境领域,市场前景与
未来应用,并对总体设计做了概括性的描述。
2. 详述了单片机的发展概况、特点、应用,各个部件的原理,串行口的通
信方式,显示管的工作原理,使各个部件都能被读者所了解,从而方便人们来认识STC89C52与PC机串行通信的原理。
3. 介绍了软件设计,流程,通信协议,初始化,波特率计算等软件上的准
备与设计,从而为整个设计的汇编阶段做好准备。
最后采用运用汇编语言将整个图纸上的设计变为实际的应用。
当然本设计也存在着很大的问题,比如说功能上相对简单容易出错等,这些问题可以在以后的工作中继续完善。
经过这几天和同组同学的课程设计,因为时间和任务的性质的关系,没有完全按照上述的测试方法进行测试,但经过一些简单的步骤的测试,证明本设计的串行通信的稳定性与实用性。
在设计的过程中我体会到了过程的快乐和结果的喜悦。
人们常常说不要看重结果,主要是过程,这几个月的过程也让我深深的体会到了自己知识的匮乏和掌握的不牢固为此在将来势必要不断地继续学习与深造,为此不断地完善自我。
参考文献
[1] 吴友宇·模拟电子技术基础·北京:清华大学出版社,2009
[2] 谭浩强·C程序设计(第四版)·北京:清华大学出版社,2010
[3] 张天凡·51单片机C语言开发详解·北京:电子工业出版社,2008
[4] 康华光,电子技术基础数字部分·北京:高等教育出版社,2008
[5] 田希晖,薛亮儒·C51单片机技术教程·北京:人民邮电出版社,2007
[6] 陶红艳,余成波·传感器与现代检测技术·北京:清华大学出版社,2009
[7] 李希文·传感器与信号调制技术·西安:西安电子科技大学,2008
[8] 吴戈,李玉峰·案例学单片机C语言开发·北京:人民邮电出版社,2008
附录一:下位机程序
#include <reg52.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
uchar buf;
sbit ds=P2^2; //温度传感器信号线
sbit dula=P2^6; //数码管段选线
sbit wela=P2^7; //数码管位选线
uint temp;
float f_temp;
unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0xbf,0x86,
0xdb,0xcf,0xe6,0xed,
0xfd,0x87,0xff,0xef}; //不带小数点的编码
void delay(uint z)//延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void dsreset(void) //18B20复位,初始化函数
{
uint i;
ds=0;
i=103;
while(i>0)i--;
ds=1;
i=4;
while(i>0)i--;
}
bit tempreadbit(void) //读1位函数
{
uint i;
bit dat;
ds=0;i++; //i++ 起延时作用
ds=1;i++;i++;
dat=ds;
i=8;while(i>0)i--;
return (dat);
}
uchar tempread(void) //读1个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tempreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DA T里}
return(dat);
}
void tempwritebyte(uchar dat) //向18B20写一个字节数据
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //写1
{
ds=0;
i++;i++;
ds=1;
i=8;while(i>0)i--;
}
else
{
ds=0; //写0
i=8;while(i>0)i--;
ds=1;
i++;i++;
}
}
}
void tempchange(void) //DS18B20 开始获取温度并转换
{
dsreset();
delay(1);
tempwritebyte(0xcc); // 写跳过读ROM指令
tempwritebyte(0x44); // 写温度转换指令
}
uint get_temp() //读取寄存器中存储的温度数据
{
uchar a,b;
dsreset();
delay(1);
tempwritebyte(0xcc);
tempwritebyte(0xbe);
a=tempread(); //读低8位
b=tempread(); //读高8位
temp=b;
temp<<=8; //两个字节组合为1个字
temp=temp|a;
f_temp=temp*0.0625; //温度在寄存器中为12位分辨率位0.0625°
temp=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5是四舍五入f_temp=f_temp+0.05;
return temp; //temp是整型
}
////////////////////显示程序//////////////////////////
void display(uchar num,uchar dat)
{
uchar i;
dula=0;
P0=table[dat];
dula=1;
dula=0;
wela=0;
i=0XFF;
i=i&(~((0X01)<<(num)));
P0=i;
wela=1;
wela=0;
delay(1);
}
void dis_temp(uint t)
{
uchar i;
i=t/100;
display(0,i);
i=t%100/10;
display(1,i+10);
i=t%100%10;
display(2,i);
}
void init_com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
EA=1;
ES = 1; //允许串口中断
}
void comm(char *parr)
{
do
{
SBUF = *parr++; //发送数据
while(!TI);//等待发送完成标志为1 TI =0; //标志清零
}while(*parr); //保持循环直到字符为'\0'
}
void main()
{
uchar buff[4],i;
dula=0;
wela=0;
init_com();
while(1)
{
tempchange();
for(i=10;i>0;i--)
{
dis_temp(get_temp());}
sprintf(buff,"%f",f_temp);
for(i=10;i>0;i--)
{
dis_temp(get_temp());}
comm(buff);
for(i=10;i>0;i--)
{
dis_temp(get_temp());}
}
}
void serial() interrupt 4
{
ES = 0; //关闭串行中断
RI = 0; //清除串行接受标志位
buf = SBUF; //从串口缓冲区取得数据
switch(buf)
{
case 0x31: P1=0xfe;break; //接收到1,第一个LED亮
case 0x32: P1=0xfd;break; //接收到2,第二个LED亮
case 0x33: P1=0xfb;break; //接收到3,第三个LED亮
case 0x34: P1=0xf7;break; //接收到4,第四个LED亮
case 0x35: P1=0xef;break; //接收到5,第五个LED亮
case 0x36: P1=0xdf;break; //接收到5,第六个LED亮
case 0x37: P1=0xbf;break; //接收到5,第七个LED亮
case 0x38: P1=0x7f;break; /接收到5,第八个LED亮
default: P1=0xff;break; //接收到其它数据,灯不亮
}
ES = 1; //允许串口中断
}
附录二:上位机程序(部分)
#include "stdafx.h"
#include "comm.h"
#include "commDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endifclass CAboutDlg : public CDialog
void CCommDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CCommDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CCommDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
BEGIN_EVENTSINK_MAP(CCommDlg, CDialog)
//{{AFX_EVENTSINK_MAP(CCommDlg)
ON_EVENT(CCommDlg, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
void CCommDlg::OnComm()
{
if(stop)return;
V ARIANT m_input1;
COleSafeArray m_input2;
long length,i;
BYTE data[1024];
CString str;
if(m_Comm.GetCommEvent()==2)//接收缓冲区内有字符
{
m_input1=m_Comm.GetInput();//读取缓冲区内的数据
m_input2=m_input1;//将V ARIANT型变量转换为ColeSafeArray型变量
length=m_input2.GetOneDimSize();//确定数据长度
for(i=0;i<length;i++)
m_input2.GetElement(&i,data+i);//将数据转换为BYTE型数组
for(i=0;i<length;i++)//将数组转换为Cstring型变量
{
BYTE a=* (char *)(data+i);
if(m_hex.GetCheck())
str.Format("%02X ",a);
else str.Format("%c",a);
m_ReceiveData+=str;
}
}
UpdateData(FALSE);//更新编辑框内容
}
char HexChar(char c)//检测一个字符是不是十六进制字符,若是返回相应的值,否则返回0x10;
{if((c>='0')&&(c<='9'))
return c-0x30;
else if((c>='A')&&(c<='F'))
return c-'A'+10;
else if((c>='a')&&(c<='f'))
return c-'a'+10;
else return 0x10;
}
int Str2Hex(CString str,CByteArray &data)
{//将一个字符串作为十六进制串转化为一个字节数组,字节间可用空格分隔,返回转换后的字节数组长度,同时字节数组长度自动设置。
int t,t1;
int rlen=0,len=str.GetLength();
data.SetSize(len/2);
for(int i=0;i<len;)
{char l,h=str[i];
if(h==' ')
{i++;
continue;
}
i++;
if(i>=len)break;
l=str[i];
t=HexChar(h);
t1=HexChar(l);
if((t==16)||(t1==16))
break;
else t=t*16+t1;
i++;
data[rlen]=(char)t;
rlen++;
}
data.SetSize(rlen);
return rlen;
}
void CCommDlg::OnButton1()
{
if( !m_Comm.GetPortOpen())
m_Comm.SetPortOpen(TRUE);//打开串口
UpdateData(TRUE);
if(m_hexsend.GetCheck())
{CByteArray data;
int len=Str2Hex(m_SendData,data);
m_Comm.SetOutput(COleVariant(data));//发送数据
}
else m_Comm.SetOutput(COleVariant(m_SendData));//发送数据}
void CCommDlg::OnButton2()
{
m_ReceiveData.Empty();//清除接收对话框中的数据
//m_SendData.Empty();//清除发送对话框中的数据UpdateData(FALSE);
}
void CCommDlg::OnComselect()
{
if(m_Comm.GetPortOpen())
m_Comm.SetPortOpen(FALSE);
m_Comm.SetCommPort(m_com.GetCurSel()+1);
}
void CCommDlg::OnComspeed()
{
CString temp;
int i=m_speed.GetCurSel();
switch(i)
{
case 0:
i=2400;
break;
case 1:
i=4800;
break;
case 2:
i=9600;
break;
case 3:
i=19200;
break;
case 4:
i=38400;
break;
}
temp.Format("%d,n,8,1",i);
m_Comm.SetSettings(temp);
}
void CCommDlg::OnStoprecv()
{
stop=!stop;
if(stop)
m_stop.SetWindowText("继续");
else
m_stop.SetWindowText("暂停");
}
附录三:单片机实物图
指导教师签字:
年月日。