找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

使用P87LPC762单片机处理红外控制信号

[复制链接]
admin 发表于 2010-5-24 23:18:06 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
Philips公司推出的51LPC系列单片机P87LPC762具有速度快可靠性高的特点在相同工作频率下指令处理速度
是标准51的两倍内建的看门狗可以有效防止程序飞跑该系列单片机的详细情况可到http://www.zlgmcu.com/查询这
里详细介绍它在红外控制中的一个应用
红外控制系统中的红外发送电路采用NB9148它是用作通用红外遥控发射器的CMOS大规模集成电路与NB9149
相配可完成10个功能控制与NB9150相配可完成18个功能控制可发射的指令达75个其中63个是连续指令可多
键组合12个是单发指令只能单键使用
一NB9148简介
1主要特点
源电压范围较宽2.2V-5.5V
MOS工艺保证了极低的功耗
多键组合
围元件少
位与其它模式兼容
需外接LC或陶瓷振荡器即产生振荡
2内部结构如下图所示
未命名.jpg
3电路外形图如下
未命名.jpg
4极限参数表Ta=25摄氏度)
未命名.jpg
5电参数表(VDD=3V,Ta=25,另有说明外)
未命名.jpg
6各管脚功能描述
未命名.jpg
未命名.jpg
7内部结构主要部分功能描述
振荡电路
内含CMOS反相器及自偏置电阻外接陶瓷振荡器或LC串联谐振回路即可组成振荡器当振荡频率设定为455kHz时则
发射载波频率为38kHz只有当按键操作时才会产生振荡以此降低功耗
键输入
通过K1~K6输入和T1~T3的时序输出可连接6 3键盘矩阵在T1这一列内的6个键图中1~6号键可以任意多键组合
成63个状态输出连续发射处于T2和T3这两列的键图中7~18号键均只能单键使用且每按一次只能发射一组控
制脉冲若一列上的数键同时按下其优先次序为K1 K2 K3 K4 K5 K6在同一K线上的键无多键功能若同时按
下数键其优先次序为T1 T2 T3
未命名.jpg
8典型应用线路如下
未命名.jpg
9发送命令格式
发送命令由12位码组成其中C1-C3是用户码用来确定不同的模式每种组合有三个状态01 10和11而00
状态
不用H S1和S2是代表连续发送或单次发送的码D1~D6是发送的数据码
未命名.jpg
10键与码的关系
未命名.jpg
11发送波形
(1)0与1的识别
正脉冲的占空比为1/4时代表0正脉冲的占空比为3/4时代表1
未命名.jpg
(2)载波
无论是0还是1它们被发射时正脉冲是被调制在38kHz振荡频率为455kHz时的载波上载波的占空
比为1/3这样有利于减小功耗
未命名.jpg
(3)基本发送波形
每个发送周期按C1 C2 C3 H S1 S2 D1 D2 D3 D4 D5 D6的次序串行发送总长度为48a其中a
等于每个码周期的1/4其计算方法是a=1/fosc 192秒
未命名.jpg
(4)单发信号
凡是按下单发键时输出码只发送两个周期
未命名.jpg
二接收处理电路
控制系统不采用与其配套的接收电路采用通用的红外接受器接受到调制后的方波脉冲序列然后由P87LPC762处
理并进行相应的控制这种方案与采用配套电路的方案相比具有成本低处理灵活多变实时控制性能佳等的诸多优点
P87LPC762的电源采用5V由一个红外接受器接受到由NB9148发出的经过检波去除38kHz载波后的高电平为5V
的方波信号下面是一个三端通用红外接受器的内部线路示意图内部包含对接收信号进行整形的斯密特触发器
未命名.jpg
输出信号送到单片机的INT1输入口由P87LPC762解码并实施相应的操作
未命名.jpg
接受信号编码的判断根据9148的编码规则从编码表中可以看出接受到的12位编码中最后6位只有一个1每个循
环组成一个编码组这样每组有6个指令码第一组1 6是连续发送的编码7 12是第一组单发编码13 18则是第
二组单发编码具体实施控制的其它外围电路可以根据大家的需要自己添加下面介绍P87LPC762中的C51处理程序
可在Keil C51 6.0以上版本中编译晶振采用11.0592Mc工作在每个机器周期6时钟的快速状态
  1. #include<REG768.H>/*Philips 87LPC768寄存器定义头文件*/
  2. #define REDINT 0x06/*红外线间隔*/
  3. /*存放消息标志的可位寻址字节Message,Message=NULL时无任消息*/
  4. unsigned char bdata Message;
  5. /*在接收过程中置位,检测标置位Get可以有效防止其它进程干扰接收,防止数据丢失.*/
  6. sbit RedMsg=Message^0;/*红外遥控消息*/
  7. sbit RedRead=Message^1;/*位接收过程标志*/
  8. sbit RedBit=Message^2;/*接收到的位值*/
  9. sbit RSend=Message^3;/*红外接收中重新发送标志*/
  10. /*存放遥控的字数据,低4位存放接收到的bit的位移,高12位从低到高存放接收到的bit*/
  11. unsigned char bdata RedDataL,RedDataH;
  12. /*RedDataH字节低6位代表指令只有一个1 C1-C3是用户码H表示连续S1 S2分别表示第一二组单发*/
  13. sbit RedData0=RedDataL^4;/*C1*/
  14. sbit RedData1=RedDataL^5;/*C2*/
  15. sbit RedData2=RedDataL^6;/*C3*/
  16. sbit RedData3=RedDataL^7;/*H*/
  17. sbit RedData11=RedDataH^0;/*D6*/
  18. sbit RedData10=RedDataH^1;/*D5*/
  19. sbit RedData9=RedDataH^2;/*D4*/
  20. sbit RedData8=RedDataH^3;/*D3*/
  21. sbit RedData7=RedDataH^4;/*D2*/
  22. sbit RedData6=RedDataH^5;/*D1*/
  23. sbit RedData5=RedDataH^6;/*S2*/
  24. sbit RedData4=RedDataH^7;/*S1*/
  25. unsigned char bdata State;/*状态字节*/
  26. sbit RedControl=State^6;/*遥控状态*/
  27. /*定时器T00的高位定时参数为Timer定时256*Timer+(80--336)个周期共139Timer+(43--182)us<37ms定时器T01
  28. 的高位定时节参数为nTimer定时256*nTimer+(24--280)个周期139nTimer+(13--152)us<9.1s,RedCon存放红外接收时的载
  29. 波计数*/
  30. unsigned char data RedCon,Timer;
  31. unsigned int nTimer;/*定时整型参数*/
  32. void main()
  33. {
  34. IEN0=0x14;/*只打开INT1中断*/
  35. WDRST=0x1E;/*看门狗清0*/
  36. WDRST=0xE1;
  37. WDCON=0x12;/*40-90ms看门狗(>最大延时37ms)*/
  38. TCON=0x40;/*定时器1开始工作,INT1低电平触发*/
  39. TMOD=0x23;/*定时器0扩展成两个8位定时器T00和T01用于同步控制*/
  40. if((WDCON&0x30)!=0x30){/*看门狗陷阱复位时无需初始化*/
  41. Message=0;/*无消息*/
  42. State=0;/*正常复位无任何状态*/
  43. }
  44. while(1){/*消息循环*/
  45. WDRST=0x1E;/*看门狗清0*/
  46. WDRST=0xE1;
  47. EX1=RedControl;/*设置遥控中断INT1*/
  48. if(RedMsg){/*执行遥控指令*/
  49. EX1=0;/*在指令没有处理完之前不能重复中断*/
  50. switch(RedDataH){/*这里加入红外指令的控制过程*/
  51. case 0x82:/*Channel 1*/
  52. break;
  53. case 0xA0:/*Channel 2*/
  54. break;
  55. /*……*/
  56. }
  57. EX1=1;
  58. RedDataL=0;/*复位红外数据*/
  59. RedDataH=0;/*复位红外数据*/
  60. RedMsg=0;}/*复位红外遥控消息*/
  61. }
  62. }
  63. void Count0(void)interrupt 1 using 3
  64. {/*定时器T00中断,最大定时37ms*/
  65. if(Timer!=0){/*检测定时器T00的扩展高位*/
  66. Timer--;
  67. return;}
  68. }
  69. /*INT1用于红外解码状态遥控解码数据处理,nTimer=1定时152--291us*/
  70. void Inte1()interrupt 2 using 2
  71. {
  72. for(nTimer=8;nTimer>1;nTimer--);/*使处理周期达到51机器周期=27.7us使得RedCon<32*/
  73. if(RedRead)RedCon++;/*0信号宽度a=420us,1信号宽度a=1260us,周期4a=1680us*/
  74. else{/*开始计数或者重新发送时开始计数*/
  75. RedBit=0;/*复位接收位*/
  76. RedCon=0;/*复位载波计数*/
  77. RedRead=1;/*置位位接收标志*/
  78. if(!ET1){/*首次接收时没有启动定时器T01接收第一个位*/
  79. TF1=0;/*复位定时器T01益出标志*/
  80. ET1=1;/*启动T01定时*/
  81. RedDataL=0;/*复位红外数据*/
  82. RedDataH=0;/*复位红外数据*/
  83. RSend=0;}/*复位重新发送标志*/
  84. }
  85. }
  86. void Count1(void)interrupt 3 using 3
  87. {/*定时器T01中断,最大定时9.1s*/
  88. if(nTimer!=0){/*检测定时器T01的扩展高位*/
  89. nTimer--;
  90. return;}
  91. ET1=0;/*关闭T01定时*/
  92. if(RedRead){/*红外接收状态*/
  93. if((RedDataL&0xF)==12){/*第一阶段接收已经结束*/
  94. RSend=1;/*置位重新发送标志以便校验*/
  95. RedDataL&=0xF0;}/*复位位指针以便校验*/
  96. if(RedCon>27-REDINT&&RedCon<27+REDINT)RedBit=1;
  97. else RedBit=0;/*低电平计数9表示0 27表示1*/
  98. if(RSend){/*检验重复发送的数据是否与第一次符合*/
  99. switch(RedDataL&0xF){
  100. case 0:/*检验重复发送的第1位数据*/
  101. if(RedBit!=RedData0)goto RClear;
  102. break;
  103. case 1:/*检验重复发送的第2位数据*/
  104. if(RedBit!=RedData1)goto RClear;
  105. break;
  106. case 2:/*检验重复发送的第3位数据*/
  107. if(RedBit!=RedData2)goto RClear;
  108. break;
  109. case 3:/*检验重复发送的第4位数据*/
  110. if(RedBit!=RedData3)goto RClear;
  111. break;
  112. case 4:/*检验重复发送的第5位数据*/
  113. if(RedBit!=RedData4)goto RClear;
  114. break;
  115. case 5:/*检验重复发送的第6位数据*/
  116. if(RedBit!=RedData5)goto RClear;
  117. break;
  118. case 6:/*检验重复发送的第7位数据*/
  119. if(RedBit!=RedData6)goto RClear;
  120. break;
  121. case 7:/*检验重复发送的第8位数据*/
  122. if(RedBit!=RedData7)goto RClear;
  123. break;
  124. case 8:/*检验重复发送的第9位数据*/
  125. if(RedBit!=RedData8)goto RClear;
  126. break;
  127. case 9:/*检验重复发送的第10位数据*/
  128. if(RedBit!=RedData9)goto RClear;
  129. break;
  130. case 10:/*检验重复发送的第11位数据*/
  131. if(RedBit!=RedData10)goto RClear;
  132. break;
  133. case 11:/*检验重复发送的第12位数据*/
  134. if(RedBit!=RedData11)goto RClear;
  135. RedMsg=1;/*接受到经过检验正确的编码后置位遥控消息*/
  136. RedBit=0;/*复位接收位*/
  137. RSend=0;/*复位重新发送标志*/
  138. RedRead=0;/*复位接收过程标志*/
  139. RedCon=0;/*复位载波计数*/
  140. return;
  141. default:/*重复发送的数据多于12位时判断为错误*/
  142. goto RClear;
  143. }
  144. }
  145. else{
  146. switch(RedDataL&0xF){
  147. case 0:/*保存首次发送的第1位数据*/
  148. RedData0=RedBit;
  149. break;
  150. case 1:/*保存首次发送的第2位数据*/
  151. RedData1=RedBit;
  152. break;
  153. case 2:/*保存首次发送的第3位数据*/
  154. RedData2=RedBit;
  155. break;
  156. case 3:/*保存首次发送的第4位数据*/
  157. RedData3=RedBit;
  158. break;
  159. case 4:/*保存首次发送的第5位数据*/
  160. RedData4=RedBit;
  161. break;
  162. case 5:/*保存首次发送的第6位数据*/
  163. RedData5=RedBit;
  164. break;
  165. case 6:/*保存首次发送的第7位数据*/
  166. RedData6=RedBit;
  167. break;
  168. case 7:/*保存首次发送的第8位数据*/
  169. RedData7=RedBit;
  170. break;
  171. case 8:/*保存首次发送的第9位数据*/
  172. RedData8=RedBit;
  173. break;
  174. case 9:/*保存首次发送的第10位数据*/
  175. RedData9=RedBit;
  176. break;
  177. case 10:/*保存首次发送的第11位数据*/
  178. RedData10=RedBit;
  179. break;
  180. case 11:/*保存首次发送的第12位数据*/
  181. RedData11=RedBit;
  182. break;
  183. default:/*首次发送的数据多于12位时判断为错误*/
  184. goto RClear;
  185. }
  186. }
  187. RedDataL++;/*位位移加1*/
  188. RedBit=0;/*复位接收位*/
  189. RedRead=0;/*复位接收过程标志*/
  190. RedCon=0;/*复位载波计数*/
  191. nTimer=423;/*用定时140a检测同步信号208a*/
  192. TF1=0;/*复位定时器T01益出标志*/
  193. ET1=1;}/*启动定时器*/
  194. else if(RSend){/*在位接收没有结束时发生定时中断需要复位接收信息(同步)*/
  195. RClear:
  196. RedDataL=0;/*复位红外数据*/
  197. RedDataH=0;/*复位红外数据*/
  198. RedBit=0;/*复位接收位*/
  199. RedRead=0;/*复位接收过程标志*/
  200. RSend=0;/*复位重新发送标志*/
  201. RedCon=0;/*复位载波计数*/
  202. ET1=0;/*关闭T01定时*/
  203. }
  204. }
复制代码
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-11-23 06:40 , Processed in 0.053147 second(s), 10 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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