这里使用的处理器是C8051F005。红外接收头接处理器引脚,中断方式接收按键数据。


一 PCA介绍

 1.1 PCA  

  可编程计数器阵列(PCA)提供增强的定时器功能,与标准8051计数器/定时器相比,它需要较少的CPU干预。PCA包含一个专用的16位计数器/定时器和5个16位捕捉/比较模块。每个捕捉/比较模块有其自己的I/O线(CEXn)。当被允许时,I/O线通过交叉开关连到端口I/O。

  计数器/定时器由一个可配置的时基信号驱动,可以在四个输入源中选择时基信号:系统时钟12分频、系统时钟4分频、定时器0溢出或ECI线上的外部时钟信号。对PCA的配置和控制是通过系统控制器的特殊功能寄存器来实现的。PCA的基本原理框图下图。

  

 1.2 捕捉/比较模块

  每个模块都可被配置为独立工作,有四种工作方式:边沿触发捕捉、软件定时器、高速输出和脉宽调制器。每个模块在CIP-51系统控制器中都有属于自己的特殊功能寄存器(SFR)。这些寄存器用于配置模块的工作方式和与模块交换数据。

  PCA0CPMn寄存器用于配置PCA捕捉/比较模块的工作方式,下表概述了模块工作在不同方式时该寄存器各位的设置情况。置‘1’ PCA0CPMn寄存器中的ECCFn位将允许模块的CCFn中断。

  注意:要使单独的CCFn中断得到响应,必须先整体允许PCA0中断。通过将EA位(IE.7)和EPCA0位(EIE1.3)设置为逻辑1来整体允许PCA0中断。

  

 1.3 边沿触发的捕捉方式

  在该方式,CEXn引脚上出现的有效电平变化导致PCA捕捉PCA计数器/定时器的值并将其装入到对应模块的16位捕捉/比较寄存器(PCA0CPLn和PCA0CPHn)。

  PCA0CPMn寄存器中的CAPNn位用于选择触发捕捉的电平变化类型:低电平到高电平(正沿)、高电平到低电平(负沿)或任何变化(正沿或负沿)。

  当捕捉发生时,PCA0CN中的捕捉/比较标志(CCFn)被置为逻辑1并产生一个中断请求(如果CCF中断被允许)。

  当CPU转向中断服务程序时,CCFn位不能被硬件自动清除,必须用软件清0。

  


二、红外编码

 2.1数据格式

  数据格式包括了引导码、用户码、数据码和数据码反码,编码总占32 位。数据反码是数据码反相后的编码,编码时可用于对数据的纠错。注意:第二段的用户码也可以在遥控应用电路中被设置成第一段用户码的反码。

  

 2.2位定义

  用户码或数据码中的每一个位可以是位‘1’,也可以是位‘0’。区分‘0’和‘1’是利用脉冲的时间间隔来区分,这种编码方式称为脉冲位置调制方式,英文简写PPM。

  

  这里只介绍了红外的一些简单的知识,还有其他重复码等知识自行学习。


三、实现

 3.1 准备

  由于项目中的红外遥控器是定制的,首先用示波器观测下某一按键的波形图。

  

  从图中可知,去除掉起始码,我们可以定义高电平短的是逻辑0,,高电平长点的是逻辑1。这样读到的32位数据为0111 0100 1000 1011 1000 1000 0111 0111

  数据的分析:两两一组,一共四组。第一组是第二组的反码;第三组是第四组的反码。

 3.2 软件实现

 #define _9ms_val         0x40CC          //9ms
#define _9ms_min 0x3900 //8.5ms
#define _9ms_max 0x4466 //9.5ms
#define _45ms_val 0x2066 //4.5ms
#define _45ms_min    0x1CCC //4ms
#define _45ms_max    0x2400 //5ms
#define _56ms_val 0x408 //0.56ms
#define _56ms_min    0x34F //0.46ms
#define _56ms_max    0x4C0 //0.66ms
#define _169ms_val 0xC2B //1.69ms
#define _169ms_min    0xACC //1.5ms
#define _169ms_max    0xC87 //1.74ms
#define _225ms_val 0x1033 //2.25ms
#define _225ms_min    0xE66 //2ms
#define _225ms_max    0x1200 //2.5ms
#define posedge 0x21 //正沿捕捉功能使能
#define engedge    0x11 //负沿捕捉功能使能

define

  上面一部分的时间是这样算出来的,系统采用的时钟是22.1184MHz。在下面的初始化中,PCA使用的是系统时钟的十二分之一,即是1.8432MHz。拿9ms作说明,

    

  得出 x=16588.8    ,转换成16进制数就是 0x40CC。

  最后两个宏参照图2得来,捕捉上升沿还是下降沿。

 void init_pca(void) {
EIE1 |= 0x08; //允许PCA0的中断请求
PCA0MD = 0x1; //系统时钟的12分频 CF 中断
PCA0CN = 0x0;
PCA0CPM0 = 0x0;
PCA0CPM0 = engedge;
PCA0L = 0x0;
PCA0H = 0x0;
conut = 0x0;
state = 0x0;
rep_fg = ;
}

初始化

   初始化完成对变量的初始化,以及首先捕获下降沿。

 #ifdef eclipse
void PCA0_ISR(void) /* 可编程计数器阵列0 */
#else
void PCA0_ISR (void) interrupt EPCA0_VECTOR /* 可编程计数器阵列0 */
#endif
{
EA = ;
switch (state) {
case 0x0: //开始第一个下降沿
PCA0L = PCA0H = 0x0;
CR = ; //允许PCA计数器
PCA0CPM0 = posedge; //设置捕获高电平
conut = 0x0;
state = 0x1;
break;
/*----------------------------------------------------------------------------*/
case 0x1: //低电平宽度 9ms
CR = ;
TIM_L_VAL.c[] = PCA0CPL0;
TIM_L_VAL.c[] = PCA0CPH0;
PCA0L = PCA0H = 0x0;
PCA0CPM0 = engedge; //设置捕获低电平
if ((TIM_L_VAL.i > _9ms_min) && (TIM_L_VAL.i < _9ms_max)) { //9ms比较
CR = ;
state = 0x2;
} else
state = 0x0; //不是9ms脉冲
break;
/*----------------------------------------------------------------------------*/
case 0x2: //高电平宽度 4.5ms 2.25
TIM_H_VAL.c[] = PCA0CPL0;
TIM_H_VAL.c[] = PCA0CPH0;
CR = ;
PCA0L = PCA0H = 0x0;
conut = 0x0;
if ((TIM_H_VAL.i > _45ms_min) && (TIM_H_VAL.i < _45ms_max)) //4.5ms比较
{
PCA0CPM0 = posedge; //设置捕获高电平
CR = ;
state = 0x3;
} else {
if ((TIM_H_VAL.i > _225ms_min) && (TIM_H_VAL.i < _225ms_max)) //2.25ms比较
{
PCA0CPM0 = posedge; //设置捕获高电平
CR = ;
rep_fg = ; //重发标志
state = 0x3;
} else //干扰信号,重新开始
{
PCA0CPM0 = engedge; //设置捕获低电平
state = 0x0;
}
}
break;
/*----------------------------------------------------------------------------*/
case 0x3: //低电平宽度 0.56ms
TIM_L_VAL.c[] = PCA0CPL0;
TIM_L_VAL.c[] = PCA0CPH0;
CR = ;
PCA0L = PCA0H = 0x0;
PCA0CPM0 = engedge;
if (conut == ) {
if ((key.c[] == ~key.c[]) && (key.c[] == ~key.c[])
&& (key.c[] == use_code)) {
key_code = key.c[];
key_bit = ;
isr_send_signal(DIS_Handle);
}
conut = 0x0;
state = 0x0;
} else {
if ((TIM_L_VAL.i > _56ms_min) && (TIM_L_VAL.i < _56ms_max)) //0.56ms比较
{
if (rep_fg) {
state = 0x0; //重发码
rep_fg = ;
//isr_send_signal(DIS_Handle);
} else {
CR = ;
state = 0x4;
}
} else
state = 0x0;
}
break;
/*----------------------------------------------------------------------------*/
case 0x4: //高电平宽度
TIM_H_VAL.c[] = PCA0CPL0;
TIM_H_VAL.c[] = PCA0CPH0;
CR = ;
PCA0L = PCA0H = 0x0;
key.l = key.l >> ;
if ((TIM_H_VAL.i > _169ms_min) && (TIM_H_VAL.i < _169ms_max))//1.69ms比较
key.l |= 0x80000000;
if ((TIM_H_VAL.i > _56ms_min) && (TIM_H_VAL.i < _56ms_max)) //0.56ms比较
key.l &= ~0x80000000;
CR = ;
PCA0CPM0 = posedge; //设置捕获高电平
state = 0x3;
conut++;
break;
/*----------------------------------------------------------------------------*/
default:
CR = ;
PCA0L = PCA0H = 0x0;
PCA0CPM0 = engedge;
state = 0x0;
break;
/*----------------------------------------------------------------------------*/
}
CCF0 = ;
EA = ;
}

实现部分

  状态0产生后,开始计数,并设置捕获上升沿。捕获到上升沿,进入到状态1,分析是否是9ms。

  状态3和状态4是核心部分,接收32位有效数据,并且判断是否有效。当为有效按键时,会发送一个信号,显示任务会等待这个信号。

  代码的第92行到第96行,接收位的处理,先接收到的位存储在字节的最低位。

  总的来说,根据波形合理的设置捕获方式,判断起始码,接收32位数据。

C8051 PCA实现红外遥控接收的更多相关文章

  1. 玩转X-CTR100 l STM32F4 l 红外遥控接收

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ]      X-CTR100控制器具有红外接收头,例程 ...

  2. 红外遥控接收发射原理及ESP8266实现

    红外遥控是利用近红外光进行数据传输的一种控制方式.近红外光波长0.76um~1.5um ,红外遥控收发器件波长一般为 0.8um~0.94um ,具有传输效率高,成本低,电路实现简单,抗干扰强等特点, ...

  3. GP1UM26(78)1RK远程红外遥控接收IC数据手册学习

    1.Features 该系列IC具有多种BMP带通频率可供选择,典型的GP1UM261RK带通频率为38KHz,内部的前置放大器等放大电路工作频率均为38KHz. Compact紧凑型,体积小 2.i ...

  4. 基于Arduino、STM32进行红外遥控信号接收

    catalogue . 遥控器原理简介 . 红外遥控原理 . 常见红外遥控器红外线信号传输协议 . 遙控器的发展 . 实验过程 . 攻击面 . 基于STM32实现红外信号解码 1. 遥控器原理简介 0 ...

  5. arduino红外遥控库IRremote的IRsend类sendRaw函数溢出问题及其解决方法

    最近在调试红外遥控格力空调,在论坛中学到了不少东西.参考: (1)<解决问题系列(4)——红外编码分析利器使用> (2)<315Mhz模块传输替代315Mhz遥控器> 调试环境 ...

  6. 51单片机tea5767收音机 红外遥控 自动搜台 存台 DIY

    先看效果图: 显示 频道CH , 频率 100.0Mhz 欢迎信息,1602 内置日文平假名, 正好用来显示博主名称. 焊接前,已经万能面包板上试验成功. 焊接完成以后,1602 的D0 - D7 接 ...

  7. 红外遥控NEC协议使用总结

    最近做了一个调试红外遥控三色灯的实习,花了一个多月的时间研究基于NEC协议的红外遥控,下面是这次实习技术方面的总结. 一.NEC协议特征: 8位地址和8位命令长度 每次传输两遍地址(用户码)和命令(按 ...

  8. Arduino红外遥控系列教程2013——红外转码

    教程三:红外转码教程——用电视遥控器取代机顶盒遥控器 前言前段时间看到了使用红外遥控的X-Bot机器人[链接],感觉很有意思.最近开始玩Arduino与红外,一方面打算将来用于BOXZ的之间的通讯控制 ...

  9. 基于FPGA的红外遥控解码与PC串口通信

    基于FPGA的红外遥控解码与PC串口通信 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<电子设计EDA>的课程设计作业(呵呵,这个月都拿 ...

随机推荐

  1. C#设计模式总结

    一.引言 经过这段时间对设计模式的学习,自己的感触还是很多的,因为我现在在写代码的时候,经常会想想这里能不能用什么设计模式来进行重构.所以,学完设计模式之后,感觉它会慢慢地影响到你写代码的思维方式.这 ...

  2. [51单片机] TFT2.4彩屏2 [32*32文字显示]

    >_<:同理如果想显示其他形式的字体,就要建立相应的库啦,如这里还有一个gb3232的汉字库:GB3232.h // ------------------ 汉字字模的数据结构定义 ---- ...

  3. ActiveMQ第三弹:在Spring中使用内置的Message Broker

    在上个例子中我们演示了如何使用Spring JMS来向ActiveMQ发送消息和接收消息.但是这个例子需要先从控制台使用ActiveMQ提供的命令行功能启动一个Message Broker,然后才能运 ...

  4. 祸福相依,大难之后的O2O迎来新福报?

    今天的O2O似乎已经成为了一个人人都不愿意提的名词,很多原本做O2O的创业者,如今都不提自己是O2O,只说是互联网+.创业者们实际上仍然是在干着O2O的事情,之所以不敢提不愿提,无非就是一提O2O,投 ...

  5. Leetcode 235 Lowest Common Ancestor of a Binary Search Tree 二叉树

    给定一个二叉搜索树的两个节点,找出他们的最近公共祖先,如, _______6______ / \ ___2__ ___8__ / \ / \ 0 4 7 9 / \ 3 5 2和8的最近公共祖先是6, ...

  6. arcgis server账号需要设置地图缓存的访问权限

    如果gis服务起不来,那么可以看看arcgis server账号有没有设置地图缓存的访问权限,有可能arcgis server账号没有这个文件夹的访问权限.  本文用菊子曰发布

  7. iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式

    iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式 说明: 1)该文简短介绍在iOS开发中遍历字典.数组和集合的几种常见方式. 2)该文对应的代码可以在下面的地址获得:https:// ...

  8. 在 Xen 虚拟机下修改系统当前时间

    在 Xen 虚拟机下修改系统当前时间 Xen 虚拟机默认不允许不同的虚拟机使用不同的系统时间,因此所有虚拟机的系统时间都会同宿主机的系统时间严格同步,用 date 命令修改虚拟机系统时间时虽然提示成功 ...

  9. linux shell 多线程执行程序

    Shell中并没有真正意义的多线程,要实现多线程可以启动多个后端进程,最大程度利用cpu性能. 直接看代码示例吧. (1) 顺序执行的代码 #!/bin/bash date ` do { echo & ...

  10. 关于H.264 x264 h264 AVC1

    1. H.264是MPEG4的第十部分,是一个标准.对头,国际上两个视频专家组(VCEG和MPEG)合作提出的标准,两个专家组各有各的叫法,所以既叫H.264,也叫AVC. 2.x264是一个编码器, ...