找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 17828|回复: 20
打印 上一主题 下一主题
收起左侧

自己写的单片机万能红外遥控解码

  [复制链接]
跳转到指定楼层
楼主
ID:102014 发表于 2016-1-6 02:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
51hei单片机论坛里流传的遥控解码程序现在都弱爆了根本解不了现在的遥控自己写个万能红外遥控解码






本程序中需要用的头文件下载:http://www.51hei.com/mcu/2564.html
//家用遥控器通用解码程序
//原理和录音机一样只不过这里录的是高低电平的脉宽,注意家用遥控器一般是38KHZ的脉冲接收头所以为了
//发射方便所以单片机使用了455MHZ晶振(旧遥控里拆一个),最好不要自己用定时器溢出来输出38KHZ的方波
//我自己试了N种中断或延时的方法都没成功,因为没有示波器也找不到究竟是神马问题最后还是靠拆一个455晶振
//才解决问题,自己家里的机顶盒和电视遥控都成功解码
  1. #include //STC12C5AxxS2系列单片机头文件
  2. #define uchar unsigned char//宏定义
  3. #define uint unsigned int//宏定义
  4. sbit Rc=P3^2;
  5. sbit LED_zs=P0^0;
  6. sbit LED_zs1=P0^1;
  7. sbit Key_s=P1^0;
  8. sbit Key_f=P1^1;
  9. sbit red=P0^2;
  10. int i=0;
  11. int TCC=0;
  12. int xdata Hdate [46];
  13. int xdata Ldate [46];
  14. ////////////////////////////////////////////////////////////////////////////////
  15. void Delay(uint ms)//延时子程序
  16. {
  17. uint x,y;
  18. for(x=ms;x>0;x--)
  19. for(y=0;y<12;y++);
  20. }

  21. ////////////////////////////////////////////////////////////////////////////////
  22. void Delay1(uint ms)//延时子程序
  23. {
  24. uint x,y;
  25. for(x=ms;x>0;x--)
  26. for(y=0;y<2400;y++);
  27. }

  28. /**********************************************************************************************/


  29. /*********************************************************************************************
  30. 函数名:定时/计数器初始化函数
  31. 调 用:T_C_init();
  32. 参 数:无
  33. 返回值:无
  34. 结 果:设置SFR中T/C1和(或)T/C0相关参数
  35. 备 注:本函数控制T/C1和T/C0,不需要使用的部分可用//屏蔽
  36. /**********************************************************************************************/
  37. void T_C_init (void){
  38. TMOD = 0x01; //高4位控制T/C1 [ GATE,C/T,M1,M0,GATE,C/T,M1,M0 ]
  39. TH0 = 0xfe; //16位计数寄存器T0高8位
  40. TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
  41. TR0 = 1; //T/C0启动开关
  42. ET0 = 1; //T/C0中断开关
  43. EA = 1; //中断总开关
  44. }
  45. /**********************************************************************************************/
  46. /*********************************************************************************************
  47. 函数名:定时/计数器0中断处理函数
  48. 调 用:[T/C0溢出后中断处理]
  49. 参 数:无
  50. 返回值:无
  51. 结 果:重新写入16位计数寄存器初始值,处理用户程序
  52. 备 注:必须允许中断并启动T/C本函数方可有效,重新写入初值需和T_C_init函数一致
  53. /**********************************************************************************************/
  54. void T_C0 (void) interrupt 1 using 1{ //切换寄存器组到1
  55. TH0 = 0xfe; //16位计数寄存器T0高8位(重新写入初值)
  56. TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
  57. //函数内容
  58. TCC++;
  59. }
  60. /**********************************************************************************************/

  61. /*********************************************************************************************
  62. 函数名:UART串口初始化函数
  63. 调 用:UART_init();
  64. 参 数:无
  65. 返回值:无
  66. 结 果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用)
  67. 备 注:振荡晶体为12MHz,PC串口端设置 [ 4800,8,无,1,无 ]
  68. /**********************************************************************************************/
  69. void UART_init (void){
  70. //EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
  71. //ES = 1; //允许UART串口的中断

  72. TMOD = 0x20; //定时器T/C1工作方式2
  73. SCON = 0x50; //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)
  74. TH1 = 0xF3; //定时器初值高8位设置
  75. TL1 = 0xF3; //定时器初值低8位设置
  76. PCON = 0x80; //波特率倍频(屏蔽本句波特率为2400)
  77. TR1 = 1; //定时器启动
  78. }


  79. /**********************************************************************************************/
  80. /*********************************************************************************************
  81. 函数名:外部中断INT初始化函数
  82. 调 用:INT_init();
  83. 参 数:无
  84. 返回值:无
  85. 结 果:启动外部中断INT1、INT0中断,设置中断方式
  86. 备 注:
  87. /**********************************************************************************************/
  88. void INT_init (void){
  89. EA = 1; //中断总开关
  90. //EX0 = 1; //允许外部中断0中断
  91. IT0 = 1; //1:下沿触发 0:低电平触发
  92. }

  93. void INT_0 (void) interrupt 0 using 2{ //切换寄存器组到2
  94. EX0 = 0; //允许外部中断0中断
  95. //用户函数内容
  96. for(i=0;i<46;i++)
  97. {
  98. //获取低电平宽度
  99. TH0 = 0xfe; //16位计数寄存器T0高8位
  100. TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
  101. TCC=0;
  102. TR0 = 1; //T/C0启动开关
  103. while(Rc==0);
  104. TR0=0;
  105. Ldate[i]=TCC;

  106. //获取高电平宽度
  107. TH0 = 0xfe; //16位计数寄存器T0高8位
  108. TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
  109. TCC=0;
  110. TR0 = 1; //T/C0启动开关
  111. while(Rc==1);
  112. TR0=0;
  113. Hdate[i]=TCC;
  114. }

  115. LED_zs=0;
  116. Delay1(100);
  117. LED_zs=1;
  118. Delay1(100);
  119. LED_zs=1;
  120. Delay1(300);
  121. LED_zs1=0;

  122. }

  123. void fs(void)
  124. {
  125. int fs;
  126. for(fs=0;fs<46;fs++)
  127. {
  128. TH0 = 0xfe; //16位计数寄存器T0高8位
  129. TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
  130. TCC=0;
  131. TR0 = 1; //T/C0启动开关
  132. while(TCC<Ldate[fs]){red=!red;}
  133. TR0=0;
  134. TH0 = 0xfe; //16位计数寄存器T0高8位
  135. TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
  136. TCC=0;
  137. TR0 = 1; //T/C0启动开关
  138. while(TCC<Hdate[fs]){red=0;}
  139. TR0=0;
  140. }

  141. void main (void){

  142. int n;
  143. IP=0x02;
  144. T_C_init();
  145. INT_init();
  146. UART_init();
  147. LED_zs=1;
  148. LED_zs1=0;
  149. red=0;
  150. while(1)
  151. {
  152. Key_f=1;
  153. if( Key_f!=1)
  154. {
  155. Delay1(2);
  156. Key_f=1;
  157. if(Key_f!=1)
  158. {
  159. for(n=0;n<46;n++)
  160. {
  161. SBUF = Ldate[n]; //将接收的数据发送回去
  162. while(TI == 0); //检查发送中断标志位
  163. TI = 0;
  164. }
  165. for(n=0;n<46;n++)
  166. {
  167. SBUF = Hdate[n]; //将接收的数据发送回去
  168. while(TI == 0); //检查发送中断标志位
  169. TI = 0;
  170. }
  171. while(!Key_f){fs();Delay1(100);}
  172. }
  173. }
  174. Key_s=1;
  175. if(Key_s!=1)
  176. {
  177. Delay1(2);
  178. if(Key_s!=1)
  179. {
  180. EX0=1;
  181. LED_zs1=1;
  182. while(!Key_s);
  183. }
  184. }

  185. }
复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏9 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:102014 发表于 2016-1-6 02:52 | 只看该作者
有朋友问我:你那画红线那是怎么回事,我也想读懂那些十六进制码。

解答:是单片机发过来的遥控解码数据串的开头,第一个字节表示红外接收头低电平脉冲的宽度,第二个字节表示红外接收头高电平脉冲的宽度,后面依此类推,基数单位是:1000000÷(晶振频率÷12)×定时器溢出率 us 试的时候注意定时器溢出时间的长度,太长了误差大,太短了可能计数的变量会溢出误差更大,我怕RAM不够先是用的char类型,结果有的遥控脉冲宽度太长导致变量溢出了,后来改用int类型才基本能应对手上所有的遥控,自己慢慢找平衡点
回复

使用道具 举报

板凳
ID:79544 发表于 2016-1-6 20:30 | 只看该作者
51黑黑 发表于 2016-1-6 02:52
有朋友问我:你那画红线那是怎么回事,我也想读懂那些十六进制码。

解答:是单片机发过来的遥控解码数据 ...

楼主怎么编译不通过啊
回复

使用道具 举报

地板
ID:8625 发表于 2016-1-6 23:04 来自手机 | 只看该作者
楼主这个不解码,只复制波形真正的万能型,顶
回复

使用道具 举报

5#
ID:46943 发表于 2016-1-7 11:04 | 只看该作者
这个好,正好在学
回复

使用道具 举报

6#
ID:67573 发表于 2016-1-8 16:54 | 只看该作者
楼主这个不解码,只复制波形真正的万能型,顶
回复

使用道具 举报

7#
ID:136767 发表于 2016-9-6 23:44 来自手机 | 只看该作者
那不是两个下降沿之间的时间吗,怎么就变成高低电平的持续时间了呢
回复

使用道具 举报

8#
ID:130816 发表于 2016-9-7 06:15 | 只看该作者
帮楼主纠正一下是455KHZ晶振
回复

使用道具 举报

9#
ID:166104 发表于 2017-2-23 09:33 | 只看该作者
只复制波形真正的万能型,顶
回复

使用道具 举报

10#
ID:169914 发表于 2017-4-30 00:32 | 只看该作者
我的也不行,式了好多种方法了。。。话说455M也好455K也罢都超出时钟界限了啊,为什么还能用呢
回复

使用道具 举报

11#
ID:193423 发表于 2017-4-30 10:11 | 只看该作者
分析的很详细
回复

使用道具 举报

12#
ID:47286 发表于 2017-4-30 13:45 | 只看该作者
感谢楼主分项 能给个电路图么 端口定义没电路图也没标注 没看懂干嘛的
回复

使用道具 举报

13#
ID:66287 发表于 2017-5-9 11:08 | 只看该作者
楼主方法新颖,赞一个!
回复

使用道具 举报

14#
ID:48994 发表于 2017-5-27 17:05 | 只看该作者
楼主你好,能发一下配套的原理图吗?还有代码编译不过啊。
回复

使用道具 举报

15#
ID:152715 发表于 2017-12-24 22:09 | 只看该作者
不错,学习
回复

使用道具 举报

16#
ID:274452 发表于 2018-1-10 18:28 | 只看该作者

不错,学习
回复

使用道具 举报

17#
ID:272625 发表于 2018-2-23 10:57 | 只看该作者
/****************************************************
            家用遥控器通用解码程序
原理和录音机一样只不过这里录的是高低电平的脉宽,注意家用遥控器一般是38KHZ的脉冲接收头所以为了
发射方便所以单片机使用了455KHZ晶振(旧遥控里拆一个),最好不要自己用定时器溢出来输出38KHZ的方波
我自己试了N种中断或延时的方法都没成功,因为没有示波器也找不到究竟是神马问题最后还是靠拆一个455晶振  
才解决问题,自己家里的机顶盒和电视遥控都成功解码  
*****************************************************/
#include"STC12C5A60S2.H"//STC12C5AxxS2系列单片机头文件
#define uchar unsigned char//宏定义
#define uint unsigned int//宏定义

sbit Rc=P3^2;
sbit LED_zs=P0^0;
sbit LED_zs1=P0^1;
sbit Key_s=P1^0;
sbit Key_f=P1^1;
sbit red=P0^2;

int i=0;
int TCC=0;
int xdata Hdate [46];
int xdata Ldate [46];
////////////////////////////////////////////////////////////////////////////////
void Delay(uint ms)//延时子程序
{
uint x,y;
for(x=ms;x>0;x--)
for(y=0;y<12;y++);
}

////////////////////////////////////////////////////////////////////////////////
void Delay1(uint ms)//延时子程序
{
uint x,y;
for(x=ms;x>0;x--)
for(y=0;y<2400;y++);
}

/**********************************************************************************************/


/*********************************************************************************************
函数名:定时/计数器初始化函数
调 用:T_C_init();
参 数:无
返回值:无
结 果:设置SFR中T/C1和(或)T/C0相关参数
备 注:本函数控制T/C1和T/C0,不需要使用的部分可用//屏蔽
/**********************************************************************************************/
void T_C_init (void){
TMOD = 0x01; //高4位控制T/C1 [ GATE,C/T,M1,M0,GATE,C/T,M1,M0 ]
TH0 = 0xfe; //16位计数寄存器T0高8位
TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
TR0 = 1; //T/C0启动开关
ET0 = 1; //T/C0中断开关
EA = 1; //中断总开关
}
/**********************************************************************************************/
/*********************************************************************************************
函数名:定时/计数器0中断处理函数
调 用:[T/C0溢出后中断处理]
参 数:无
返回值:无
结 果:重新写入16位计数寄存器初始值,处理用户程序
备 注:必须允许中断并启动T/C本函数方可有效,重新写入初值需和T_C_init函数一致
/**********************************************************************************************/
void T_C0 (void) interrupt 1 using 1{ //切换寄存器组到1
TH0 = 0xfe; //16位计数寄存器T0高8位(重新写入初值)
TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
//函数内容
TCC++;
}
/**********************************************************************************************/

/*********************************************************************************************
函数名:UART串口初始化函数
调 用:UART_init();
参 数:无
返回值:无
结 果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用)
备 注:振荡晶体为12MHz,PC串口端设置 [ 4800,8,无,1,无 ]
/**********************************************************************************************/
void UART_init (void){
//EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
//ES = 1; //允许UART串口的中断

TMOD = 0x20; //定时器T/C1工作方式2
SCON = 0x50; //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)
TH1 = 0xF3; //定时器初值高8位设置
TL1 = 0xF3; //定时器初值低8位设置
PCON = 0x80; //波特率倍频(屏蔽本句波特率为2400)
TR1 = 1; //定时器启动
}


/**********************************************************************************************/
/*********************************************************************************************
函数名:外部中断INT初始化函数
调 用:INT_init();
参 数:无
返回值:无
结 果:启动外部中断INT1、INT0中断,设置中断方式
备 注:
/**********************************************************************************************/
void INT_init (void){
EA = 1; //中断总开关
//EX0 = 1; //允许外部中断0中断
IT0 = 1; //1:下沿触发 0:低电平触发
}

void INT_0 (void) interrupt 0 using 2{ //切换寄存器组到2
EX0 = 0; //允许外部中断0中断
//用户函数内容
for(i=0;i<46;i++)
{
//获取低电平宽度
TH0 = 0xfe; //16位计数寄存器T0高8位
TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
TCC=0;
TR0 = 1; //T/C0启动开关
while(Rc==0);
TR0=0;
Ldate[i]=TCC;

//获取高电平宽度
TH0 = 0xfe; //16位计数寄存器T0高8位
TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
TCC=0;
TR0 = 1; //T/C0启动开关
while(Rc==1);
TR0=0;
Hdate[i]=TCC;
}

LED_zs=0;
Delay1(100);
LED_zs=1;
Delay1(100);
LED_zs=1;
Delay1(300);
LED_zs1=0;

}

void fs(void)
{
int fs;
for(fs=0;fs<46;fs++)
{
TH0 = 0xfe; //16位计数寄存器T0高8位
TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
TCC=0;
TR0 = 1; //T/C0启动开关
while(TCC<Ldate[fs]){red=!red;}
TR0=0;
TH0 = 0xfe; //16位计数寄存器T0高8位
TL0 = 0x0c; //16位计数寄存器T0低8位(100uS延时)
TCC=0;
TR0 = 1; //T/C0启动开关
while(TCC<Hdate[fs]){red=0;}
TR0=0;
}
}
void main (void){

int n;
IP=0x02;
T_C_init();
INT_init();
UART_init();
LED_zs=1;
LED_zs1=0;
red=0;
while(1)
{
Key_f=1;
if( Key_f!=1)
{
Delay1(2);
Key_f=1;
if(Key_f!=1)
{
for(n=0;n<46;n++)
{
SBUF = Ldate[n]; //将接收的数据发送回去
while(TI == 0); //检查发送中断标志位
TI = 0;
}
for(n=0;n<46;n++)
{
SBUF = Hdate[n]; //将接收的数据发送回去
while(TI == 0); //检查发送中断标志位
TI = 0;
}
while(!Key_f){fs();Delay1(100);}
}
}
Key_s=1;
if(Key_s!=1)
{
Delay1(2);
if(Key_s!=1)
{
EX0=1;
LED_zs1=1;
while(!Key_s);
}
}
}
}
回复

使用道具 举报

18#
ID:272625 发表于 2018-2-23 10:58 | 只看该作者
不知道端口定义,不会用!
回复

使用道具 举报

19#
ID:284994 发表于 2018-2-23 16:05 | 只看该作者
学习中
回复

使用道具 举报

20#
ID:189909 发表于 2018-4-7 17:00 | 只看该作者
楼主  发送函数中while(TCC<Ldate[fs]){red=!red;}这个是什么意思啊?TCC<Ldate[fs]这句话不能理解啊好像是不成立

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

21#
ID:259955 发表于 2019-8-5 10:58 | 只看该作者
遥控器按键值破解,开、关机按键值都为0x707030CF ,就只能关机不能开机。这是怎么一回事 ? 。。。。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表