电脑红外遥控器

     大二小学期的时候,和David做了一个电脑红外遥控器。虽然谈不上创新吧,但是,除了我们,这一届也没有别人在做,最后的效果还不错,能作为一个大众小产品使用!

     下面将过程描述一下,希望对此感兴趣的童鞋有帮助~

      硬件:整个系统,微控制器采用了Microchip公司的PIC16F877,外围器件采用了MAX232电平转化芯片,HS38b通用红外线接头,11.052MHZ有源晶振及通用电脑串口。

      软件:编程语言是汇编,在电脑上利用Grider软件进行数据捕捉和命令的设置。

      一.      实验论证与比较

1,         红外线接受模块

红外线接受模块实用的是市面上常见的HS38系列红外接收管。它具有价格低廉,微型化、抗干扰能力强,输出信号幅度适应PIC信号接受,并且直接采用5V供电,不用另设电源电路。它可直接将模拟红外信号翻译成为单片机可以识别的高低电平,供单片机进行解码。

2.储存与译码模块

       储存与译码模块采用的是PIC系列单片机。单片机将完成一个串行接受,判断头码和诸如连续按键等误操作,核实后并行储存,再向下一个模块串行输出的过程。储存和译码模块是整个系统的核心。

3.电平转化和电脑通信模块

          这部分采用的是MAX232系列的电平转化芯片。改芯片有工作稳定,实用电压范围广等特点,同样采用的是5     V供电,和整个电路板相适应。输出一端分别与9口通用串行接口的23口相连,分别负责接受和发送数据,建立起单片机和电脑之间交流的桥梁。

4,供电模块

           本次实验采取了两套供电设计方案,分别为L7805系列稳压芯片供电和串口窃电。前者勿用赘述,而窃电电路利用DTR, RTS两口的串口信号电压,通过稳压电路对整个电路板进行供电。由于DTR,RTS默认电压为负12V,在电压正负转化中又分为两套方案,分别为通过L7905实现和C++控制台软件编程实现。所有三套方案均存在与电路板上,此为整个硬件设计的一大尝试。

 

.硬件系统设计

1.系统总体设计

系统模块框图如图所示:

 

 

2.各模块工作原理说明:

供电模块:采用3种模式——外接电源供电,串口窃电(分为硬件和软件两种实现方法),为整个电路提供动力。

红外接受模块:由HS28b完成,直接与单片机进行通信

电平转化模块:有MAX232完成电平转化,完成单片机和电脑间的上行和下行通信。

通用接口:内嵌窃电电路接头。DTR ,RTS口被引出供电。

其他诸如复位,晶振等最小系统必备模块不在赘述。其中晶振使用的是11.0592MHZ,复位为人工复位。

 

 

 

3.各模块设计及参数计算

   1红外线模块的设计

 

 

 

 

2.       电平转化模块设计

3.       电源电路设计

1,外接电源供电

2,用软件对串口47口编程后,用稳压管实现5V供电

其中用控制台程序将DTR,RTS置为高电平(DTRenable,RTSenable

 

4.       L7905实现电平转化进行供电

 

 

 

三,软件系统设计

1主程序流程图

  

 

 

 

 

 

 

 

2.子程序Read_IR流程图

3.子程序Tran_Cmd流程图

 

4.子程序Delay0流程图

5.子程序

    子程序4是普通的计数延时,使用三层的循环计数。

 

四,系统调试

1,    硬件系统调试

一开始的时候我们找了一个做成是红外先遥控器为蓝本设计了电路图(蓝本用的不是PIC系列芯片,我们做了一些改进)。由于很多问题都是一知半解,而在PROTEUS中没有HS38系列芯片,红外输入无法模拟,只有直接进行上板测试,因而走了不少弯路。如下是最初的设计图:

 而最终的设计除了红外管以外全部推翻原有电路图。

一,        电平转化电路

             最初的电平转化电路即如图所示。设想用一个三极管的反向和放大功能达到电平的转化,使得输出电平能够达到电脑串口接受到的目的。这是沿用的前人蓝本的思路,但实际操作起来发现完全不可行,输出电平远远偏离接受范围,串口接受到的数据全为1111111.后来听从老师的建议,采用MAX232进行电平转化工作,并首先在最小系统的盒子上实验成功,最终电平转化的问题迎刃而解。采用MAX232工作十分稳定,干扰也很小,效果突出。

二,         窃电电路

最初的设计也是如上图所示,整个窃电电路电路简单并且看上去很行,既有稳压模块也有防止电平抖动的模块。但上板试验后才发现忽略了一个最大的问题:窃电要求从正电源进行,而47口的默认输出均为负12伏。查资料发现要对串口进行编程,将DTR,RTS口置为ENABLE才能输出高电平。而在自学部分控制台串口操作程序(MScomm),对串口进行编程后发现串口电平仍不变,为此几天百思不得其解。偶尔尝试将串口和电路板接上在队串口电压测量,发现此时窃电电路已经正常工作。猜想可能是串口悬空是维持了默认设置,当有数据交换设置才被激活。初步验收后老师提出更高要求,不对串口编程直接用硬件实现,于是有了第三套L7905的设计方案。

三,        晶振和复位

           晶振最初采用的是无源晶振,发现工作不稳定,后换成有对应频率的有源晶振。复位电路最初采用的自动复位,但发现程序一旦跑飞就拉不回来,最终采取了人工复位的设计方案。

2,    软件系统调试

软件的调试主要是进行仿真对红外信号的解码仿真可以使用引脚连续激励方式,编写.sti文件。在这个过程中,解决的问题主要有以下的几个方面:

1.      程序的流程图是在基础上,和老师交流得到的,程序是在反复的修改下完成的,所以,确定没有逻辑上的错误,但是,进行仿真时的结果并不准确,经过检查,发现了主要的错误在于,实际过程中的电平高低的持续的时间不会和通过示波器看到的记录时间值吻合,又因为在编程的过程中,是按严格的电平持续时间计算的,所以,出现了问题,例如,当接收命令码的时候要捕捉01时,持续的低电平下,计数器LoX的值是56时,我们按照0处理,这时低电平的持续时间是0.5ms,在这里时间是精确的,没有允余。实际上常有误差,就是在电脑上仿真的时候也会不能正确的解码,所以,这里要对计数的范围进行扩大,例如,当20时,就按照0处理。在此后的仿真中,结果是正确的。

2.      遥控器的额外信号问题。选用的遥控器是万能遥控器,在按一个键的情况下,这种遥控器会发射5种编码的值,而且是一种编码格式跟随另外一种编码格式,在这种情况下,红外一体化接收头的电平变化多种多样,这样造成了错误,所以,要对无用的信号进行屏蔽。

如果不进行屏蔽,就会发生单片机对同一按键进行了两次的数据传输。此处屏蔽的方法是在正确的接收信号后关闭引脚RC6RC6接红外接收头),时间是1s

 

 

3,    软硬件联合调试。

由于作品涉及到的部分多,在解决了原理和基本矛盾后后期的调试基本上都是软硬件联合调试。在最小系统的箱子上搭出电路,取得初步成果后上电路板试验,再将最小系统和电路板进行比较。在期间主要解决了两大问题:

,解码程序头码的处理

     最初对头码的解码思路较为理想化,延时的空间不够。在传输事先在单片机中储存的数据是效果良好,但进行红外数据的接受和传输时数据很不稳定。在实际操作中又更多干扰信号和抖动,需要讲头码验证的条件放宽,否则许多正确的信号也无法被识别。

二,晶振和复位电路的调整

     发现工作不稳定,后换成有对应频率的有源晶振。复位电路最初采用的自动复位,但发现程序一旦跑飞就拉不回来,最终采取了人工复位的设计方案。并对通信电路中的串行电阻值进行了一定范围的调整。

 

最终在实验板上的效果超过了在试验箱上的效果(试验箱上的接线多少有些接触不良)。

--------------------------------------------------------------end---------------------------------------------------

这里有很多的图片没能让大家看清。可以通过QQ:[email protected]

 -------------------------------------------------------------------------------------------------------------------------

汇编代码:

;Read IR to R232 by PIC6F877 ;这是一个关于红外线解码和PC与PIC之间传输的程序 ;wanghailiang 09-9-2 ;list p=16F877 ;硬件的介绍 ;************************************************************************ ;**general registers counta EQU 0x32 ;延时器 countb EQU 0x33 ; LoX EQU 0x34 ;暂时计数 Bit_Cntr EQU 0x35 ;字节计数位 Cmd_Byte EQU 0x36 ;暂存命令码 Dev_Byte EQU 0x37 ;暂存机器码 Flags EQU 0x38 ;接收标志位 C EQU 0x00 ;状态寄存器进位位 ErrFlag EQU 0x00 StartFlag EQU 0x01 ;接收标志位 One EQU 0x02 Zero EQU 0x03 StartFlag1 EQU 0x04 ;************************************************************************* ;****SFR trm0 EQU 01h ;计数器0地址 STATUS EQU 3h RS_PORT EQU 07h option_reg EQU 81h ;定义选项寄存器地址 RS_TRIS EQU 87h intcon EQU 0Bh ADCON1 EQU 9FH IR_PORT EQU 05h IR_TRIS EQU 85h ; 红外接收口 IR_In EQU 1h TXREG EQU 19h SPBRG EQU 99h RCSTA EQU 18h TXSTA EQU 98h TXEN EQU 0x05 ;RS控制寄存器,控制位 Tran_On EQU 0x04 SPEN EQU 0x07 TX9 EQU 0x06 ;9位数据校检 RP0 EQU 5h trm0b EQU d'256'-d'130' ;6ms的延时初始值(128分频下!) ;**************************************************************************** ;***main org 0x0000 main Initilise clrf Dev_Byte clrf Cmd_Byte bsf RCSTA, SPEN bsf STATUS,RP0 movlw .71 ;波特(11.0592Mhz) movwf SPBRG bsf IR_TRIS,IR_In movlw 0x00 movwf RS_TRIS movlw B'00000110' movwf ADCON1 movlw B'11100101' movwf TXSTA ;输出属性的定义 movlw B'01010110' ;初始化计时器 movwf option_reg bcf STATUS,RP0 ; call ReadIR ;将目的字节码存到暂时寄存器中 call Tran_Cmd ;将命令码传输到串口上 bsf STATUS,RP0 bcf IR_PORT,IR_In bcf STATUS,RP0 call delay1 goto Initilise ;回到主程序 ;*************************************************************************** ;IR routines ReadIR clrf Flags clrf LoX call delay0 movlw 0x08 ;准备接收8字节的开始码 movwf Bit_Cntr Get_Dev call Read_Pulse CheckOut1 btfss Flags, StartFlag1 ; goto Initilise Begin_RevDev call Read_Pulse btfsc Flags, ErrFlag ;放弃,如果检测到错误 goto Initilise bcf STATUS , C btfss Flags, Zero bsf STATUS , C rrf Dev_Byte , f decfsz Bit_Cntr , f goto Begin_RevDev movlw 0x08 ;准备接收8字节的命令码 movwf Bit_Cntr bcf Flags,StartFlag1 Get_Cmd Next_RcvBit call Read_Pulse CheckOut2 btfss Flags,StartFlag1 ; goto Initilise Begin_RevCmd call Read_Pulse btfsc Flags,ErrFlag ;放弃,如果检测到错误 goto Initilise bcf STATUS , C btfss Flags, Zero bsf STATUS , C rrf Cmd_Byte , f decfsz Bit_Cntr , f goto Begin_RevCmd retlw 0x00 ;end of ReadIR ;----------------------------------------------------------------------------- ;---Read_Pulse Read_Pulse clrf LoX btfsc IR_PORT,IR_In goto Nops goto $-2 Nops nop nop nop nop nop ;延时响应时间 nop ;为计数器工作计算时间 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop incf LoX, f btfsc IR_PORT, IR_In goto Nops ;如果还是接收到高电平则继续计数 ; test if Zero, One, or Start (or error) Chk_Pulse clrf Flags TryError movf LoX, w ; 时间短 addlw d'255' - d'8' ; if LoX <= 8 btfsc STATUS , C goto TryZero bsf Flags, ErrFlag ; 错误 bcf Flags, StartFlag retlw 0x00 TryZero movf LoX, w ; 检查0 addlw d'255' - d'52' ; if LoX <= 52 btfsc STATUS , C goto TryOne bsf Flags, Zero ;0 retlw 0x00 TryOne movf LoX, w ;检查1 addlw d'255' - d'150' ; if LoX <= 150 btfsc STATUS , C goto TryStart1 bsf Flags, One ;1 retlw 0x00 TryStart1 bsf Flags, StartFlag1 ; Start pulse found retlw 0x00 ;end of pulse measuring routines ;*********************************************************************************************** ;**start of transmit routines Tran_Cmd movf Cmd_Byte,0 ;move Cmd_Byt movwf TXREG RETURN ;end of RS routines ;******************************************************************************** ;****start of delay time routines ;delay0 Trm0(8.4ms) option_reg 01010110 ;trm0b equ d'256'-d'181' delay0 btfsc IR_PORT, IR_In ; wait until Low bcf intcon,2 ;清除TMR0溢出标志位 goto $-1 movlw trm0b ;TRM0赋初值 movwf trm0 ;重新启动定时计数 loop1 btfsc IR_PORT,IR_In ;error,不是延时了6ms的低电平 goto Initilise btfss intcon,2 ;检测溢出标志位 goto loop1 bsf Flags,StartFlag return ;子程序返回 ;------------------------------------------------------------------------------- ;----delay1 to waste 1s delay1 movlw D'255' movwf counta Loop2 movlw D'255' movwf countb Loop3 decfsz countb,1 goto Loop3 decfsz counta,1 goto Loop2 return end  

 


 

 

你可能感兴趣的:(信息技术,delay,cmd,byte,编程,工作,汇编)