亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C++實現用掌上電腦遙控電視

2019-11-17 05:03:36
字體:
來源:轉載
供稿:網友
1. 簡介

  你是否曾想過通過你的掌上電腦上的IR端口控制你的TV、Hi-Fi或者其它視頻?本文將介紹怎樣使用掌上電腦中的IR端口來編程控制一臺TV。
2. 背景

  我近些日子丟失了我的老式索尼TV的遙控器。這本身沒有什么問題,因為我買了個新的遙控器作為代替。然而,當電視失去了它的設定的顏色時,我碰到了問題,因為它只能顯示黑白色了,而新的遙控器沒有顏色調整按鈕。我決定在我的老式的Jornada 525掌上電腦上寫一個程序使用IR端口把正確的代碼發送給TV。

  共有三個主要協議可以用于發送IR代碼到設備上。索尼TV使用 ’Pulse Coded’ 方法,它需要發送一個包含頭(header)位的以空格隔開的’1’位和’0’位的數據流。這些位被調制成一種40KHz的載波信號。其中,頭長度為2200 μs,’1’位為110 μs,’0’位為550 μs,而空格是550μs的沉默(silence)。大多數索尼設備使用12位數據,它被分離成6位的地址(設備類型)和6位命令。因此數據看起來象這個樣子:hxxxxxxyyyyyy,其中h是頭位,xxxxxx是6位的命令(msb first),yyyyyy是6位的地址。對此我不再細述,因為網上有很多資源描述這種協議,并列舉了針對不同設備的代碼。一些新的索尼設備使用19位代碼,我相信另外的制造商也使用和我描述的相同的格式。還有可能為使用’Space Coded’或’Shift Coded’協議的設備寫出相似的類。

  我曾使用嵌入式C++寫過一個類CirPulse,它封裝了從一臺運行Windows CE 3.0的Jornada 525 PC上控制索尼及其相匹配設備的功能。估計它能夠與其它相匹配設備和操作系統一起工作,但是你需要試驗才行!

更多文章 更多內容請看C/C++技術專題  電腦配置手冊  電腦維修專題專題,或
3. 實現過程分析

  這個CIrPulse類暴露了幾個函數,它們使得發送IR代碼盡可能輕易。在聲明CIrPulse類時,你應該調用一次FindIrPort(),它返回一個描述IrDA端口的端口號的UINT,這通過搜索注冊表得到。
這個端口號用于后面的調用來打開IrDA端口進行串行通訊。
UINT CIrPulse::FindIrPort()
{
 // 查詢注冊表中的IR端口號
 HKEY hKey = NULL;
 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("Comm/IrDA"),0, 0, &hKey) == ERROR_SUCCESS)
 {
  DWord dwType = 0;
  DWORD dwData = 0;
  DWORD dwSize = sizeof(dwData);
  if (RegQueryValueEx(hKey, _T("Port"), NULL, &dwType, (LPBYTE) &dwData, &dwSize) == ERROR_SUCCESS)
  {
   if (dwType == REG_DWORD && dwSize == sizeof(dwData))
   {
    RegCloseKey(hKey);

    return (UINT) dwData;
   }
  }
  RegCloseKey(hKey);
 }
 return 0;
}
  得到端口號后,你可以調用Open(UINT)函數,把通過調用FindIrPort()得到的端口號傳遞過去。這打開該端口并設置串口參數,假如成功返回true。該端口被設置為115200波特,8個數據位,2個停止位和奇偶校驗位。關于如何產生載波以及為什么我使用這些設置將在本文后面介紹。
BOOL CIrPulse::Open(UINT uiport)
{
 ASSERT(uiPort > 0 && uiPort <= 255);
 Close();
 //打開IRDA端口
 CString strPort;
 strPort.Format(_T("COM%d:"), uiPort);
 m_irPort = CreateFile((LPCTSTR) strPort, GENERIC_READ GENERIC_WRITE,0, NULL, OPEN_EXISTING, 0, NULL);
 if (m_irPort == INVALID_HANDLE_VALUE)
 {
  return FALSE;
 }
 //設置輸入和輸出緩沖區的大小
 VERIFY(SetupComm(m_irPort, 2048, 2048));
 //清除讀和寫緩沖區
 VERIFY(PurgeComm(m_irPort,PURGE_TXABORTPURGE_RXABORT
 PURGE_TXCLEARPURGE_RXCLEAR));
 //重新初始化所有的IRDA端口設置
 DCB dcb;
 dcb.DCBlength = sizeof(DCB);
 VERIFY(GetCommState(m_irPort, &dcb));
 dcb.BaudRate = CBR_115200;
 dcb.fBinary = TRUE;
 dcb.fParity = TRUE;
 dcb.fOutxCtsFlow = FALSE;
 dcb.fOutxDsrFlow = FALSE;
 dcb.fDtrControl = DTR_CONTROL_DISABLE;
 dcb.fDsrSensitivity = FALSE;
 dcb.fTXContinueOnXoff = FALSE;
 dcb.fOutX = FALSE;
 dcb.fInX = FALSE;
 dcb.fErrorChar = FALSE;
 dcb.fNull = FALSE;
 dcb.fRtsControl = RTS_CONTROL_DISABLE;
 dcb.fAbortOnError = FALSE;
 dcb.ByteSize = 8;
 dcb.Parity = EVENPARITY;
 dcb.StopBits = TWOSTOPBITS;
 VERIFY(SetCommState(m_irPort, &dcb));
 //為所有的讀和寫操作設置超時值
 COMMTIMEOUTS timeouts;
 VERIFY(GetCommTimeouts(m_irPort, &timeouts));
 timeouts.ReadIntervalTimeout = MAXDWORD;
 timeouts.ReadTotalTimeoutMultiplier = 0;
 timeouts.ReadTotalTimeoutConstant = 0;
 timeouts.WriteTotalTimeoutMultiplier = 0;
 timeouts.WriteTotalTimeoutConstant = 0;
 VERIFY(SetCommTimeouts(m_irPort, &timeouts));
 DWORD dwEvent=EV_TXEMPTY;
 SetCommMask(m_irPort,dwEvent);
 return TRUE;
}
更多文章 更多內容請看C/C++技術專題  電腦配置手冊  電腦維修專題專題,或
  調用函數SetCodeSize(DWORD)來設置要傳送的位數(如12位)。這可以在任何時候完成且只需要做一次。它一直保持有效,直到后面的調用改變它為止。

  最后調用SendCode(long),傳遞實際要發送的代碼。
BOOL CIrPulse::SendCode(DWORD lValue)
{
 DWORD dwCount;
 int i=0;
 ASSERT(iDataLength>0);
 //清除傳送緩沖區
 VERIFY(PurgeComm(m_irPort,PURGE_TXABORT PURGE_RXABORT PURGE_TXCLEAR PURGE_RXCLEAR));

 //每次按鍵設置代碼6次
 for(int x=0;x<6;x++) {
  MakeStream(lValue); //發送代碼
  dwCount=GetTickCount();
  while(GetTickCount()<dwCount+26) //延遲26ms
   i++;
 }
 return true;
}
  注重這個函數調用另外一個函數MakeStream(long)6次,每兩次調用之間停頓26毫秒。我發現該代碼必須發送好幾次才能使接收設備響應,大概是為防止假行為的緣故吧。26毫秒對于接收設備登記該代碼是必需的,在下一個代碼出現之前。

  這個函數MakeStream(long)把字節流寫入IrPort,并根據是否有起始位(1或者0)來確保發送正確的數據包長度。包含數據字節(0xdb)的緩沖區是以一個ByteArray形式存在的。

  函數Close()用于在端口使用后,自然地關閉IrPort。

更多文章 更多內容請看C/C++技術專題  電腦配置手冊  電腦維修專題專題,或
  這個函數在我的ornada上運行良好。請看下面的討論以進一步確定你要做的可能性改變。
BOOL CIrPulse::MakeStream(DWORD lValue) {
 DWORD dwStreamLength;
 //創建開始脈沖
 dwStreamLength=iHPulse/charWidth;
 ASSERT(Write((const char *)bPulseStream.GetData(),
 dwStreamLength)==dwStreamLength);
 // ************************************
 // ***** 在下一個脈沖到來前延遲一段時間
 // ************************************
 //循環操作代碼中的位來發送脈沖
 for(int i=0;i<iDataLength;i++) {
  if(lValue & 1) {
   //創建一個脈沖1
   dwStreamLength=i1Pulse/charWidth;
   ASSERT(Write((const char *)bPulseStream.GetData(),
   dwStreamLength)==dwStreamLength);
   // *********************************
   // ***在下一個脈沖到來前延遲一段時間
   // *********************************
  }
  else {
   //創建一個脈沖 0
   dwStreamLength=i0Pulse/charWidth;
   ASSERT(Write((const char *)bPulseStream.GetData(),
   dwStreamLength)==dwStreamLength);
   // ********************************
   // **在下一個脈沖到來前延遲一段時間
   // ********************************
  }
  lValue >>= 1;
 }
 return TRUE;
}
  我在所附源代碼中包含了一個簡單的應用程序,它使用CIrPulse來創建一臺索尼TV的遠距離遙控。它具有基本的頻道選擇、音量調整和開/關機的功能。

4. 非凡注重

  因為該CIrPort類使用一個串行端口連接到該IR端口,所以必須生成一個40KHz的載波信號,這通過從該串行端口發送恰當的字符來實現。幸好,假如我們發送字符0xdb,以115200波特,用8個數據位,2個停止位和奇偶校驗,這樣就能產生一種極接近38.4KHz的載波信號。我們所有的索尼設備接收這種數據是沒有問題的。

  最大的問題是,如何實現間隔每次脈沖的沉默周期。不可能由串行端口來產生該沉默周期,因為就算你發送一個0x0字符,由于存在起始和停止位,你仍然在該IR上得到脈沖。我通過發送不同的字符進行試驗,依據的前提是假如你不以40KHz的頻率發送一個載波信號,這有可能使設備誤把這個當作一個沉默。這樣做的優點是你可以產生一個包含完整的代碼的byteArray,以確保準確計時。但是結果并不一致,所以我拒絕使用這個方法,為的是實現在兩次從串行端口發出成組的0xdb字符之間支持暫停。因為需要的延遲是以550μs的順序;到目前為止,我還沒有找到取得獨立于處理器速度的暫停的方法。在我的Jornada上,是完全不必產生一個延遲的,因為每次調用Write函數看上去都使用了合適的時限。不管怎樣,我擔心的是,你可能胡亂產生一個可以使你的掌上電腦能工作的一個延遲。
更多文章 更多內容請看C/C++技術專題  電腦配置手冊  電腦維修專題專題,或

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲人a成www在线影院| 久久精视频免费在线久久完整在线看| 成人女保姆的销魂服务| 国产欧美一区二区三区四区| 性欧美在线看片a免费观看| 欧美大片免费观看在线观看网站推荐| 国产精品视频资源| 国产精品国产福利国产秒拍| 亚洲一级片在线看| 中文字幕视频在线免费欧美日韩综合在线看| 亚洲精品在线看| 97成人精品视频在线观看| 国产精品 欧美在线| 日韩欧美在线中文字幕| www.欧美三级电影.com| 精品久久久久久久中文字幕| 欧美韩国理论所午夜片917电影| 亚洲国产日韩欧美在线99| 久久久最新网址| 国产精品免费一区二区三区都可以| 91精品久久久久久久久青青| 久久精品电影网站| 欧美成人免费全部| 欧美一级淫片aaaaaaa视频| 91国产精品电影| 日韩中文字幕在线视频播放| 成人网在线观看| xxxx欧美18另类的高清| 欧美一级淫片丝袜脚交| 欧美亚洲视频一区二区| 色无极亚洲影院| 在线免费看av不卡| 精品偷拍一区二区三区在线看| 欧美国产高跟鞋裸体秀xxxhd| 亚洲色图18p| 亚洲人成电影网| 97免费视频在线| 亚洲成人精品久久| 亚洲午夜女主播在线直播| 成人黄色网免费| 成人www视频在线观看| 久久影院模特热| 日韩麻豆第一页| 日韩中文有码在线视频| 欧美高清视频一区二区| 欧美与欧洲交xxxx免费观看| 中文字幕精品国产| 美日韩在线视频| 欧美成人合集magnet| 亚洲国产一区自拍| 91欧美日韩一区| 久久久久国色av免费观看性色| 亚洲黄页视频免费观看| 91九色国产在线| 精品亚洲一区二区三区四区五区| 宅男66日本亚洲欧美视频| 国产精品女主播视频| 96精品视频在线| 精品欧美国产一区二区三区| 疯狂做受xxxx欧美肥白少妇| 中文字幕精品一区二区精品| 亚洲一区二区精品| 日韩综合中文字幕| 精品成人乱色一区二区| 亚洲一区二区三区视频| 91高清免费视频| 国内精久久久久久久久久人| 亚洲一级黄色片| 国产精品91在线观看| 久久久久久久激情视频| 在线播放国产一区中文字幕剧情欧美| 亚洲天堂av综合网| 成人女保姆的销魂服务| 欧美日韩人人澡狠狠躁视频| 九九热r在线视频精品| 成人黄色生活片| 亚洲色图综合久久| 久久网福利资源网站| 海角国产乱辈乱精品视频| 欧美色视频日本版| 国产精品欧美日韩久久| 日韩av网址在线| 欧美精品在线免费观看| 国自在线精品视频| 国产日韩欧美日韩大片| 日韩色av导航| 日韩视频免费看| 亚洲色图欧美制服丝袜另类第一页| 国内精品小视频在线观看| 亚洲一区二区久久久久久| 久久精品精品电影网| 91精品视频一区| 在线色欧美三级视频| 人人澡人人澡人人看欧美| 最近2019年日本中文免费字幕| 欧美一级淫片播放口| 中文字幕日韩免费视频| 中文字幕视频一区二区在线有码| 亚洲第一区中文99精品| 91在线视频精品| 国产一区二区三区在线看| 欧美日韩国产中文精品字幕自在自线| 国产精品高潮呻吟久久av无限| 欧美一级片一区| 正在播放欧美一区| 久久久精品一区| 成人在线免费观看视视频| 久久久精品免费视频| 亚洲韩国青草视频| 日韩成人av在线播放| 日本中文字幕成人| 日韩欧美亚洲范冰冰与中字| 久久人人看视频| 自拍偷拍免费精品| 日韩在线观看免费全集电视剧网站| 中文字幕日韩精品在线| 国产在线精品播放| 国产精品极品尤物在线观看| 91免费人成网站在线观看18| 国产97在线观看| 一本色道久久综合亚洲精品小说| 韩国三级电影久久久久久| 欧美午夜性色大片在线观看| 91麻豆国产语对白在线观看| 性欧美亚洲xxxx乳在线观看| 欧美精品xxx| 国产日韩在线免费| 中文日韩在线观看| 欧美激情视频网址| 欧美大秀在线观看| 国产成人精品久久二区二区| 欧美三级欧美成人高清www| 欧美精品免费在线观看| 狠狠色狠色综合曰曰| 亚洲第一区第二区| 中文字幕亚洲无线码在线一区| 欧美激情国产精品| 日韩av电影院| 精品国产依人香蕉在线精品| 欧美激情三级免费| 日韩精品高清在线| 国产欧美精品一区二区三区介绍| 精品国产欧美一区二区三区成人| 午夜精品视频网站| 18一19gay欧美视频网站| 日本久久亚洲电影| 亚洲视频在线视频| 中文字幕亚洲精品| 精品久久久久久久久中文字幕| 精品国偷自产在线视频99| 亚洲va欧美va国产综合剧情| 国产精品久久久久久久av电影| 久久的精品视频| 欧美床上激情在线观看| 国产ts一区二区| 91亚洲精品久久久| 97碰在线观看| 91成人在线播放| 成人激情在线播放| 欧美一级电影免费在线观看| 日韩精品中文字幕在线| 国产日韩欧美中文在线播放| 亚洲男人第一网站| 国产精品电影观看|