【蓝桥杯单片机】红外接收及NEC红外通信协议

实验开发板为CT107D蓝桥官方板,编译环境为MDK5

目录

 

1 、红外发射和接收原理简述

2、蓝桥杯竞赛板所使用的红外一体化接收头

2.1、通信协议

2.2、实际驱动


工程下载地址:

https://gitee.com/Joseph_Cooper/blue-bridge-mcu/tree/master


1 、红外发射和接收原理简述

红外发射:通过单片机软件模拟发射出一定频率的红外信号,红外信号的发射类似于普通LED,不过红外发射头发射的是不可见的红外光,并且以一定的频率发射 。

红外接收头:L2为红外接收管收到的红外光越强则反向电流越大则3口电压越小通过运算后发向信号检测端口。

在这里先不深入研究原理,蓝桥的板子为一体化接收头先掌握驱动原理吧。

2、蓝桥杯竞赛板所使用的红外一体化接收头

2.1、通信协议

红外一体化接收头使用的是NEC通信协议。只用一个引脚来完成数据的接收因此对时间有严格的要求。

NEC数据格式:引导码、用户码、用户码(或者用户码反码)、按键键码和键码反码,
最后一个停止位。

引导码:9ms的载波+4.5ms的空闲。
比特值“0”:560us的载波+560us的空闲。
比特值“1”:560us的载波+1.68ms的空闲。

图片来源@金沙滩工作室

2.2、实际驱动

在使用红外接收头前要先将红J2跳线帽全部右移才能使用红外发射和接收。

一般红外接收引脚会接在外部中断方便接收到信号后直接读取信号,但是反人类的蓝桥开发板并没有,所以我用了一根杜邦线连接了P3^3和P1^1。

具体操作如下:

/**************************************************/
/*	需使用杜邦线将P1^1和P3^3短接									*/
/**************************************************/
#include "infrared.h"

bit irflag = 0;

u8 ircode[4];//数码管接收缓冲区

void InitInfrared()
{
	//AUXR &= 0x7F;//设置定时器为12T模式
	IR_INPUT = 1;
	TMOD = (TMOD & 0x0F) | 0x10;
	TR1 = 0;
	ET1 = 0;//定时器1中断关闭
	IT1 = 1;//设置外部中断1为下降沿触发
}

u16 GetHighTime()
{
	TH1 = 0;
	TL1 = 0;
	TR1 = 1;
	while(IR_INPUT)
	{
		if(TH1 >= 0x40) break;//高电平时间持续过长(约18ms)则跳出
	}
	TR1 = 0;
	
	return (TH1 * 256 + TL1);
}

u16 GetLowTime()
{
	
	TH1 = 0;
	TL1 = 0;
	TR1 = 1;
	while(!IR_INPUT)
	{
		if(TH1 >= 0x40) break;//低电平时间持续过长(约18ms)则跳出
	}
	TR1 = 0;
	
	return (TH1 * 256 + TL1);
}
//INT1外部中断服务函数,接收红外并解码
void Service_INT1() interrupt 2
{
	u8 i, j;
	u8 byt;
	u16 time;
	
	SMG_Display();
	
	time = GetLowTime();
	if( (time < 7833) || (time > 8755) )//判断是否为误码
	{
		IE1 = 0;//清除外部中断标志
		return;
	}
	
	time = GetHighTime();
	if( (time < 3686) || (time > 4608) )//判断是否为误码
	{
		IE1 = 0;
		return;
	}
	
	for(i = 0; i < 4; i ++)
	{
		for(j = 0; j < 8; j ++)
		{
			//先判断每位的数据中的低电平是否超时
			time  = GetLowTime();
			if( (time < 313) || (time > 718) )
			{
				IE1 = 0;
				return;
			}
			//接收判断每位高电平时间判断值
			time  = GetHighTime();
			if( (time > 313) && (time < 718) )//值为0
			{
				byt >>= 1;
			}
			else if( (time > 1345) || (time < 1751) )//值为1
			{
				byt >>= 1;
				byt |= 0x80;
			}
			else//不符合上述两种条件即为误码
			{
				IE1 = 0;
				return;
			}
		}
		ircode[i] = byt;
	}
	irflag = 1;
	IE1 = 0;
	
}

void HW_Get()
{
	if(irflag)
	{
		irflag = 0;
		SMG_Buff[0] = SMG[ircode[0] >> 4];
		SMG_Buff[1] = SMG[ircode[0]&0x0F];
		
		SMG_Buff[6] = SMG[ircode[2] >> 4];
		SMG_Buff[7] = SMG[ircode[2]&0x0F];
	}
}

/****************************infrared.h****************************/
#ifndef _INFRARED_H
#define _INFRARED_H

#include "config.h"
#include "SMG.h"

sbit IR_INPUT = P1^1;

extern void InitInfrared();
extern u16 GetHighTime();
extern u16 GetLowRime();
extern void HW_Get();

#endif

数码管上显示的是用户码的前两位和16进制的键码

  • 22
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 32
    评论
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值