导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→PIC 端口模拟 红外通讯 38K调制 1200bps 偶校

* 62408: PIC 端口模拟 红外通讯 38K调制 1200bps 偶校验 半双工

   guest 
guest发表的帖子 

 PIC 端口模拟 红外通讯 38K调制 1200bps 偶校验 半双工
最近写了个小程序,贴出来大家分享

考虑到有些场合同时需要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

发表时间:2004年9月14日12:13:03

  
回复该帖

本主题共有 1 帖,分页:>>>>>该主题的所有内容[1]条

 *树形目录 只列出部分跟帖的标题以及简单的摘要信息 该主题的部分跟帖如下:

[上一篇帖子]:看占空比 3/4-->1  ; 1/4-->0?
[下一篇帖子]:你的麻烦真大了,时间要是充足,建议自己设计 ,软硬件设计,改了许多东西,照搬估计是不行的,