DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 403|回复: 0
打印 上一主题 下一主题

PC机与PIC单片机串行通讯的实现

[复制链接]
跳转到指定楼层
楼主
发表于 2012-1-27 14:12:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

                                          PC机与PIC单片机串行通讯的实现          [/td]        [/tr]                                于万民,王哈力,郑洪平
              (哈尔滨理工大学 黑龙江哈尔滨 150040;
              2.齐齐哈尔铁路车辆(集团)有限责任公司
              黑龙江齐齐哈尔 161002)          [/td]        [/tr]                   [td]            随着计算机应用技术和微机网络技术的发展,计算机与其外部设备之间的数据传输越发显得重要。而串行通讯技术是实现这一功能的有效途径,他具有使用方便、数据传输可靠、适用于远距离通讯的特点,在工业监控、数据采集、检测等系统中有着广泛的应用。               
              1 异步串行通讯的原理及硬件电路的实现            1.1 异步串行通讯的原理            在异步通讯中,数据是一帧一帧传送的,其数据格式如图1所示。                                    
              在帧格式中,一个字符由4部分组成:起始位、数据位、奇偶校验位和停止位。首先是一个起始位"o",然后是5~8位数据(规定低位在前,高位在后),接下来是奇偶校验位(可省略),最后是停止位"1"。起始位"o"信号只占用1位,用来通知接收设备一个待接收的字符开始到来。线路上在不传送字符时应保持为"广。接收端不断检测线路的状态,若连续为"1"以后又检测到一个"o",就知道发来一个新字符,应马上准备接收。            1.2 硬件电路的实现            PC机与PICl6C711单片机之间的串行异步通讯采用RS232接口电路实现,利用计算机的串行接口进行数据传输。因为RS232逻辑电子对地是对称的,与TTI。,CMOS逻辑电平完全不同。逻辑"1"电平为一5~15V之间,逻辑电平"0"为+5~15V之间,其与单片机的逻辑电平不一致,必须进行电子转换,采用MCl488和MCl489芯片可分别实现TTL-RS232和RS232-TTL之间的电平转换。接口电路图如图2所示。                                    2 PC机通讯程序的编制            利用VC++6.0在Windows 98以上的环境下运行,VC实现串行通讯有3种途径:            (1)利用MSComm控件,他是Microsoh公司提供的简化WindOWS串行通讯编程的ActiveX控件,他为应用程序提供了处理串行通讯的2种方法:数据驱动法和查询法;            (2)利用Cseria1PONt类进行串口通讯,他适合于需要使用多个串口时的通讯;            (3)用Win API函数对串口进行操作。            本文以VC++6.0调用Win API函数为例编程实现。Win API函数对串口进行操作不是对端口直接进行读写,而是把所有的设备都看成文件,从而进行相应的文件操作。            第1步,在MainForm.cpp定义全局变量HANDLE hCom;//准备打开的串口的句柄HANDLEh Comm WatchThread;//辅助线程的全局函数            第2步,打开串口,设置串口hCom=CreateFile(〞COMl〞,GENERIC_READ︱GENERIC_WRITE,NULL,               OPEN_EXISTING, FILE_ FLAG_OVERLAPPED,NULL);//这里,我们使用FILE_FLAG_OVERLAPPED结构,这正是使用API函数实现非阻塞通讯的关键所在。            ASSERT(hCom! =INVALID HANDLE VALUE);
              //检测打开串口操作是否成功
              SetCommMask(hCom,EVRXCHAR IEVTXEMPTY);
              //设置事件驱动的类型
              SetupComm(hCom,1024,512); //设置输入缓冲区的大小
              PurgeComm (hCom, PURGE TXABORT ︱ PURGE RXABORT︱PURGETXCLEAR︱PURGE               RXCLEAR);
              //清理输入输出缓冲区
              COMMTIMEOUTS Comm丁imeOuts;
              //定义超时结构,井填写该结构
              SetCommTimeOuts (hCom,&CommTimesOuts);
              //设置读写操作所允许的超时
              DCB dcb; //设置数据控制快的结构
              dcb.BaudRate=9600; //设置波特率
              dcb.ByteSze=8;
              dcb.StopBits=onestopbit;
              dcb.fBinary=trUE; //二进制通讯格式
              dcb.fPar北y:FALSE;
              SetCommState(Hcom,&dcb) //串口参数配置            第3步,启动一个辅助线程,用于串口事件的处理。这里用他来监视串口状态,主线程则可专心进行数据处理。            HCommWatchThread =CreateThread ((LPSECURITY_ATtrIBUTES) NULL, (LPTHEARD_               START - ROUTINE) CommWatchPROC, GetSafeHwnd ( ),&dwThreadID);               
              ASSERT(hCommWatchThread! =NULL);            第4步,要为辅助线程写一个全局函数,主要完成数据接收的工作。            UNIT CommWatchProc(HWND hSendWnd)
              {DWORD dwEvtMask=0;
              SetCommMask(hCom,EV_RXCHAR︱EV_ _TXEMPTY);
              //有哪些串口事件需要监视
              WaitCommEvent(hCom,&dwEvMask,Os);
              //等待串口通讯事件的发生
              If(dwEvtMask&EV_RXCHAR)= =EV_RXCHAR)
              //缓冲区中有数据到达
              {COMSTART ComStari;
              DWORD dwLenlgth;
              ClearCommError(hCom,&dwErrorFlags,&ComStart);
              DwLength=ComStat.cbInQuei ; //输入缓冲区有多少数据
              If(dwLenlTth>0)
              {BOOL fReadStari
              fReadStat = =ReadFile (hCom, 1pBuffer,dwLength,
              &dwBytesRead,,&Read_OS(npTTYInfO));
              //读数据因为使用1pOverlapped结构,ReadFile()立即返回
              FALSE;
              If(! fReadStat)
              {if(GetLastError()= =ERROR_IO_PENDIN)
              {while (! GetOverLappedReault (hCom,&READ_OS
              (opTTYInfo),&dwNytesRead,trUE)
              {dWError=GetlastError();
              if(dwError==ERROR_IO_INCOMPLETE)
              CONTINUE; //缓冲区数据没有读完,继续
              ……}
              ∷ PostMESSage (( HWND ) hSendWnd, WM
              NOTIFYPROCESS,0,0); //通知主线程,串口接到数据}            第5步,在主线程中发送下行命令:            BOOL f WriteStat;
              Char szBuffer[count];
              //准备好发送的数据,放在szBuffer[]中
              FWrirteStar=WriteFile(hCom,szBuffer,dwbytesToWrite,
              &dwBytesWritten&WRITE_OS(npTTYInof));
              int err=GetLastError();
              if(!fWriteStat){if(GetLastError()= =ERROR_IO_PENDING)
              {while (! GetOverlappedResult (hCom,&WRITE OS
              (npTTYInfO),&dwBytesWritten,true))
              {dwError=GetLasrError();
              if(dwError= =ERROR_IO_INCOMPLETE)
              {dwBytesSent+=dwbytesWritten;
              continue;))}}            3 PIC"C711单片机串行通讯的实现            本文以单片机对温度传感器DSl820进行数据采集为例,实现单片机与PC机的通讯。限于篇幅,给出传送一个DSl820信号到串口的主要部分程序:            A2 EQU 2 //RA2接收数据端
              A1 EQU 1 //RAl发送数据
              RCVREG EQU 26
              R-COUNT EQU 27 //接收数据计数器
              T-COUNT EQU 28 //发送数据计数器
              MSB EQU 7
              NUM EQU 6B //设置下位机序号67
              NUM-ADDR EQU 2A //存储本机号码的地址
              SEN-CODE EQU 39 //传感器信号存放地址
              MAIN CALL SUB-INIT //初始化程序
              CALL SUB-REC //调用接收子程序
              CALL SUB_ COMP //对接收的数据进行处理
              CALL
              SUB_trANS //发送数据子程序
              GOTO
              EXIT
              SUB_INITCLRF RA
              BCF STATUS,RP0
              MOVLW B'00001101' //初始化MOVWF
              trISA
              MOVLW NUM
              MOVWF NUM
              RETURN
              SUB-REC
              RCVR BTFSCRA,A2 //检测起始位
              GOTO RCVR // 未检测到
              MOVL W2 //接收的数据位数
              MOVWF R_COUN
              R_NEXTCALL DELAY //调用延时程序
              BCF STATUS,C
              RRF RCVREG
              BTFSC RA,A2
              BSF RCVREG,MSB
              CALL DELAY
              DECFSZ R_COUNT
              GOTO R_NEXT
              RETURN
              SUB_COMPMOVLW 6A
              MOVWF CONT
              MOVFCONT,W
              XORWF NUM_ADDR,1 MOVLW
              1 ;
              ADDWF NUM_ADDR,1 DECFSZ
              NUM-ADDR,1
              GOTO EXIT
              NOP
              OVERNOP
              RETURN
              SUB_trANSMOVLW 3 //发送的数据位数
              MOVWF T_ COUNT
              MOVLW 2A
              MOVWF SEN_CODE
              BCF RA,A1 //设置发送起始位0
              T_NEXTCALL DELAY
              RRF SEN_CODE
              BTFSC STATUS,C
              BSF RA,A1 //发送数据位"1"
              BTFSS STATUS,C
              BCF RA,A1 //发送数据位"0"
              DECFS2T_COUNT
              GOTO T_NEXT
              CALL DELAY
              BSF RA,A1 //发送停止位
              RETURN
              EXITNOP
              END            4 结 语            本文所论述的通讯方法曾在对气体传感的在线检测中应用,由于DSl820为数字传感器,因此利用单片机可直接对DSl820操作,将温度值存储在单片机通用寄存器中,通过VC调用WinAPI函数对串口读写,可将温度值及气体传感器信号采集到PC机界面,从而实现对气体传感器在不同温度值下的在线检测。实践证明,利用VC开发通讯系统,从底层到上层直接面向用户,具有很强的调试功能,采用文中所述的方式构建的通讯在线检测系统工作稳定,数据传输可靠。                                    [/td]        [/tr]        [tr]          [td] [/td]        [/tr]        [tr]          [td]                       [/td]        [/tr]      [/table]    [/td][/tr]           
            
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2025-9-21 19:41 , 耗时 0.086815 秒, 19 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表