开发板鸿蒙Hi3861之俄罗斯方块 += 遥控器

系统
红外遥控器是个很实用的键盘扩展,即能扩展键盘还能远程操作!首先在我的小游戏上试一下!

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

Hi3861解码红外遥控器

红外遥控器是个很实用的键盘扩展,即能扩展键盘还能远程操作!

首先在我的小游戏上试一下!

先前发布的小游戏:https://harmonyos.51cto.com/posts/1995

视频:https://harmonyos.51cto.com/show/2063

先上图:


一、红外遥控器原理(简述)

红外遥控器是通过940nm-950nm的红外线传输的,载波频率是38K,传输协议也比较简单:


  • 首先发送一个9ms的引导码,引起接收方注意,我要发送数据了!
  • 停止4.5ms;
  • 开始发送数据(发560us停560us代表一个bit 0,发560us停1680us代表发送一个bit 1);
  • 每次传输发送4个字节 0-15是用户码(一个控制器这个码是固定的)16-23是命令码,24-31是命令码的反码,以上都是低位在前。

上图左是红外发光二极管

上图右是红外接收器(HS0038B),会自动过滤掉38K的载波留下数据信息

我压上了杜邦头可以直接插在开发板的引脚上。

二、解析原理

接收器有三个管脚(左:输出,中:电源负,右:电源正)

配置该管脚为普通输入、启用内部上拉电阻、并注册中断函数;

  1. IoSetFunc(WIFI_IOT_IO_NAME_GPIO_6, WIFI_IOT_IO_FUNC_GPIO_6_GPIO); 
  2.    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_6, WIFI_IOT_GPIO_DIR_IN); 
  3.    IoSetPull(WIFI_IOT_IO_NAME_GPIO_6, WIFI_IOT_IO_PULL_UP); 
  4.    GpioRegisterIsrFunc(WIFI_IOT_IO_NAME_GPIO_6, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, rc_decode, NULL); 

 有输出(下降沿)的时候触发中断,中断里读取us时钟;

  • 然后判断本次中断与上一次中断的时间间隔;
  • 如果在13500(9000+4500)左右,说明接收到了一个引导信号,准备接收数据;
  • 如果在1120(560+560)左右,说明接收到一个 bit 0,接收数据不变,接收序号++;
  • 如果在2240(560+1680)左右,说明接收到一个 bit 1,接收数据与上接收序号所在的位为1;
  • 如果接收序号=32说明该次接收结束
  • 判断第3个字节与第4个字节是否刚好是互补的,成功可执行命令解析执行相关操作。
  1. static void rc_decode(char *arg) 
  2.  
  3.  
  4. (void) arg; 
  5.  
  6. time_r = hi_get_us(); 
  7.  
  8. // t = 13500 
  9.  
  10. if(time_r - time_c > 13000 && time_r - time_c < 14000) 
  11.  
  12.  
  13. n = 0; 
  14.  
  15. data.Int = 0; 
  16.  
  17.  
  18. // t = 1120 
  19.  
  20. if(time_r - time_c > 920 && time_r - time_c < 1320) 
  21.  
  22.  
  23. ++n; 
  24.  
  25.  
  26. // t = 2250 
  27.  
  28. if(time_r - time_c > 2050 && time_r - time_c < 2450) 
  29.  
  30.  
  31. data.Int |= 1< 
  32.  
  33. ++n; 
  34.  
  35.  
  36. if(n == 32) 
  37.  
  38.  
  39. if ((data.Char[2] ^ data.Char[3]) == 0xff) 
  40.  
  41.  
  42. //printf("user_code:%x\tcom_code:%x\n", data.Short[0], data.Char[2]); 
  43.  
  44. switch_key(data.Char[2]); 
  45.  
  46.  
  47. data.Int = 0; 
  48.  
  49.  
  50. time_c = time_r; 
  51.  

 要获取每个按键的命令码是什么,可以直接打印到串口

  1. printf("user_code:%x\tcom_code:%x\n", data.Short[0], data.Char[2]); 

然后对不同的键码进行一个switch操作就OK了!

  1. void switch_key(unsigned char key
  2.     switch(key
  3.     { 
  4.         case 0x99: block_left();break; 
  5.         case 0xc1: block_right();break; 
  6.         case 0xca: game_stop();break; 
  7.         case 0xd2: block_down();break; 
  8.         case 0xce: block_turn();break; 
  9.     } 

 三、同时也实现了红外编码

  1. void rc_encode(unsigned user_code, unsigned com_code) 
  2.     PwmInit(PWM); 
  3.     PwmStart(PWM, 1404, 4212); 
  4.     hi_udelay(9000); 
  5.     PwmStop(PWM); 
  6.     hi_udelay(4500); 
  7.     unsigned int data = user_code | com_code<<16 | ~com_code<<24; 
  8.     for(unsigned char i=0;i<32;++i) 
  9.     { 
  10.         PwmStart(PWM, 1404, 4212); 
  11.         hi_udelay(560); 
  12.         PwmStop(PWM); 
  13.         hi_udelay((data&0x0001)==0x0001?1680:560); 
  14.         data >>= 1; 
  15.     }   
  16.     PwmStart(PWM, 1404, 4212); 
  17.     hi_udelay(560); 
  18.     PwmStop(PWM); 
  19.     hi_udelay(3000); 
  20.     PwmStart(PWM, 1404, 4212); 
  21.     hi_udelay(560); 
  22.     PwmStop(PWM); 

 编码就是解码的反操作,相关简单

  • 函数接收用户码和命令码;
  • 发送9000us的引导码,停4500us
  • 将用户码与命令码整理成一个32位的数据,方便发送;
  • 依次按位进行开关PWM进行发送;38k = (160M/4212), 1/3的占空比(4212/3=1404)
  • 32位发送完后,再发送一个结束码

发送间隔本应该用定时器进行操作,但Hi3861的定时器都是ms级的,无法完成us级延时;

开始我用usleep延时操作,发现误差有一两个数量级,根本无法使用,还好我找到了hi_udelay(),位于hi_time.h可以满足需求!

以上只是介绍最常见的红外遥控器的解码及编码!有些厂家自己定义了请多非标编码就不一一介绍了!

最近必须付上代码!!!

©著作权归作者和HarmonyOS技术社区共同所有,如需转载,请注明出处,否则将追究法律责任

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

 

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2020-12-11 12:45:04

鸿蒙Hi3861游戏

2015-01-22 15:36:46

游戏源码

2011-06-13 18:21:12

2021-01-12 12:16:55

鸿蒙HarmonyOS游戏

2014-10-08 10:04:14

代码解释俄罗斯方块

2020-02-27 13:43:14

Emacs俄罗斯方块应用

2020-05-19 17:26:21

Python俄罗斯方块游戏开发

2021-12-29 11:56:16

Linux俄罗斯方块

2014-05-26 10:07:18

Javascript俄罗斯方块

2020-10-14 09:37:03

HiBurn鸿蒙.bin文件

2015-04-28 09:21:28

JSJS俄罗斯方块游戏帝国

2016-06-13 10:21:49

二维码条形码二进制

2021-06-25 15:32:13

鸿蒙HarmonyOS应用

2009-06-08 09:59:24

谷歌俄罗斯方块版权

2020-11-06 10:15:16

HiBurn

2021-02-01 13:58:51

鸿蒙HarmonyOS应用开发

2020-12-15 11:57:49

Hi3861 HarmonyOS开发板

2020-10-30 17:42:36

鸿蒙 OS Hi386

2020-12-08 12:36:41

Hi3861 ADC驱动开发

2023-09-26 08:51:29

PygamePython语言
点赞
收藏

51CTO技术栈公众号