自制电脑红外遥控接收器.doc_第1页
自制电脑红外遥控接收器.doc_第2页
自制电脑红外遥控接收器.doc_第3页
自制电脑红外遥控接收器.doc_第4页
自制电脑红外遥控接收器.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、自制电脑红外遥控接收器(PC软解码) 收藏 此文于20091014被推荐到CSDN首页如何被推荐?网上有很多介绍红外遥控接收器制作的文章,但其中大部分是用单片进行红外解码,然后再通过串口或USB把解码后的按键信息传入到PC的。这样的电路制作起来,不仅造价相对偏高,而且需要对单片编程,这会令大部分软件开发爱好者望而却步.最近看到一篇仅需要7个简单元器件的红外接收器,只需拿起烙铁,不需硬件编程就可以制作完成,原理图如下: 由原理图我们可知,红外接收头把接收的红外信号转换为高低电平通过串口的DSR管脚传入到PC,PC软件通过对DSR高低电平信号的时间曲线进行分析,从而获得相对应的按键信息.

2、红外遥控器一般采用脉宽调制的串行码,经38kHz的载频把红外信号发射出去。其编码信息一般由三部分组成:引导码、地址码和数据码。一般信号长度大约100ms左右,持续按键则重复发送(中间会有10ms以上的间歇).常态下,红外接收头的输出(OUT)都是高电平,引导码信号首先会令红外接收头输出一个大约10ms左右的低电平(不同遥控器有不同的时延),这可令接收设备从容判定信号的到来,而后面的地址码和数据码其电平高低变化就相对较快了,大概在几十或几百个微秒之间。PC红外遥控软件一般选用Girder,在使用之前需要安装“SFH56 plugin for Girder”这个插件(文件名”igor SFH56P

3、 lug。dll"),否则不能正常处理我们这种电路的红外接收器信号。可悲的是我至今没找到这个插件,网上提供的很多链接都是坏的.即使找到了这个插件,要想在我们自己编写的程序中使用也是困难的,因为Girder并没有为我们开发者提供API接口。既然Girder能用软件实现红外解码,我们为什么不能呢?凡事都要开动大脑,积极行动才对,下面就是我自己焊接的一个红外接收器(元器件是在中发买的,一共不到10元钱,还富裕好多电阻、电容!) (图下方的红外遥控器的接收器是基于USB的,仅支持Vista以上版本,并且不支持个人开发,不过今天它终于发挥了它应有的作用。当然用电视或VCD遥控器也是可

4、以的)硬件有了,但程序该从何编起呢?1、由于接收到的红外信号在微秒级别中变化,对系统实时性要求较高,所以具备垃圾回收功能,实时性没有保证的C,似乎完不成这种信号的接收功能,所以我们选择的是VC,由它实现高优先级的线程去进行信号接收.2、由于红外遥控信号是脉宽调制的串行码,所以我们需要采集信号的宽度,显然采用一般的时钟函数来获取时间间隔是不可行的,因为精度太低,所以我们需用采用多媒体时钟和高精度计时的API函数.3、一般我们按键持续时间为几秒钟,并且由于按键发出前有一个10ms左右的引导信号,所以我们的程序很容易判断出信号起始点,这样我们一次仅需要接收一定量的原始数据就可以完成初步信号采集工作。

5、4、对于我们的红外接收程序来说并不需要实际解码出红外信号到底包含了那些具体的信息,只要其能够区分出红外遥控上的各个按键就行。5、由于红接收器是通过串口RTS管脚供电,且通过DSR传递红外信号的,所以我们的程序即使不接收数据,也要打开串口,不过仅需要处理RTS和DSR管脚的信号即可。好了,动手去做,下面是用VC实现的一个DLL,其功能就是接收并记录红外信号的持续时间。核心代码如下:DWORD WINAPI ThreadProc(LPVOID pParam)         LARGE_INTEGER litmp; &

6、#160;        LONGLONG QPart1,QPart2;          double dfFreq;    int iTime=0;  /微秒          / 获得计数器的时钟频率          QueryPe

7、rformanceFrequency(&litmp);          dfFreq = (double)1000000。0/litmp.QuadPart;                      DWORD ModemState,oldModemState=MS_DSR_ON;   &

8、#160;              /EV_BREAK or EV_CTS or EV_DSR or EV_ERR or EV_RING or EV_RLSD or EV_RXCHAR or EV_RXFLAG or EV_TXEMPTY         /SetCommMask(HSC_COM_Handle,EV_DSR);      

9、;   /DWORD EvtMask,dwError;         /COMSTAT cs;            while(HSC_Thread_RunFlag)                    

10、        /等待DSR信号发生变化        /WaitCommEvent(HSC_COM_Handle,EvtMask,HSC_Ovread);             /ClearCommError(HSC_COM_Handle,dwError,cs);       

11、;             /获得DSR的状态                   GetCommModemStatus(HSC_COM_Handle,&ModemState);         

12、60;         ModemState = (ModemState MS_DSR_ON);                                     

13、  if(ModemState = oldModemState)  continue;                   oldModemState=ModemState;              /清计数      

14、;             InterlockedExchange(HSC_NUM,0);                           /开始接收数据       

15、;            if(HSC_State = 0 && ModemState = 0)                                &#

16、160;        QueryPerformanceCounter(litmp);                 QPart1 = litmp.QuadPart;             HSC_State=1;      

17、                 /复位计数                      InterlockedExchange(&HSC_NUM,0);       

18、60;   InterlockedExchange(HSC_Index,0);                       /开启定时器                    &#

19、160; HSC_TimerID = timeSetEvent(10,HSC_Accuracy,MMTimer,NULL,TIME_PERIODIC);                       continue;              

20、60;                        /接收数据状态                   if(HSC_State = 1)     

21、                           QueryPerformanceCounter(litmp);                      

22、  QPart2 = litmp.QuadPart;                             /                 &#

23、160;          if(ModemState = 0)                                      

24、                                iTime = (int)(QPart2-QPart1)*dfFreq);             

25、60;                                          else        

26、60;                                  iTime = (int)((QPart1QPart2)dfFreq);           &

27、#160;                                             if(HSC_Index HSC_BufferSize) &

28、#160;                                   (HSC_Buffer+HSC_Index) = iTime;          

29、;                                              InterlockedIncrement(&HSC_Ind

30、ex);            /-            QPart1=QPart2;                         &

31、#160;       return STILL_ACTIVE;如果采用WaitCommEvent函数,你会发现CPU使用时间会很低,不过它会让接收程序无法正常退出,所以只好注释掉该函数了,此时你会发现CPU使用时间会很高。原始数据一旦采集完毕,剩下的就由C程序大显身手吧。C#中DLL的接口函数如下:     const string DllPath = ”YFHSCollect。dll";     DllImport(DllPath) 

32、0;   public static extern Int32 HSCStart(Int32 COM, Int32 delay, Int32 BufferSize);     DllImport(DllPath)     public static extern Int32 HSCEnd();     DllImport(DllPath) public static extern Int32 HSCData(int intData);我封装了一个

33、类,一旦有按键信息,就会触发一个Click事件.此外程序还具备自学习功能,并且可以把学习后的结果序列化到一个XML文件中去,这样下次再按键就可以识别出键名了。主程序中测试代码如下:public partial class frmMain : Form            YFHWCollect hw =null;        int hwData = null;     &

34、#160;   public frmMain()                    InitializeComponent();            hw = new YFHWCollect(this, 1);      &

35、#160;     hw.Click += new YFHWCollect.HWEventHandler(hw_Click);                 void hw_Click(object sender, HWEventArgs e)              

36、60;     string strInfo = ""            for (int i = 0; i < e.lstData。Count; i+)                       

37、     for (int j = 0; j e。lstDatai.Length; j+)                                    strInfo += e。lstDataij.ToStri

38、ng() + ” "                                strInfo += "rn”;              

39、60;         txtInfo.Text = strInfo;            lblKeyName。Text = e。KeyName+ ” (" + (e.Interval /10)。ToString() + ”ms)"            hwData = e

40、。Data;            picBar。Refresh();                private void btnCommand_Click(object sender, EventArgs e)            

41、        if (btnCommand.Text = ”开始")                            btnCommand.Text = "停止”;      

42、60;         hw。Start();                        else                 &#

43、160;          btnCommand.Text = ”开始”;                hw.End();                     &#

44、160;       private void btnStudy_Click(object sender, EventArgs e)                    hw.Study(txtKeyName。Text);            &

45、#160;    private void picBar_Paint(object sender, PaintEventArgs e)                    int width = picBar.Width, height = picBar.Height;          

46、;  e.Graphics.DrawLine(new Pen(Color.Gray), 0, height / 2, width, height / 2);             if (hwData != null)                     

47、0;      float Len=0;                foreach(int l in hwData)                        &

48、#160;          Len+=l;                                float dx = width / Len,DX=0;                Pen p = new Pen(Color。Green);                float Y=0, Y1=height/4,Y2=(float)(height*3.0/4.0);    &

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论