历史上的今天

今天是:2024年10月19日(星期六)

正在发生

2019年10月19日 | PIC16系列单片机与PC机 串行通信的软硬件实现

发布者:精品古钱斋 来源: eefocus关键字:PIC16系列  单片机  串行通信  软硬件 手机看文章 扫描二维码
随时随地手机看文章

1 前言


美国Microchip公司的PIC16系列单片机是一种新型的CMOS工艺的8位单片机。其中,PIC16FXX单片机的程序存储器为电可擦除闪速存储器(flash),可多次修改程序,甚至可以在线编程。PIC16F83和PIC16F84片内数据存储器除RAM外,还有64字节的EEPROM,可以当作一般的或非易失性的数据存储器使用,简单方便。它还具有片内上电复位、延时电路、看门狗电路等。另外,PIC16系列单片机功耗极低,因而是一种非常适合在各种便携式设备中使用的高性价比的单片机,并已经得到了越来越广泛的应用。


但是在许多需要大量计算的运用中,还必须借助微机的强大数据处理能力。这样必须通过通信电路实现PIC单片机与微机间的可靠数据传输。有的PIC16单片机内并没有提供串行口,所以串行通信必须通过自己设计的硬件电路和通信软件来实现。


下面介绍用查询法实现异步串行通讯的方法。同时给出了用PIC16F84单片机的两个I/O口模拟2线串行口的硬件接口电路、程序流程框图、单片机内通信程序以及微机内的通信程序等。


2 硬件实现方法与电路


PIC16F84单片机的程序存储器由1K×14的闪速(flash)存储器构成,它只有13条I/O口,1个定时器,为了尽量节省单片机的软硬件资源,采用下述异步串行通信的实现方法。


如图1所示,PIC16F84在4MHz时钟下,采用半双工方式,可实现9600波特率的异步串行数据通信,1位停止位,8位数据位,无校验位。接收和发送以低位在先(一般模式),采用软件延时。为节省篇幅,单片机内的通信程序中未提供任何握手协议,用户可根据自己的需要在软件中加入握手方式。


由于PIC16F84本身没有专门的串行口,这里用其I/O口来模拟串行口的功能。


PC机的串行接口是符合EIA RS-232C规范的外部总线标准接口。RS-232C采用的是负逻辑,即逻辑“1”:-5V至-15V;逻辑“0”:+5V至+15V。而CMOS电平为:逻辑“1”:4.99V,逻辑“0”:0.01V;TTL电平的逻辑“1”和“0”则分别为2.4V和0.4V。因此在用RS-232C总线进行串行通信时需外接电路实现电平转换。在发送端用驱动器将TTL或CMOS电平转换为RS-232C电平,在接收端用接收器将RS—232C电平再转换为TTL或CMOS电平。


这里选用了MAXIM公司的MAX202E来作电平转换。MAX202E属于MAXIM公司的通用串行接收/发送驱动器芯片。其外围电路简单,只需外接四个0.1μF的电容即可,如图1所示。


jc.GIF (2374 bytes)

图1 接口原理图


3 PIC16F84单片机内通信程序的设计

jc1.GIF (4938 bytes)

图2 接收子程序框图   图3发送子程序框图


图2和图3分别是串行发送和接收的子程序流程框图。发送时,通过使数据发送端DX为低电平并保持B秒(9600波特率时为104μs)来发送起始位。随后每B秒钟通过置位或清零DX端把数据发送出去。这里的B是指一位所持续的时间(B=1/波特率)。接收时,数据接收端DR大约要每B/2秒(9600波特率时为52μs)查询一次以检测起始位,如果检测到起始位,则在大约1.5B秒(9600波特率时为156μs)后检测第一位数据位,随后每B秒钟检测一次其它的数据位。


相应的源程序如下:


;接收子程序

Rcvr

          clrwdt


;清片内看门狗

;定时器

btfsc


RA,DR ;检测起始位

goto


Rcvr ;未检测到起始位

movlw


8 ;检测到起始位

movwf


R_CNT ;8位数据位

Rnext

call


Delay ;延时B/2秒

bcf


STATUS,C ;清进位标志

rrf


RevReg ;LSB在先

btfsc


RA,DR ;该位为0

 


;还是为1

bsf


RcvReg,MSB ;为1

call


Delay ;延时B/2秒

decfsz


R_CNT

goto


Rnext

retlw0


;返回

;发送子程序

Xmtr

clrwdt


;清片内看门狗

;定时器

movlw


8 ;发送位数为8

movwf


X_CNT

bcf


RA,DX ;发送起始位

Xnext

call


Delay ;延时B/2秒

call


Delay ;延时B/2秒

rrf


XmtReg ;LSB在先

btfsc


STATUS,C ;检测将要发送

 


;的数据位

bsf


RA,DX ;数据位为1

btfss


STATUS,C

bcf


RA,DX ;数据位为0

decfsz


X_CNT ;位计数为0则

;发停止位

goto


Xnext ;位计数不为0

;则发下一位数据位

Xstop

call


Delay ;延时B/2秒

call


Delay ;延时B/2秒

Bsf


RA,DX ;发送停止位

Retlw


0 ;返回

;延时子程序

Delay

movlw


12 ;52μS延时

movwf


DCNT

Dnext

decfsz


DCNT

goto


Dnext

retlw 0


4 Win95的串行通信机制及串口查询法的原理


常用的DOS系统主要是工作在响应中断方式。PC机串行通信程序大多利用其BIOS块的INT14H中断,以查询串口的方式完成异步串行通信。


Windows系统函数即包含了通信支持中断功能。Win95系统为每个通信设备开辟了用户定义的输入输出缓冲区(即读/写缓冲区),数据进出通信口均由系统后台来完成。应用程序只需完成对输入输出缓冲区操作就可以了。实际过程是每接收一个字符就产生一个低级硬件中断,Win95系统中的串行驱动程序就取得了控制权,并将接收到的字符放入输入数据缓冲区。然后将控制权返还正在运行的应用程序。如果输入缓冲区数据已满,串行驱动程序用当前定义的流控制机制通知发送方停止发送数据。队列中的数据按“先进先出”的次序处理。


   (1) 按协议的设置初始化并打开串口,这样做就是通知Windows本应用程序需要这个串口,并封锁其他应用程序使它们不能使用此串口。

   (2) 配置这个串口。

   (3) 在串口上往返地传输数据,并在传输过程中进行校验。

   (4) 不需要此串口时,关闭串口。即释放串口以供其它应用程序使用。

在这四个步骤中,主要的程序代码集中在第(3)步。


串口查询法是一种主要工作在查询方式下的实现方法。当通信程序工作在“查询”方式时,可以不考虑Win95的进程和线程的问题。仅在串口有数据时,去读串口缓冲区就可以了,如图4所示。这种方法下确定串口读取的时机、握手协议及软件纠错的实现是程序员应考虑的主要问题。

jc2.GIF (1145 bytes)

图4 读取接收缓冲区数据流程图

jc3.GIF (1515 bytes)

图5 串口初始化流程


由于这种方法主要工作在查询方式。程序员必须完成相当一部分通信状态的检测工作,许多细节(甚至包括通信过程中的字符属性的转换)也必须通过程序代码完成。这种查询方法对通信双方协议的依赖性尤其大。双方通信协议的约定对程序实现的难易程度影响很大。


串口查询法中,一般串口初始化的流程如图5。


值得注意的一点是,此方法下协议的约定必须满足以下条件:即甲方发送时,乙方必须在甲方发送动作之前进入循环接收状态,直到接收到字符后通过对串口读取函数ReadFile返回值的判断跳出循环状态。


同时,一般为了不使系统因循环等待接收而进入“死循环”状态,可以人为设置读取串口的循环次数,一般1000~10000次即可。


本程序的实现平台是VB4,这是一种极为灵活的高级语言,它可以方便地引入汇编语言的思维,利用其GoTo转向语句方便地控制程序的流程,灵活方便。


5 PC机内通信程序的实例


现约定甲方是PC机,乙方是单片机系统(如读卡器)。通信格式设置为2400波特率,8位数据位,1位停止位,无奇偶校验。


下面是一个约定好通讯协议的程序实例,协议流程如图6所示。


以下是甲方(PC机)的几个子函数的程序实例。

jc4.GIF (2223 bytes)


图6 通信协议流程


Private Function OpenThePort(cPort as String,cBaud as String,cParity


as String,cData as String,tStops asString)As Boolean    ’ 打开串口的子过程


   Dim lResult as Long


   Dim lHandle as Long


   Dim DCB_COMM as DCB


   Dim cDCBConfig as String


   lHandle = CreateFile(cPort,GENERIC_READ Or GENERIC_WRITE,


   0&,0&,OPEN_EXISTING,0&,0&)


   If lHandle = -1 Then    ’打开串口失败


       OpenThePort = False


       MsgBox “串口可能正被其他应用程序占用!”


       lResult = CloseHandle(lHandle)  ’先关闭串口后再打开


       If lResult = 0 Then


           OpenThePort


           Exit Function


       End If


   End If


   cDCBConfig.band = 2400     ’设置DCB


   cDCBConfig.parity = None


   cDCBConfig.data = 8


   cDCBConfig.stop = 1


   lResult = BuildCommDCB(cDCBConfig,DCB_COMM)     ’按用户设定配置一个DCB结构


   If lResult = 0 Then


        OpenThePort = False


        MsgBox “无法建立DCB设备控制块”


        Exit Function


   End If


   lResult = SetCommState(lHandle,DCB_Comm)  ’实际设置一个串口的DCB                    


   If lResult = 0 Then


        OpenThePort = False


        MsgBox “无法建立DCB设备控制块”


        Exit Function


   End If


   OpenThePort = True


End Function


Private Sub SendHand ( ) ’发送握手信号的子过程


   Dim Nchars As Long


   Static Readbuff As String * 1


   Static Writebuff As String * 1


   Dim lpDCB As DCB


   Dim lRet As Long


   Dim lHandle As Long


   Dim lpOverlapped As OVERLAPPED


   Dim RNum As Integer


   MsgBox “请把读卡器插在串口2上!”,


                48,“提示窗口”


   lHandle = OpenThePort(COMM1,2400,None,8,1)


   lRet = PurgeComm( lHandle,1 ) ’清输出缓冲区


   lRet = PurgeComm( lHandle,0 ) ’清输入缓冲区


   lRet = GetCommState ( lHandle,lpDCB ) ’获得通讯口的状态


Shand:


   Writebuff$= Chr$(&H8F)


   lRet = WriteFile (lHandle,Writebuff$,1,Nchars,lpOverlapped )


                   ’送握手信号入串口缓冲区


      If lRet <= 0 Then


         MsgBox “发送操作出错,卡握手信号未发送成功”, 16


         GoTo Shand ’不成功则重发


      Else


          GoTo Qtest


      End If


   GoTo Shand


Qtest:


   Readbuff$ =“ ” ’清除缓冲区为空


Do While lHandle ’循环查询串口


   RNum = 0 ’设置读串口次数的指针为0


ReadAgain:


   lRet = ReadFile( lHandle,   Readbuff$,1,Nchars,lpOverlapped )


   If lRet < 0 Then


      MsgBox “读取应答信号时出错”, 16


      End If


      If lRet = 0 Then


         If RNum > 1000 Then  ’只读1000次串口,以免陷入死循环


             MsgBox


            "卡没有插接好或卡没有接在串口上!"


            GoTo CloseP


        End If


        RNum = RNum + 1


        GoTo ReadAgain


   End If


   If Hex$(Asc(Readbuff)) <> Hex$(&HFF) Then GoTo Shand


        ’回送码不正确则返回继续发送握手信号


   Else


      Label1.Caption = “握手信号是:”


        +Hex$(Asc(Readbuff$))


      Msgbox “握手信号正确,已正确联机”


      GoTo CloseP


   End If


Loop


CloseP:lRet = CloseHandle( lHandle )


           If lRet = 0 Then


               MsgBox “串行通讯口关闭成功”,


                            48,“提示窗口”


           End If


End Sub


这里要注意的是:当PC机与单片机系统通信时,单片机数据存储区( RAM )内的数据是十六进制,在信号线上传输的是十六进制数的ASCII码的二进制形式;而Windows系统下使用的是ANSI码,ANSI码仅在前126个与ASCII码相同。即在Win95下接收到的是十六进制数的ASCII码的字符串,可先转换为ANSI码后再在Win95下还原为十六进制数。


具体为:Code$=Hex$(Asc ( Readbuff$ ) )


另外,由于32位API函数参数的数据类型的变化,所有整形参数都被换为长整型(Long)以支持32位的处理,这一点在设置返回值时尤其如此。


6 结束语


以上的软硬件在我们的实践中达到了较为理想的效果。通过软件节省了硬件的开销,并通过在PIC16F84单片机系统和PC机双方的通信软件内增加握手信号,达到了软件数据校验的目的,获得了较高的通信可靠性。


参 考 文 献


1 MICROCHIP CO. PIC16/17 MICROCO-NTROLLER DATA BOOK. 1995/1996   

2 李东星等. PIC16CXX系列单片机应用设计. 高奇电子科技公司,1996.10 

3 美 Darwin Boyle等. Visual Basic 4 Developer’s Guide.

关键字:PIC16系列  单片机  串行通信  软硬件 引用地址:PIC16系列单片机与PC机 串行通信的软硬件实现

上一篇:PIC单片机在ICD1上做LED灯的循环闪烁程序
下一篇:PIC单片机在ICD 上做一个简单的查表程序

推荐阅读

近期,台积电开始多次提到它的一个新技术-「系统整合单晶片(System-on-Integrated-Chips;SoIC)」,而在今天的法说会上,更具体的提出量产的时间,预计在2021年,台积电的SoIC技术就将进行量产。究竟什么是SoIC?根据台积电在之前的技术论坛上的说明,所谓SoIC是一种创新的多芯片堆栈技术,能对10纳米以下的制程进行晶圆级的接合技术。该技术没有突起的...
着社会的发展,交通安全问题越来越凸显,传统的汽车安全理念也在逐渐发生变化,传统的安全理念很被动比如安全带、安全气囊、保险杠等多是些被动的方法并不能有效解决交通事故的发生,随着科技的进步,汽车的安全被细化,因此主动安全的概念慢慢的形成并不断的完善。 所谓主动安全,其实是和被动安全的概念相对应的。被动安全侧重于在遇到事故...
泄密者 Sleepy Kuma 援引韩国网站 Clien 的消息称,LG 可能不会在 2021 年上半年发布搭载骁龙 875 的旗舰机。  骁龙 875 是高通的首款 5nm 芯片,可能会在 12 月亮相。虽然不知道 LG 为什么决定不在明年上半年发布搭载该芯片的旗舰智能手机,但这背后可能有两个原因。 高通一直在稳步提高其旗舰芯片的价格,预计今...
据外媒报道,移动计算解决方案供应商新汉(NEXCOM)宣布发布其最新的IP65级车载计算器VTC 7252-7C4IP,呈现更安全的增强型车辆监控技术,使公共车辆更安全。新的车载监控系统会乘客活动,以及实时驾驶员和车辆位置状态等车上事件。(图片来源:新汉)该VTC 7252-7C4IP采用英特尔®第9代处理器Core™ i7-9700TE,支持通过多个摄像头同时实时监控,为驾驶...

史海拾趣

问答坊 | AI 解惑

DC/DC开关电源稳压集成电源

本文介绍几种新型 DC/DC开关电源稳压集成电路: LM25576 、 NCP3063 、 MAX15020 、S-8550。            DC/DC开关电源又称为 DC-DC 变换器,因为它的功能是进行输入/输出电压转换,实际上它的全过程是“DC-AC- ...…

查看全部问答∨

fft的c语言程序!

/**************************************************************/ /* */ /*     fft.c */ /* */ /**************************************************************/ /* Fast Fourier Transform (FFT). Using ...…

查看全部问答∨

申请

想申请用于消费机的设计,之前是用51内核。现在想换成M0…

查看全部问答∨

串口通信编程问题

请教下,在uclinux下面已经写好了我的串口1的驱动,移植到44b0下面了,串口0自带了驱动。现在的问题是,想不明白,怎么进行两台pc各接一个串口,一台发,一台收,中间的过程是怎么样的?帮忙看下啊。想昏了。 …

查看全部问答∨

STM32F103ZET6调试怪现象分析!

今天,同事跟我说,有一台设备,现象很怪!第一次上电,人机界面显示的电压不正常,系统的3相电压都是60伏,但是设备显示的,都在0伏左右,重新上电,就好了,这样的设备不能出厂呀,拿来我看! 一测,果然如此,在重新上电,测试100次,都正 ...…

查看全部问答∨

【PSoC4心得】自以为完美的ADC的LCD模拟指针显示 居然还有BUG出没

以100例中的第70个ADC例子为蓝本,增加LCD显示,把VREF改作5V(不算精确的电压),增大测量电压的范围到:0~5V. LCD显示出了显示电压的MV值外,另以模拟“指针”的形式,粗略地指示电压的变化情况。 看视频能了解更多真相,你一定还能猜出输入的 ...…

查看全部问答∨

在官方资料下了一个ADXL345的示例代码,用什么软件打开的?

在官方资料下了一个ADXL345的示例代码,我用的KEIL4打开,只能看到。C的文件,其他h文件打不开,另外编译的那个按钮也没用,这个何解,哪位用过的给个提示,是用的什么软件打开的,或者还是版本的问题吗 …

查看全部问答∨

MQ-3酒精传感器的温湿度补偿(维持相对精确且恒定的酒精浓度环境)

MQ-3传感器在校准后,在不是标准温湿度下所探测的数据误差会非常大。老师要求我做成高精度,所以让我画出在酒精浓度恒定(200ppm)的前提下,随温湿度增大传感器电阻值的变化曲线。那么问题来了,我怎么维持一个酒精浓度精确且恒定的环境呢?在学校 ...…

查看全部问答∨

SD卡读写必须要用FAT文件系统吗

SD卡读写必须要用FAT文件系统吗…

查看全部问答∨

请教一下关于数据校验方式

最近在解一组数据,数据校验码是最后两字节,大家一起帮我想想,一般出两个字节checksun的有哪些计算方法。 比如有双字节异或和,又比如CRC16的校验,低位在前,高位在后什么的。请大家帮帮忙告之一下一般还有哪些校验方式是两校验码的。 …

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved