|
电视机红外遥控至少学习,前段时间在家里研究红外通信原理,市场上遥控器有很多种 ENC协议是小日本,市场上用的比较多, 我手上这个电视遥控器是个杂牌子,遥控器是42位编码, 引导码低电平9ms 引导吗高电平5ms 接下来关键地方是用户码
用户码头是用来区别不同型号的遥控器,这是我手头遥控器 13位用户正吗0010001110000
13为 用户反码1101110001111 和正码相反
接下来就是8位按键正码 00000000
8位按键反码 11111111
我自己把手头遥控器的解码程序写出来程序代码如下,本人测试成功
/**********************************************************************************
* STM32F103VET6 红外驱动【遥控器解码实验程序】
*
* 遥控器 :42位编码
*
***********************************************************************************/
#include "stm32f10x.h"
#include "exti.h"
#include "beep.h"
#include "SysTick.h"
#define LED1_0 GPIOD->BRR = 0x00000100 //LED低电平
#define LED2_0 GPIOD->BRR = 0x00000200
#define LED3_0 GPIOD->BRR = 0x00000400
#define LED4_0 GPIOD->BRR = 0x00000800
#define LED1_1 GPIOD->BSRR = 0x00000100 //LED高电平
#define LED2_1 GPIOD->BSRR = 0x00000200
#define LED3_1 GPIOD->BSRR = 0x00000400
#define LED4_1 GPIOD->BSRR = 0x00000800
#define IR_Hongwai_0 GPIOE->BRR = 0x00000004 //红外数据低电平
#define IR_Hongwai_1 GPIOE->BSRR = 0x00000004 //红外数据高电平
#define IR_Hongwai_x GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2) //读取红外电平状态
unsigned char TimeByte;
unsigned int IR_Tireafg[4];
unsigned int IR_xidwrit[8] = {0, 0, 0, 0, 0, 0 ,0, 0};
/*
* GPIO端口配置子函数
*/
void GPIO_InitStructReadtempCmd(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; //配置GPIO管脚
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //配置管脚为输入上拉
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //配置管脚速率50MHZ
GPIO_Init(GPIOE, &GPIO_InitStruct); //初始化指定端口
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //配置管脚陪推挽式输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
}
/*
* 配置外设时钟子函数
*/
void RCC_APB2PeriphReadtempyCmd(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //打开GPIOB外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //打开GPIOE外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); //打开GPIOD外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE); //打开AFIO复用功能外设时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
}
/*
* 计算低脉宽持续时间Count1 * 10us
*/
unsigned int IR_HongwaiRead_LSB_Cmd()
{
unsigned int Count1 = 0; //定义时间变量
IR_Hongwai_0; //红外数据低电平
do //进入循环体
{
Count1++; //时间变量加1
Delay_10us(1); //延时10us
} while(IR_Hongwai_x == 0); //判断条件如果读出来的红外数据为高电平跳出循环体
return(Count1); //返回时间变量积数
}
/*
* 计算高脉宽持续时间Count2 * 10us
*/
unsigned int IR_HongwaiRead_MSB_Cmd()
{
unsigned int Count2 = 0; //定义时间变量
IR_Hongwai_1; //红外数据高电平
do //进入循环体
{
Count2++; //时间变量加1
Delay_10us(1); //延时10us
} while(IR_Hongwai_x == 1); //判断条件如果读出来的红外数据为低电平跳出循环体
return(Count2);
}
/*
* 函数主体
*/
int main(void)
{
SystemInit(); //初始化系统时钟进入72M主频
SYSTICK_InitStructReadTCmd(); //初始化SysTick配置器寄存器
RCC_APB2PeriphReadtempyCmd(); //初始化外设时钟配置寄存器
GPIO_InitStructReadtempCmd(); //初始化GPIO端口配置寄存器
EXTI_InitStructReadtempCmd(); //初始化EXTI外部线路寄存器
NVIC_InitStructReadtempCmd(); //初始化NVIC中断配置寄存器
while(1)
{
}
}
/*
* EXTI外部中断线服务程序
*/
void EXTI2_IRQHandler(void)
{
unsigned char i = 0;
unsigned char flag = 1;
// unsigned char flag1 = 1;
unsigned int Countline2 = 0;
IR_Hongwai_1;
Countline2 = IR_HongwaiRead_LSB_Cmd(); //低电平引导码 9ms判断
if((Countline2 < 850) || (Countline2 > 950)) //小于8694us 大于9272us 一直循环否则跳出
{
return;
}
Countline2 = IR_HongwaiRead_MSB_Cmd(); //高电平引导码 4.5ms判断
if((Countline2 < 400) || (Countline2 > 450)) //小于4195us 大于4712us 一直循环否则跳出
{
return;
}
TimeByte = 0;
for(i = 1; i < 14; i++)
{
TimeByte = TimeByte >> 1;
Countline2 = IR_HongwaiRead_LSB_Cmd(); //低电平延时0.56 判断
if((Countline2 < 40) || (Countline2 > 85))//小于425us 大于851us 一直循环否则跳出
{
return;
}
Countline2 = IR_HongwaiRead_MSB_Cmd(); //高电平延时0.56判断
if((Countline2 < 40) || (Countline2 > 200))//小于425us 大于1793us 一直循环否则跳出
{
return;
}
if( Countline2 > 130) //高电平延时大于1300us写1否则写0
{
TimeByte |= 0x80; //写1
}
}
IR_Tireafg[0] = TimeByte;
TimeByte = 0;
for(i = 14; i < 27; i++)
{
TimeByte = TimeByte >> 1;
Countline2 = IR_HongwaiRead_LSB_Cmd();
if((Countline2 < 40) || (Countline2 > 85))
{
return;
}
Countline2 = IR_HongwaiRead_MSB_Cmd();
if((Countline2 < 40) || (Countline2 > 200))
{
return;
}
if( Countline2 > 130)
{
TimeByte |= 0x80;
}
}
IR_Tireafg[1] = TimeByte;
TimeByte = 0;
for(i = 27; i < 35; i++)
{
TimeByte = TimeByte >> 1;
Countline2 = IR_HongwaiRead_LSB_Cmd();
if((Countline2 < 40) || (Countline2 > 85))
{
return;
}
Countline2 = IR_HongwaiRead_MSB_Cmd();
if((Countline2 < 40) && (Countline2 > 200))
{
return;
}
if( Countline2 > 130)
{
TimeByte |= 0x80;
}
}
IR_Tireafg[2] = TimeByte;
TimeByte = 0;
for(i = 35; i < 43; i++)
{
TimeByte = TimeByte >> 1;
Countline2 = IR_HongwaiRead_LSB_Cmd();
while((Countline2 < 40) || (Countline2 > 85))
{
return;
}
Countline2 = IR_HongwaiRead_MSB_Cmd();
while((Countline2 < 40) || (Countline2 > 200))
{
return;
}
if( Countline2 > 130)
{
TimeByte |= 0x80;
}
}
IR_Tireafg[3] = TimeByte;
//************************判断用户正码和反码***************************************//
do
{
if(IR_Tireafg[0] == 0x08 & IR_Tireafg[1] == 0xF7 )
{
flag = 0;
}
} while(flag == 1);
//************************判断按键正码和反码***************************************//
/* do
{
if(IR_Tireafg[2] == ~IR_Tireafg[3])
{
flag1 = 0;
}
} while(flag1 == 0); */
//************************按下键码对应LED点亮**************************************//
switch (IR_Tireafg[2])
{
case 0x00: //按键 0
LED1_1; LED2_0; LED3_0; LED4_0;
break;
case 0x01: //按键 1
LED1_0; LED2_1; LED3_0; LED4_0;
break;
case 0x02: //按键 2
LED1_0; LED2_0; LED3_1; LED4_0;
break;
case 0x03: //按键 3
LED1_0; LED2_0; LED3_0; LED4_1;
break;
case 0x04: //按键 4
LED1_0; LED2_0; LED3_1; LED4_0;
break;
case 0x05: //按键 5
LED1_0; LED2_1; LED3_0; LED4_0;
break;
case 0x06: //按键 6
LED1_1; LED2_0; LED3_0; LED4_0;
break;
case 0x07: //按键 7
LED1_1; LED2_0; LED3_1; LED4_0;
break;
case 0x08: //按键 8
LED1_0; LED2_0; LED3_0; LED4_0;
break;
case 0x09: //按键 9
LED1_0; LED2_1; LED3_0; LED4_1;
break;
case 0x15: //静音键
LED1_0; LED2_1; LED3_1; LED4_0;
break;
case 0x1C: //开机键
LED1_1; LED2_0; LED3_0; LED4_1;
break;
case 0x14: //OSD键
LED1_1; LED2_1; LED3_0; LED4_0;
break;
case 0x0E: //RECALL键
LED1_0; LED2_0; LED3_1; LED4_1;
break;
case 0x19: //SLEEP键
LED1_1; LED2_1; LED3_1; LED4_0;
break;
case 0x0A: //A/C键
LED1_0; LED2_1; LED3_1; LED4_1;
break;
case 0x0F: //TV/AV键
LED1_1; LED2_1; LED3_1; LED4_1;
break;
case 0x13: //PP键
LED1_1; LED2_0; LED3_1; LED4_0;
break;
case 0x0C: //GAME键
LED1_0; LED2_1; LED3_1; LED4_1;
break;
case 0x1E: //V-键
LED1_1; LED2_1; LED3_1; LED4_0;
break;
case 0x1F: //V+键
LED1_0; LED2_0; LED3_1; LED4_0;
break;
case 0x1B: //P+键
LED1_0; LED2_0; LED3_0; LED4_1;
break;
case 0x1A: //P-键
LED1_1; LED2_0; LED3_0; LED4_0;
break;
case 0x10: //MENU键
LED1_0; LED2_1; LED3_0; LED4_0;
break;
default : break;
}
// Beep_lookCmd(); //蜂鸣器按键音
EXTI_ClearITPendingBit(EXTI_Line2); //清除EXTI2外部线路挂起位
}
/*******************************************END****************************************/
|
|