No.62408 作者:guest 邮件:guest@guest.com ID:6 登陆:16560次 文章数:7648篇 最后登陆IP:219.68.9.43 最后登陆:2005/5/20 1:37:44 注册:2003/3/10 16:21:00 财富:35062 发帖时间:2004/9/14 12:13:03 发贴者IP:222.45.39.213 标题:guest:PIC 端口模拟 红外通讯 38K调制 1200bps 偶校验 半双工 摘要:No.62408PIC 端口模拟 红外通讯 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 b ......
>>返回讨论的主题
|