红外解码:VS1838B接收头
21键遥控器:
这里是发送的高低电平的图片,真正单片机接收到是要将PWM脉冲0变1,1变0
明显看出遥控器发出的波形和接收头解码相反
同步码;地址码;地址反码;控制码,控制反码;反码用于校验
接收端:逻辑1=560us低电平+1680us高电平;逻辑0=560us低电平+560us高电平;低位在前高位在后;8位的格式;
程序的代码学习:
红外接收的初始化,开启中断
#include "hwjs.h"
#include "SysTick.h"
u32 hw_jsm; //定义一个32位数据变量,保存接收码 4*8低位在前高位在后
u8 hw_jsbz; //定义一个8位数据的变量,用于指示接收标志
/*******************************************************************************
* 函 数 名 : Hwjs_Init
* 函数功能 : 红外端口初始化函数 时钟端口及外部中断初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Hwjs_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 开启GPIO时钟及管脚复用时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//红外接收GPIOB_Pin_9
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入节约了一个上拉电阻
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9); //选择GPIO管脚用作外部中断线路
EXTI_ClearITPendingBit(EXTI_Line9);
/* 设置外部中断的模式 */
EXTI_InitStructure.EXTI_Line=EXTI_Line9;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* 设置NVIC参数 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //打开全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
* 函 数 名 : HW_jssj
* 函数功能 : 高电平持续时间,将记录的时间保存在t中返回,其中一次大约20us
* 输 入 : 无
* 输 出 : t
*******************************************************************************/
u8 HW_jssj()//记录红外接收的高电平时间
{
u8 t=0;
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==1)//高电平
{
t++;
delay_us(20);
if(t>=250) return t;//超时溢出 20*250=5000us=5ms
}
return t;
}
void EXTI9_5_IRQHandler(void) //红外遥控外部中断
{
u8 Tim=0,Ok=0,Data,Num=0;//Tim用来记录高电平时间,
//OK用来记录起始码正确,Data记录数据,Num记录4*8=32位
while(1)
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==1)
{
Tim=HW_jssj();//获得此次高电平时间
if(Tim>=250) break;//不是有用的信号
if(Tim>=200 && Tim<250)//4ms~5ms
{
Ok=1;//收到起始信号
}
else if(Tim>=60 && Tim<90)//1200us~1800us 1680us
{
Data=1;//收到数据 1
}
else if(Tim>=10 && Tim<50)//200us~1000us 560us
{
Data=0;//收到数据 0
}
if(Ok==1)
{
hw_jsm<<=1;
hw_jsm+=Data;//低位存在了前面了
if(Num>=32)
{
hw_jsbz=1;
break;
}
}
Num++;
}
}
EXTI_ClearITPendingBit(EXTI_Line9);
}