热卖开发板:
  • 51单片机开发板
  • USB开发板
  • AVR单片机开发板
  • PIC端口模拟红外通讯程序设计

      最近写了个小程序,贴出来大家分享

       

      考虑到有些场合同时需要232(485),和红外,PIC16F87x系列单片机只有一个UART模块,因而用端口模拟红外通讯有它的用武之地。当然,如果仅仅是红外通讯那完全可以用
      UART模块,38K调制载波可用PWM生成,这样可简化设计。

      PIC 端口模拟 红外通讯 38K调制 1200bps 偶校验 半双工  适用于16F7X 16F87X


      INT_Serv    ;单片机自动清GIE
       movwf W_Temp      ;save W
       swapf STATUS,W     ;save STATUS
       movwf STATUS_Temp
       swapf FSR,W      ;save FSR
       movwf FSR_Temp
       
       ;红外接收中断
       banksel INTCON      ;RB0 interrupt
       btfsc INTCON,INTF
       call INT_Serv_IR_RX
       
       swapf FSR_Temp,W     ;restore FSR
       movwf FSR
       swapf STATUS_Temp,W    ;restore STATUS
       movwf STATUS
       swapf W_Temp,F     ;restore W
       swapf W_Temp,W
       retfie

      ;-----------------------------------------------------
      ;函数名:INT_Serv_IR_RX()
      ;函数功能:RB0红外数据中断接收子程序(0唤醒)
      ;函数入口参数:IR_Data_ADD,IR_Data_Length,注意中断中间变量INT_Loop_Temp3,INT_Loop_Temp4,IR_Data_Temp INT_Loop_Temp2
      ;函数出口参数:无
      ;-----------------------------------------------------
       
      INT_Serv_IR_RX
       
       
       banksel INTCON
       ;bcf  INTCON,INTE     ;Disable RB0 interrupt
       bcf  INTCON,INTF     ;clear interrutpt flag
       ;-----------------------------------
       movlw D'59'      ;wait start
       movwf INT_Loop_Temp3
      IR_RX_Start_Wait1
       nop
       nop
       nop
       nop
       decfsz INT_Loop_Temp3,F
       goto IR_RX_Start_Wait1
       
       btfsc PORTB,IR_RX     ;再一次检测起始位 数据中间采样,有待于改进 59*7+4+59*7+3=833us ---> 1200bps
       goto IR_RX_END
       
       movlw D'59'      ;wait start
       movwf INT_Loop_Temp3
      IR_RX_Start_Wait2
       nop
       nop
       nop
       nop
       decfsz INT_Loop_Temp3,F
       goto IR_RX_Start_Wait2
       ;-----------------------------------
       movlw D'8'      ;8位数据
       movwf INT_Loop_Temp4 
       clrf INT_Loop_Temp2
       
      IR_RX_lp1
       movlw D'58'      ;数据中间采样,有待于改进 58*7+7+4+59*7+3=833us ---> 1200bps
       movwf INT_Loop_Temp3
       
      IR_RX_Data_Wait1
       nop
       nop
       nop
       nop
       decfsz INT_Loop_Temp3,F
       goto IR_RX_Data_Wait1
       
       incf INT_Loop_Temp2,F    ;1的个数,为校验准备 (9月9号)
       btfss PORTB,IR_RX
       decf INT_Loop_Temp2,F
       nop
       nop
       nop
       nop
       
       bcf  STATUS,C     
       btfsc PORTB,IR_RX
       bsf  STATUS,C
       rrf  IR_Data_Temp,F    ;先收低位!!!!!!!!!!
       
       
       movlw D'59'      
       movwf INT_Loop_Temp3
       
      IR_RX_Data_Wait2
       nop
       nop
       nop
       nop
       decfsz INT_Loop_Temp3,F
       goto IR_RX_Data_Wait2
       
       decfsz INT_Loop_Temp4,F
       goto IR_RX_lp1     ;一字节完毕
       ;----------------------------
       movlw D'59'      ;接收校验位,数据中间采样,有待于改进 59*7+4+59*7+3=833us ---> 1200bps (9月9号)
       movwf INT_Loop_Temp3
      IR_RX_E_Wait1
       nop
       nop
       nop
       nop
       decfsz INT_Loop_Temp3,F
       goto IR_RX_E_Wait1
       
       incf INT_Loop_Temp2,F
       btfss PORTB,IR_RX
       decf INT_Loop_Temp2,F 
       nop
       
       movlw D'59'      
       movwf INT_Loop_Temp3
      IR_RX_E_Wait2
       nop
       nop
       nop
       nop
       decfsz INT_Loop_Temp3,F
       goto IR_RX_E_Wait2
       ;-------------------------------
       movlw D'109'      ;等待停止位,并给出10*7个周期用于处理下面的指令,方便接收连续数据.但规约规定,byte之间至少间隔12ms
       movwf INT_Loop_Temp3
      IR_RX_Stop_Wait
       nop
       nop
       nop
       nop
       decfsz INT_Loop_Temp3,F
       goto IR_RX_Stop_Wait
       ;------------------------------
          btfsc Flags,Flag_Receive_Frame   ;存在没有被处理过的数据帧,拒绝新帧。 (9月2号)
       goto IR_RX_END
       
       btfsc INT_Loop_Temp2,0    ;如有奇偶校验加在这里,C保留了校验位。(9月9号)
       goto IR_ECheck_Error    ;1个数为奇,丢帧
       

       ;如果接收的数据过长要加出错处理,否则可能影响RAM其他区域的寄存器数据!(待完善)
       
       movf IR_Data_Temp,W
       xorlw 0xFE
       btfsc   STATUS,Z
       goto IR_Receive_FEH
       btfss Flags,Flag_FEH    ;Flag_FEH=0 end
       goto IR_RX_END
       xorlw 0x16^0xFE
       btfsc STATUS,Z
       goto IR_Receive_END
       goto IR_Save_Data
       
      IR_Receive_FEH        ;数据中间出现FEH如何?
       bsf  Flags,Flag_FEH
       clrf IR_Data_Length
       goto IR_RX_END
      IR_Receive_END
       bsf  Flags,Flag_Receive_Frame     ;数据中间出现16H如何?
       bcf  Flags,Flag_FEH
       bsf  Flags,Flag_IR_Frame    ;IR Received frame
       ;goto INT_Serv_485_END    ;also save end
      IR_Save_Data
       movlw IR_Data_ADD
       movwf FSR
       movf IR_Data_Length,W
       addwf FSR,F
       movf IR_Data_Temp,W
       movwf INDF
       incf IR_Data_Length,F   ;增加接收数据个数
      IR_RX_END
       bsf  INTCON,INTE     ;enable RB0 interrupt
       return
      IR_ECheck_Error
       bcf  Flags,Flag_FEH
       bsf  INTCON,INTE     ;enable RB0 interrupt
       return
      ;-----------------------------------------------------
      ;函数名:Delay_20ms()
      ;函数功能:485字节间发送延时
      ;函数入口参数:Delay2
      ;函数出口参数:无
      ;-----------------------------------------------------
      Delay
       banksel Delay1
       clrf Delay1
       
      Delay_lp1
       decfsz Delay1,F
       goto Delay_lp1  ;(256*3+3)*25
       decfsz Delay2,F
       goto Delay_lp1
       
       return
      ;-----------------------------------------------------
      ;函数名:Initial_IR()
      ;函数功能:初始化红外
      ;函数入口参数:无
      ;函数出口参数:无
      ;----------------------------------------------------- 
      Initial_IR
       bsf  STATUS,RP0
       bcf  TRISC,IR_TX   ;output
       bsf  TRISB,IR_RX   ;input
       bcf  STATUS,RP0
       
       bcf  PORTC,IR_TX   ;no TX
       bcf  Flags,Flag_Receive_Frame
       clrf IR_Data_Length  ;clear Data_Number
       
       bsf  INTCON,INTE   ;enable RB0(IR_RX) interrupt !!!!!!
       bsf  STATUS,RP0   ;bank1
       bcf  OPTION_REG,INTEDG ;down endage
       bcf  STATUS,RP0   ;bank0
       
       return
      ;-----------------------------------------------------
      ;函数名:IR_Send_Byte()
      ;函数功能:红外字节发送
      ;函数入口参数:IR_Data_Temp(待发送数据)
      ;函数出口参数:无
      ;----------------------------------------------------- 
      IR_Send_Byte
       movlw D'9'
       movwf Loop_Temp1
       clrf Loop_Temp4   ;保存1的个数
       
       goto IR_Send_0   ;起始位
       
      IR_Send_Data_lp1
       rrf  IR_Data_Temp,F  ;先发低位!!!!!!!!1
       btfss STATUS,C   
       goto IR_Send_0
       goto IR_Send_1
       
      IR_Send_0
       movlw D'32'   ;32*26us=1200Hz
       movwf Loop_Temp2
      IR_38K      ;26uS=38K
       bsf  PORTC,IR_TX  ;7+1=8
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       bcf  PORTC,IR_TX  ;14+1+2+1=18
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       decfsz Loop_Temp2,F
       goto IR_38K
       
       goto IR_Send_Next
       
      IR_Send_1

       bcf  PORTC,IR_TX  ;~ 119*(4+1+2)=833us=1200Hz
       movlw D'119'
       movwf Loop_Temp2
       incf Loop_Temp4,F
      IR_Send_1_Delay
       nop
       nop
       nop
       nop
       decfsz Loop_Temp2,F
       goto IR_Send_1_Delay
       
      IR_Send_Next
       decfsz Loop_Temp1,F
       goto IR_Send_Data_lp1
      ;----------------------------------
      ;发送校验位
       btfsc Loop_Temp4,0
       goto IR_Send_E1 
      IR_Send_E0
       movlw D'32'   ;32*26us=1200Hz
       movwf Loop_Temp2
      IR_E38K      ;26uS=38K
       bsf  PORTC,IR_TX  ;7+1=8
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       bcf  PORTC,IR_TX  ;14+1+2+1=18
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       decfsz Loop_Temp2,F
       goto IR_E38K
       
       goto IR_Stop
      IR_Send_E1

       bcf  PORTC,IR_TX  ;~ 119*(4+1+2)=833us=1200Hz
       movlw D'119'
       movwf Loop_Temp2
      IR_Send_E1_Delay
       nop
       nop
       nop
       nop
       decfsz Loop_Temp2,F
       goto IR_Send_E1_Delay
      ;----------------------------------

      IR_Stop 
       bcf  PORTC,IR_TX  ;~ 119*(4+1+2)=833us=1200Hz
       movlw D'119'
       movwf Loop_Temp2
      IR_Send_Stop
       nop
       nop
       nop
       nop
       decfsz Loop_Temp2,F
       goto IR_Send_Stop

       return
       
      ;-----------------------------------------------------
      ;函数名:IR_Send_Data()
      ;函数功能:IR发送数据
      ;函数入口参数:IR_Data_ADD(发送数据首地址),IR_Data_Length(发送数据长度)
      ;函数出口参数:无
      ;----------------------------------------------------- 
      IR_Send_Data
          banksel INTCON
       bcf  INTCON,INTE  ;disable IR_RX interrupt
       
       banksel IR_Data_ADD
       movlw IR_Data_ADD  ;Data begining address
       movwf FSR
       
       movlw 3     ;3个FEH唤醒字节
       movwf Loop_Temp3
      Send_Data_IR_lp0 
       movlw 0xFE    ;FE 唤醒接收,视通讯协议定
       movwf IR_Data_Temp
       call IR_Send_Byte
       
       movlw Delay_20ms
       movwf Delay2
       call Delay    ;字节之间的延时 20ms
       
       decfsz Loop_Temp3,F
       goto Send_Data_IR_lp0
       
       movf IR_Data_Length,F    ;产生Z标志
       btfsc STATUS,Z   ;Length=0 return
       goto Send_Data_IR_END
       
       movf IR_Data_Length,W ;Data length
       movwf Loop_Temp3
        
      Send_Data_IR_lp1
       movf INDF,W
       
       ;addlw 0x33    ;
       
       movwf IR_Data_Temp
       call IR_Send_Byte
       
       movlw Delay_20ms
       movwf Delay2
       call Delay    ; 12ms<20ms<300ms
       
       incf FSR,F    ;point to next data
       decfsz Loop_Temp3,F  ;all data sended?
       goto Send_Data_IR_lp1 
      Send_Data_IR_END 
       banksel INTCON
       bsf  INTCON,INTE   ;enable IR_RX interrupt
       
       return

    声明:CEPARK已尽力确保内容的准确性,但因业务发展和技术服务的需要,有关内容可能会根据实际情况随时更新或者修改,恕不另行通知,不便之处敬请谅解!
      商城推荐
      社区指南
    CEPARK电子园-电子工程师自己的网络家园!
      迷你博客,轻松完成日志发布,管理相册;展示个性自我
      兴趣小组,热点话题,加入您感兴趣的话题讨论小组,一起交流吧
      最新资讯,热门话题与好友一起分享信息,他评论感兴趣的话题
      实名认证,真实交友,还可以轻松快捷的了解好友动态
      邀请您身边的好友,朋友,同事一起加入欢乐圈