新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 用VC++.NET实现C167CR单片机与PC的串行通信

用VC++.NET实现C167CR单片机与PC的串行通信

作者:时间:2010-08-11来源:网络收藏
1 引言

PC与单片机构成的上位机、下位机分布式控制系统是一种常见的工业控制系统,单片机作为下位机可进行现场数据采集和就地控制,并可将采集到的数据或者状态 信息传送到上位PC机,以做进一步的分析处理。在实际应用中,上位机与下位机的通信问题是首要解决的问题之一,以其高效率、可靠、标准统一的优点 成为重要的通信手段,本文即在WINDOWS XP环境下,使用 中的MSComm控件实现C167CR单片机与PC之间的,其通信线路通过RS232连接(距离小于15m)。

2 C167CR单片机串行接口简介

是德国Infineon公司(前西门子半导体部)开发的一种16位单片机,属于单片机中的高端产品,片内有16通道10A/D转换 器、9个定时器、2个串行接口以及15个报文的CAN接口等功能模块。C167CR单片机有两种类型的串行接口:异步/同步串行接口(ASC0)和高速同 步串行接口(SSC),下面介绍异步/同步串行接口(ASC0)。ASC0的接口功能是通过设置几个专用寄存器来予以确定。

2.1 异步/同步串行接口(ASC0

16位控制寄存器S0CON的各位定义如图1所示。

数据接收由接收使能位S0REN来控制,只有当波特率生成器启动位S0R置为1”时,才能进行串行数据的发送和接收。

2.2 ASC0波特率寄存器S0BG

寄存器S0BG具有双重功能,可用作波特率生成器和重载寄存器,它具有13位的重载能力,不同的重载值对应不同的波特率。读SOBG时,返回的是定时器的内容(1513位返回为0),写SOBG时,将更改重载寄存器的值(1513位无效)。

2.3 缓存寄存器

串行口ASC0有两个缓存寄存器:接收缓存寄存器S0RBUF和发送缓存寄存器S0TBUF。发送时只要发送器空闲,装载到S0TBUF中的数据将立即转送到发送移位寄存器进行发送。将S0R S0REN置位,可直接从接收缓存寄存器S0RBUF读取数据。

2.4 中断寄存器

串行口ASC04个可位寻址的中断控制寄存器,发送中断寄存器S0TIC,发送缓存器中断寄存器S0TBIC,接收中断寄存器S0RIC,串行口ASC0错误中断寄存器S0EIC。只有当总中断允许位IEN1”时,这些中断寄存器才能进行控制。

3 控件

MSComm介绍

WINDOWS环境下,用户不能直接对PC的串行端口进行操作。 中,通过使用微软公司提供的Microsoft Comm Control控件(简称MSComm),可以方便地实现PC与外部设备之间的串行通信,编程工作量相对较少。注意Visual C++.NET中控件MSComm的函数与Visual C++6.0中的控件函数有所不同。MSComm有二十多个属性,其中主要的属性有:

CommPort:设置和返回通信端口号,CommPort1即使用串行端口Com1
PortOpen
:打开或关闭通信端口。
InBufferSize
:设置接收缓冲区大小。
OutBufferSize
:设置发送缓冲区大小。
Input
:读取并删除缓存区中的数据。
Output
:将数据写入发送缓存区。
Settings
:设置波特率、奇偶校验、数据位和停止位参数,默认值为“9600,N,8,1”,即波特率9600b/s、不进行奇偶校验、8个数据位、1个停止位。
InputLen
:设置每次从缓存区读取的字节数。

InputMode:设置和返回数据类型,设置为0时读取的数据为文本形式,设置为1时读取的数据为二进制数据。PC与单片机通信时,InputMode属性常设置为二进制数据形式。
Rthreshold
:设置OnComm事件发生前,接收缓存区可以接收的字符数。若设置为0,则不产生OnComm事件。

串行通信控件MSComm有二种处理通信的工作方式:事件驱动方式和查询工作方式。事件驱动方式是指:当串行端口接收或发送完指定数量数据以及发生通信错 误等情况时,MSComm控件触发OnComm事件,作出相应处理。查询工作方式是指:通过查询控件的某些属性值(如InBufferCount属性)来 作出进一步的处理。以下的程序实例采用事件驱动方式来接收数据。

4 串行通信程序实例

41程序功能

本程序是在WINDOWS XP环境下进行数据的发送和接收,PC一次性向C167CR单片机发送12字节(ASCII字符)的数据,单片机接收完数据后,再返回所接收到的所有数据,通过比较PC发送和接收到的数据,验证串行通信的可靠性。

42 PC通信程序设计

421 实现步骤

第一步:启动“Visual Studio.NET”,选择新建项目,在项目类型窗口中选择“Visual C++项目,模板窗口选择“MFC应用程序。输入项目名称,单击确定按钮。应用程序类型选择基于对话框,其他设置皆为默认值,单击完成按钮。

第二步:选择工具菜单下子菜单自定义工具箱COM组件中的“Microsoft Communication ControlVersion6.0”,单击确定按钮,插入MSComm控件。这与Visual C++6.0的插入方法不同。

第三步:删去应用程序主对话框中的静态文本和确定按钮,将取消按钮改为退出程序。添加两个静态文本发送数据接受数据,以及两个编辑框、一个按钮开始通信和一个MSComm控件。

第四步:添加变量和事件处理程序。由于Visual C++.NET没有ClassWizard,添加方法与Visual C++6.0不同。右键单击控件,通过子菜单添加变量添加事件处理程序实现此步骤。为两个编辑框分别添加CString型全局变量m_Send m_Receive,并为开始通信按钮添加BN_CLICKED事件处理函数OnSendData(),为MSComm控件添加CMSComm型变 量m_ComOnComm事件处理函数OnCommMscomm()。其中函数OnSendData()用来发送数据,函数OnCommMscomm ()用来接收数据。

窗体界面如图2所示。

用VC++.NET实现C167CR单片机与PC的串行通信

4.2.2 Visual C++.NET程序代码

在OnInitDialog()函数中进行串行口初始化

BOOL CserialDlg::OnInitDialog()
{//省略自动生成的代码
// TODO:在此添加额外的初始化代码
m_Com.put__CommPort(1); //设置串口为COM1
m_Com.put_InBufferSize(1024); //设置输入缓存区的大小,Bytes
m_Com.put_OutBufferSize(512); //设置发送缓存区的大小,Bytes
m_Com.put_PortOpen(true); // 打开串口
m_Com.put_InputMode(1); //以二进制方式接收数据
m_Com.put_Settings(“9600,n,8,1”); //设置数据传输速率等参数
m_Com.put_RThreshold(12); //表示收到12个字符引发一个OnComm事件
m_Com.put_InputLen(0); //一次读出接收缓存区的字符
m_Com.get_Input(); //清空接收缓存区
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}

数据发送程序代码

void CserialDlg::OnSendData()
{ // TODO: 在此添加控件通知处理程序代码
if(!m_Com.get_PortOpen()) m_Com.put_PortOpen(true); //若没打开串口,则打开
UpdateData(true); //将编辑框中的数据传递给变量
m_Com.put_Output(COleVariant(m_Send)) ; //将编辑框中的字符串数据转换
VARIANT类型,并发送出去
}

数据接收程序代码

void CserialDlg::OnCommMscomm()
{ // TODO: 在此添加消息处理程序代码
VARIANT vReceive;
COleSafeArray sReceivearray;
long k , i;
BYTE bReceive[1024];
CString str;
m_Receive="";
k=m_Com.get_CommEvent();
switch(k){
case 2: //接收到Rthreshold个数据
vReceive=m_Com.get_Input(); //读取缓存区内的数据
sReceivearray=vReceive; //将数据由VARIANT型转换为SafeArray型
for(i=0;i12;i++)
sReceivearray.GetElement(i,bReceive+i); //将数据转换为BTYE型数组
for (i=0;i5;i++)
{ char a=*(char*)(bReceive+i);
str.Format("%c",a);
m_Receive+=str; } //将数据转换为CString型,传递给变量m_Receive
UpdateData(false); //更新编辑框内容
break;
default: break;
}
}

程序中的put_Output()函数要求VARIANT型数据作为参数,可以调用类ColeVariant的构造函数将多种类型数据(如CString,int等)转换为VARIANT类型数据。同时数据接收函数get_Input()接收到的数据为VARIANT类型,可通过一系列转换,转换为所要求的类型予以显示。


4.3 通信程序设计

串行通信程序采取8位数据异步发送工作方式,接收数据使用中断方式,接收完12字节数据后再将全部数据发送出去。具体C语言程序如下。
初始化程序:

#include reg167.h>
void init(void)
{ P3 |= 0x0400; /*设置输入、输出引脚*/
DP3 |= 0x0400;
DP3 = 0xF7FF;
S0BG = 0x40; /*设置波特率为9600*/
S0CON = 0x8011; /*设置串行口状态:8位数据异步工作方式,1位停止位等*/
S0RIC=0x0044; /*设置中断允许位、中断优先级*/
IEN=1; } /*中断全局使能*/

主程序:

#include reg167.h>
extern void init(void);
static unsigned int i=0;
static unsigned char c[5];
unsigned int n;
void serialcom (void) interrupt 0x2B using s_rbank{ /*中断接收数据*/
if(i==0) c[0]=S0RBUF; else c[i]=S0RBUF;
if(i==11) { for(n=0;n12;n++) S0TBUF=c[n]; } /*接收12个字节后发送*/
i=i+1; if(i==12) i=0;
}
void main (void) { init (); while (1) {S0RIR=0;} }



评论


相关推荐

技术专区

关闭