一. 红外线系统的组成
(1)、般由红外发射装置和红外接收设备两大部分组成。
(2)、红外发射装置又可由键盘电路、红外编码芯片、电源和红外发射电路组成。 红外接收设备可由红外接收电路、红外解码芯片、电源和应用电路组成。
二、 红外脉冲码 (NEC码)
(1)、 NEC码的位定义:(代表bit:0)低电平时间固定为0.56毫秒,如果高电平时间为1.125-0.56=0.56毫秒,则这个脉冲代表0;
(代表bit:1)低电平的时间为0.56毫秒,高电平为2.25-0.56=1.69毫秒时。这个脉冲代表1。
(2)、由位组成的数据格式。
(1)数据格式包括了引导码、用户码、数据码和数据码反码,编码总占32位。数据反码是数据码反相后的编码,编码时可用于对数据的纠错。(注意:第二段的用户码也可以在遥控应用电路中被设置成第一段用户码的反码。)
三、红外接收部分
(1)、这里用(stm32f407g)单片机的外部中断触发,接收脚位用上拉的方法。这里的外部中断触发方式用下降延触发中断。进入中断后在WHILE中等待判断是否为起始码电平4.5MS的高电平。代码如下:
hongwai.h中的代码
#ifndef _hongwai_H
#define _hongwai_H
#include "system.h"位带操作的文件
//全局变量
extern u32 hw_jsm;//存放获取到的红外接收码
extern u8 hw_jsbz;//接收完成标志
//函数声明
void Hwjs_Init(void);
u8 HW_jssj(void);
void EXTI9_5_IRQnHandler(void);
#endif
hongwai.c中的代码内容为:
1、红外初始化函数Hwjs_Init() 其中包括管脚的初始化、中断的初始化
2、读取GPIOA_8管脚高电平时间函数 HW_jssj(void)
3、外部中断发生时的解码函数EXTI9_5_IRQHandler(void)
# include "hongwai.h"
#include "SysTick.h"//时钟延时函数头文件
u32 hw_jsm;//存放获取到的红外接收码
u8 hw_jsbz;//接收完成标志
void Hwjs_Init()//红外基本配置初始化函数
{
GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO结构体变量
EXTI_InitTypeDef EXTI_InitStructure;//定义外部中断结构体变量
NVIC_InitTypeDef NVIC_InitStructure;//定义中断结构体变量
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能端口A时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);//使能外部中断时钟
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource8);//将GPIOA管脚映射到中断上
//GPIO初始化
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN; //输入模式
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;//管脚设置A8
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化结构体
EXTI_ClearITPendingBit(EXTI_Line8);//清除外部中断8的中断标志
//外部中断初始化
EXTI_InitStructure.EXTI_Line=EXTI_Line8;//外部中断线8
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//选择中断触发
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿触发
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
//中断初始化
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//EXTI9_5中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
}
//读取GPIOA_8管脚高电平时间函数,返回值为该管脚的高电平时间t t自加一次为20us
u8 HW_jssj(void)
{
u8 t=0;//时间变量
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)==1)//判断为高电平则循环
{
t++;
delay_us(20);
if(t>250)//高电平时间过长,强制结束函数
{
return t;
}
}
return t;
}
//外部中断8函数,用于对红外进行解码,并将解码后的数据存入全局变量hw_jsm
void EXTI9_5_IRQHandler(void)
{
u8 Tim=0;//时间变量
u8 ok=0;//判断数据是否有效的变量
u8 DATA=0;//存储接收数据的值
u8 Num=0;//用于判断是否接收完32位
while(1)
{
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)==1)//高电平到来
{
Tim=HW_jssj();//获取高电平
if(Tim>=250)break;//如果高电平时间超时
if(Tim>=200&&Tim<250)//如果高电平在4ms和5ms毫秒的有效时间之间
{
ok=1;
}
else if(Tim>=60&&Tim<90)//高电平在1.2到1.8毫秒之间
{
DATA=1;
}else if(Tim>=10&&Tim<50)//高电平在0.2到1毫秒之间
{
DATA=0;
}
if(ok==1)//如果成功接收到引导码,则开始存放获取到的数据
{
//二进制按位操作,将DATA读取到的中读取的值存入
hw_jsm<<=1;
hw_jsm+=DATA;
if(Num>=32)//判断是否接收完32位
{
hw_jsbz=1;//接收完成标志置一
break;
}
}
Num++;//每接收完一位累加一次,加到32接收完毕
}
}
EXTI_ClearITPendingBit(EXTI_Line8);//清除外部中断8的中断标志
}
main 代码
#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"//串口通讯头文件(需要将获取到的码通过串口输出到屏幕)
# include "hongwai.h"
int main()
{
u8 i=0;
SysTick_Init(168);//延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组
LED_Init();//led灯控制函数初始化
USART1_Init(9600);//串口初始化
Hwjs_Init();//红外初始化
while(1)//发生中断以后hw_jsm会自动保存红外的编码
{
if(hw_jsbz==1)//如果有接收到红外
{
hw_jsbz=0;//清除接收判断标志,以便下一次接收
printf("红外接收码 %0.8X\r\n",hw_jsm);
hw_jsm=0;//清除接收码内容,以便下一次接收
}
i++;
if(i%20==0)
{
led1=!led1;
}
delay_ms(10);//延时
}
}