论文部分内容阅读
摘要:介绍上位机与下位机的串行通信的实现。下位机利用ARM技术,上位机用VC来编写串行通信程序。详细介绍了ARM自带的UART的工作原理及与计算机串行口的连接方法。利用WIN32 API函数在VC下实现了串行通信程序.并给出了部分代码实例。
关键词:ARM;串行通信
中图分类号:TP311文献标识码:A文章编号:1009-3044(2007)03-10705-01
1 引言
目前嵌入式技术的应用越来越广泛,已经深入到到工业控制、消费类电子产品、通信系统、网络系统、无线系统等各类产品市场。这类产品主要使用的微处理器也从最早的8位向32位转变,特别是ARM微处理器凭借其强大的功能日益受到电子工程师的喜爱。本文使用ARM7系列的LPC2290。
2 LPC2290的UART发送和接收原理
LPC2290的UART单元包括接收器模块和发送器模块。接收器模块U0Rx监视串行输入线RxD0的有效输入。当移位寄存器U0RSR接收到一个有效字符时,它将该字符传送到UART0 Rx缓冲寄存器FIFO中,等待CPU通过VPB接口进行访问。发送器模块U0Tx接收CPU或主机写入的数据并将数据缓存到UART0 TX保持寄存器FIFO(U0THR)中。移位寄存器U0TSR读取U0THR中的数据并将数据通过串行输出线TxD0发送。
3 LPC2290和PC机之间串行通信的硬件实现及初始化
在实际工程应用中PC机的RS 232接口性能指标并非最好,却由于广泛的市场支持而经久不衰。在使用中只需3根线就可实现2个数字设备的全双工数据传输正说明了RS 232的优势。通过电平转换芯片(如MAX232),把3.3 V的逻辑电平转换为RS 232的逻辑电平,此串行接口使用了RS 232的3根线进行通信。从TxD0引脚发送出去的信号经过电平转换再与外设进行通信,而从外部串口过来的信号则先经电平转换,然后由RxD0进入接收移位寄存器。
LPC2290和PC机之间进行串行通信首先需要进行初始化,主要包括波特率设置、串口工作模式设置。其中串口工作模式设置在线控制寄存器U0LCR中完成,其结构为:
波特率设置在除数锁存器U0DLL、U0DLM中设置,其中U0DLL存放除数的底8位,U0DLM存放除数的高8位。下图为初始化流程。
4 上位机通信程序的VC实现
利用Windows API提供的通信函数可以编写出可移植性强的串行通信程序。在Win32中,串口和其它通信设备均作为文件处理,串口的打开、关闭、读和写所用的API函数与操作文件的函数相同。可通过CreateFile函数打开串口;通过CloseFile函数关闭串口;通过DCB结构和GetCommState及SetCommState函数来设置串口状态;通过ReadFile和WriteFile函数读和写串口。对串行通信设备,Win32 API可支持同步和异步两种I/O操作。本文主要描述异步方式,异步操作方式相对要复杂一些,但它可让耗时的I/O操作在后台进行,这样不会挂起调用线程,这在大数据量通信的情况下对改善调用线程的响应速度是相当有效的。异步操作方式特别适合同时对多个串口设备进行I/O操作和同时对一个串口设备进行读写操作。
4.1串口设备的初始化
包括串口的打开、超时变量设置、串口通信事件的创建、串口状态参数的设置,代码如下:
HANDLE m_hComm;
m_hComm=CreateFile(“com1”,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
COMMTIMEOUTS m_CommTimeouts;//超时变量设置
m_CommTimeouts.ReadIntervalTimeout=1000;
m_CommTimeouts.ReadTotalTimeoutMultiplier=1000;
m_CommTimeouts.ReadTotalTimeoutConstant=1000;
m_CommTimeouts.WritetotalTimeoutMultiplier=1000;
m_CommTimeouts.WriteTotalTimeoutConstant=1000;
用异步方式操作串口必须先定义OVERLAPPED结构,其中的hEvent用CreateEvent函数建立,另外定义两个用于读写的OVERLAPPED结构,对应的hEvent用CreateEvent函数建立,代码如下:
if(m_ov.hEvent!=NULL)
ResetEvent(m_ov.hEvent);
m_ov.hEvent =CreateEvent(NULL,TRUE,FALSE,NULL);
m_hWriteEvent= CreateEvent(NULL,TRUE,FALSE,NULL);
m_hShutdownEvent= CreateEvent(NULL,TRUE,FALSE,NULL);
設置好通信事件后,再设置串口参数,可用BuildCommDCB和SetCommState函数设置。配置好参数后,用PurgeComm函数终止读写并清空接收与发送缓冲区。
4.2接收数据
一般向串口写数据是可以控制的,而读数据发生在什么时候是无法知道的,所以要建立一个线程专门负责读数据。在线程中,循环地用eadFile读串口,同时用WaitCommEvent函数检测线路状态:部分代码:
for (;;)
{//监测通信事件,掩码保存在Event变量中
bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);
Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE);
switch (Event)
{case 0: //关闭串口,结束线程
case 1://接收数据
GetCommMask(port->m_hComm, &CommEvent);
if (CommEvent & EV_RXCHAR) ReceiveChar(port, comstat);
break;
case 2://发送数据
WriteChar(port);break;}}
以上给出了用WIN32 API编写串行通信程序的基本思路,并用此方法编写了上位机通信程序。
5 结束语
PC机与下位机的通信在实际应用中广泛存在,目前包括串行通信及各种现场总线在内有多种实现方法,虽然RS 232存在通信距离限制等问题,但是它是绝大多数包括RS 485在内的通信协议的基础。经过某课题项目实践证明,下位机采集数据上传给上位机并接收上位机下发的命令参数,通信过程相当稳定。而运用新一代嵌入式技术与上位机通信必将成为一种趋势。
参考文献:
[1]龚建伟,熊光明.编著. Visual C++/Turbo C串口通信编程实践[M]. 电子工业出版社.
[2]周立功.等. ARM嵌入式系统基础教程[M]. 北京航空航天大学出版社.
[3]Robert D.Thompson.著.MFC开发人员参考手册[M].机械工业出版社.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
关键词:ARM;串行通信
中图分类号:TP311文献标识码:A文章编号:1009-3044(2007)03-10705-01
1 引言
目前嵌入式技术的应用越来越广泛,已经深入到到工业控制、消费类电子产品、通信系统、网络系统、无线系统等各类产品市场。这类产品主要使用的微处理器也从最早的8位向32位转变,特别是ARM微处理器凭借其强大的功能日益受到电子工程师的喜爱。本文使用ARM7系列的LPC2290。
2 LPC2290的UART发送和接收原理
LPC2290的UART单元包括接收器模块和发送器模块。接收器模块U0Rx监视串行输入线RxD0的有效输入。当移位寄存器U0RSR接收到一个有效字符时,它将该字符传送到UART0 Rx缓冲寄存器FIFO中,等待CPU通过VPB接口进行访问。发送器模块U0Tx接收CPU或主机写入的数据并将数据缓存到UART0 TX保持寄存器FIFO(U0THR)中。移位寄存器U0TSR读取U0THR中的数据并将数据通过串行输出线TxD0发送。
3 LPC2290和PC机之间串行通信的硬件实现及初始化
在实际工程应用中PC机的RS 232接口性能指标并非最好,却由于广泛的市场支持而经久不衰。在使用中只需3根线就可实现2个数字设备的全双工数据传输正说明了RS 232的优势。通过电平转换芯片(如MAX232),把3.3 V的逻辑电平转换为RS 232的逻辑电平,此串行接口使用了RS 232的3根线进行通信。从TxD0引脚发送出去的信号经过电平转换再与外设进行通信,而从外部串口过来的信号则先经电平转换,然后由RxD0进入接收移位寄存器。
LPC2290和PC机之间进行串行通信首先需要进行初始化,主要包括波特率设置、串口工作模式设置。其中串口工作模式设置在线控制寄存器U0LCR中完成,其结构为:
波特率设置在除数锁存器U0DLL、U0DLM中设置,其中U0DLL存放除数的底8位,U0DLM存放除数的高8位。下图为初始化流程。
4 上位机通信程序的VC实现
利用Windows API提供的通信函数可以编写出可移植性强的串行通信程序。在Win32中,串口和其它通信设备均作为文件处理,串口的打开、关闭、读和写所用的API函数与操作文件的函数相同。可通过CreateFile函数打开串口;通过CloseFile函数关闭串口;通过DCB结构和GetCommState及SetCommState函数来设置串口状态;通过ReadFile和WriteFile函数读和写串口。对串行通信设备,Win32 API可支持同步和异步两种I/O操作。本文主要描述异步方式,异步操作方式相对要复杂一些,但它可让耗时的I/O操作在后台进行,这样不会挂起调用线程,这在大数据量通信的情况下对改善调用线程的响应速度是相当有效的。异步操作方式特别适合同时对多个串口设备进行I/O操作和同时对一个串口设备进行读写操作。
4.1串口设备的初始化
包括串口的打开、超时变量设置、串口通信事件的创建、串口状态参数的设置,代码如下:
HANDLE m_hComm;
m_hComm=CreateFile(“com1”,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
COMMTIMEOUTS m_CommTimeouts;//超时变量设置
m_CommTimeouts.ReadIntervalTimeout=1000;
m_CommTimeouts.ReadTotalTimeoutMultiplier=1000;
m_CommTimeouts.ReadTotalTimeoutConstant=1000;
m_CommTimeouts.WritetotalTimeoutMultiplier=1000;
m_CommTimeouts.WriteTotalTimeoutConstant=1000;
用异步方式操作串口必须先定义OVERLAPPED结构,其中的hEvent用CreateEvent函数建立,另外定义两个用于读写的OVERLAPPED结构,对应的hEvent用CreateEvent函数建立,代码如下:
if(m_ov.hEvent!=NULL)
ResetEvent(m_ov.hEvent);
m_ov.hEvent =CreateEvent(NULL,TRUE,FALSE,NULL);
m_hWriteEvent= CreateEvent(NULL,TRUE,FALSE,NULL);
m_hShutdownEvent= CreateEvent(NULL,TRUE,FALSE,NULL);
設置好通信事件后,再设置串口参数,可用BuildCommDCB和SetCommState函数设置。配置好参数后,用PurgeComm函数终止读写并清空接收与发送缓冲区。
4.2接收数据
一般向串口写数据是可以控制的,而读数据发生在什么时候是无法知道的,所以要建立一个线程专门负责读数据。在线程中,循环地用eadFile读串口,同时用WaitCommEvent函数检测线路状态:部分代码:
for (;;)
{//监测通信事件,掩码保存在Event变量中
bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);
Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE);
switch (Event)
{case 0: //关闭串口,结束线程
case 1://接收数据
GetCommMask(port->m_hComm, &CommEvent);
if (CommEvent & EV_RXCHAR) ReceiveChar(port, comstat);
break;
case 2://发送数据
WriteChar(port);break;}}
以上给出了用WIN32 API编写串行通信程序的基本思路,并用此方法编写了上位机通信程序。
5 结束语
PC机与下位机的通信在实际应用中广泛存在,目前包括串行通信及各种现场总线在内有多种实现方法,虽然RS 232存在通信距离限制等问题,但是它是绝大多数包括RS 485在内的通信协议的基础。经过某课题项目实践证明,下位机采集数据上传给上位机并接收上位机下发的命令参数,通信过程相当稳定。而运用新一代嵌入式技术与上位机通信必将成为一种趋势。
参考文献:
[1]龚建伟,熊光明.编著. Visual C++/Turbo C串口通信编程实践[M]. 电子工业出版社.
[2]周立功.等. ARM嵌入式系统基础教程[M]. 北京航空航天大学出版社.
[3]Robert D.Thompson.著.MFC开发人员参考手册[M].机械工业出版社.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。