winnie 发表于 2009-5-6 09:36:59

PIC单片机I/O口单线通讯的实现

中、低档PIC单片机有些不带串口,有些虽然有串行口,却受串口固定协议的限制或留作他用,故需用普通I/O口进行通讯。由于中、低档机I/O口数量相对较少,为节省口线,就要用I/O口模拟串行通讯。
    本文以两片采用不同主频的PIC单片机(A机时钟频率为6MHz,使用口线RB6;B机时钟频率为4MHz,使用口线RB4)之间用异步通讯方式传送一组数据为例,说明I/O口一线通讯的实现方法。
    一、设计思想
    1.时钟同步问题
    因两个单片机的时钟不同,故采用异步通讯方式。发送、接收一位数据时,采用软件延时,保证发送、接收完全同步。
    2.数据发送、接收方式
    I/O口一线串行通讯,并-串(或串-并)转换用软件完成。将欲发送的字节存于16H中,经移位指令移至进位位。根据进位位的值,将口线RB6置0或1。接收端RB4接收并判断后,置进位标志为0或1,再经移位指令移入14H中。这样循环执行8次,就可将一个字节由低位到高位一位位地发送出去。数据传送速率可用延时循环的方法进行调节。
    3.握手协议
    先发握手信号,后发数据。假定A机为发送,B机为接收。A机开始发送时,先发送一个握手数据信号,B机收到后回送一个应答信号,表示同意接收。
    A机收到应答信号后,开始发送数据。握手信号和数据信号都按异步通讯格式,先发准备信号“1”,接着发送起始位“0”,然后发数据位。
    4.数据传送
    异步通讯时,发送时钟控制数据位的定时移位串行输出,接收时钟检测起始位,并控制数据的定时接收移入。两个时钟信号不是通过信号线传递,而是采用编程约定的办法,使之和实际使用的数据速率基本保持一致,而数据信号中的起始位则是发和收的同步控制。接收时钟为数据传送波特率的16倍频信号,即一个数据位宽的时间内将会出现16个接收时钟的信号,这是检测起始位和保证在数据位中央位置接收数据所需要的。为排除瞬时干扰,在检测到数据输入线的电平由“1”变为“0”之后,接收端将继续检测。仅当连续8个接收时钟周期内都检测到数据线上的电平为“0”时,才确认是起始位,且发送端每一个“0”或“1”都发送16次,接收端将以16倍的时钟周期,即以位宽时间为间隔,接收各数据位(在其中央位置接收数据)。一个字长数据(8位)接收完后,子程序返回。
    二、程序框图和源程序
    下面给出发送、接收一字长(8位)信号的子程序框图(见图1、图2)和PIC单片机源程序(发送、接收联络信号与数据信号相同)。注:所有延时程序略。
    1.发送子程序
   list p=16c65,f=inhx8m
portbequ6
trisbequ 16h
status equ3
rp0    equ5
        org0x100
fs    bsf   status,rp0;选存储体1
       bcf   trisb,6    ;置RB6为输出
     bcf   status,rp0;恢复存储体0
     bsf    portb,6   ;发准备信号“1”
       movlw0x08
       movwf1f       ;置发送字长
       call   ystb      ;延时同步
     movlw0x10
       movwf1c
fs1bcf    portb,6   ;发16个起始位
       decfsz1c,1
     goto   fs1
ts    call   ystj      ;延时调节波特率
     rrf    16h,1   ;发送字节移位
    btfscstatus,0
       goto    ty
     movlw0x10
       movwf1c
fs2bcf    portb,6   ;位为0,发16个“0”
       decfsz1c,1
     goto   fs2
       goto   tr
ty    movlw0x10
     movwf1c
fs3bsf    portb,6   ;位为1,发16个“1”
       decfsz1c,1
    goto         fs3
tr    decfsz1f,1
      goto    ts      ;发送未完,延时发下一位
       return          ;发送结束返回
    end
    2.接收子程序
   list p=16c65,f=inhx8m
portbequ6
trisbequ 16h
status equ 3
rp0    equ5
         org   0x200
js    bsf    status,rp0;选存储体1
      bsf   trisb,4   ;置RB4为输入
      bcf    status,rp0;恢复存储体0
js1btfss   portb,4    ;检测收到“1”否
      goto    js1      ;未收到“1”继续检测
      movlw0x08      ;置接收字长8位
      movwf1f
loop1 movlw0x08      ;置循环次数8
     movwf1d
loopbtfscportb,4    ;检测起始位
      goto   loop1   ;未收到“0”重置8次循环
     decfsz1d,1
       goto   loop       ;收到“0”继续检测
jz    call   ystb       ;收到8个“0”,延时同步,接收数据
      btfsc    portb,4   ;测试接收位
      goto   jy
      bcf    status,0    ;收到“0”置c=0
      goto   j1
jy    bsf    status,0    ;收到“1”置c=1
j1    rrf   14h,1      ;接收位移入14h
      decfsz1f,1
      goto   jz         ;未接收完,延时接收下一位
      return            ;接收完返回
      end

      
页: [1]
查看完整版本: PIC单片机I/O口单线通讯的实现