一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要 2.25ms( 560us 脉冲+1680us 低电平),一个逻辑 0 的传输需要 1.125ms(560us 脉冲+560us 低电平)。而红外接收头在收到脉冲的时候为低电平,在没有脉冲 的时候为高电平,这样,我们在接收头端收到的信号为:逻辑 1 应该是 560us 低 +1680us 高,逻辑 0 应该是 560us 低+560us 高。
所以可以通过计算高电平时 间判断接收到的数据是 0 还是 1。
hongwai.c
#include "hongwai.h"
#include "systick.h"
u32 Hong_Data; //红外线接受的数据
u8 Hong_Flag; //接受是否完成
/*****************************************************************
函数名:Hongwai_Init()
函数功能:红外初始化
输入:无
输出:无
****************************************************************/
void Hongwai_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG|RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG,&GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOG, GPIO_PinSource15); //选择GPIO管脚用作外部中断线路,重映射
EXTI_ClearITPendingBit(EXTI_Line15);
EXTI_InitStructure.EXTI_Line = EXTI_Line15;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*****************************************************************
函数名:Hig_Cou()
函数功能:高电平时间判别函数
输入:无
输出:8位的时间判别参数
****************************************************************/
u8 Hig_Cou()
{
u8 t=0;
if(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_15))
{
t++;
delay_us(20);
if(t>=250) return t;
}
return t;
}
/*****************************************************************
函数名:EXTI15_10_IRQHandler()
函数功能:中断服务函数,进行解码并存储
输入:无
输出:无
****************************************************************/
void EXTI15_10_IRQHandler()
{
u8 tim; //高电平时间参数变量
u8 ok; //引导码有效变量
u8 data; //接受高低电平
u8 num; //接受次数
while(1)
{
if(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_15)==1)
{
tim = Hig_Cou(); //获取高电平时间
if(tim>=250) break;
if(tim<250&&tim>200) ok = 1; //引导码有效
if(tim<90&&tim>70) data = 1; //接受是高电平
else if(tim<40&&tim>15) data = 0; //接收是低电平
if(ok) //引导码有效
{
Hong_Data <<=1; //移位
Hong_Data+=data; //把数据存入Hong_Data
}
if(num>=32) //32位4字节都接受完
{
Hong_Flag = 1; //传输完
break;
}
num++;
}
EXTI_ClearITPendingBit(EXTI_Line15);
}
}
hongwai.h
#ifndef _hongwai_H
#define _hongwai_H
#include "system.h"
extern u32 Hong_Data;
extern u8 Hong_Flag;
void Hongwai_Init(void);
u8 Hig_Cou(void);
#endif
main.c
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"
#include "hongwai.h"
int main()
{
u8 i=0;
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组
LED_Init();
USART1_Init(9600);
Hongwai_Init();
while(1)
{
if(Hong_Flag==1)//接受完成
{
Hong_Flag=0; //清空标志位,供下次使用
printf("发红外接收码是:%.8X\r\n",Hong_Data);
Hong_Data=0;//清空数据供下次使用
}
i++;
if(i%20==0)
{
led1=!led1;
}
delay_ms(10);
}
}
网友评论