C51单片机——红外遥控 驱动程序


本文为学习HC6800-EM3 V2.2开发板的学习笔记汇总,本文所用 红外接收头的引脚封装如图下:

引脚封装

驱动函数封装

声明:请自行根据晶振编写相匹配的延时函数

IrReceive.h文件

#ifndef __IRRECEIVE_H__
#define __IRRECEIVE_H__

#include "delay.h"//请自行根据晶振编写相匹配的延时函数;

typedef struct{
	uchar usercode;//用户码
	uchar cmd;//操作码
	uchar ok;//完成标志位
	uchar irtime; //时间控制
	uint  count_repeat;//重复码计数器
	u32 receive;//数据缓存
}ir_value_t;

extern ir_value_t IrValue;//结构体声明

void irReceiveInit(void);//初始化
void IrValueParse(u32 recv);//数据处理函数

#endif

IrReceive.c文件

红外接收头的out引脚接在单片机的P3.2口,以外部中断0下降沿方式触发

#include "IrReceive.h"

void irReceiveInit(void)//初始化
{
  TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
  TH0=0; //重载值
  TL0=0; //初始化值
  ET0=1;    //开中断
  TR0=1;    
	
	IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
	EX0 = 1;   //使能外部中断
	EA = 1;    //开总中断
}

void IrValueParse(u32 recv)//数据处理函数
{
	uchar temp1;
	uchar temp2;
	temp1=recv;
	temp2=recv>>8;
	IrValue.usercode=temp1;
	if(temp1!=(uchar)(~temp2))
	{
		IrValue.ok=0;
		return;
	}
	temp1=recv>>16;
	temp2=recv>>24;
	IrValue.cmd=temp1;
	if(temp1!=(uchar)(~temp2))
	{
		IrValue.ok=0;
		return;
	}
	IrValue.ok=1;
}

ir_value_t IrValue;

void timer0_isr(void) interrupt 1 //定时器0中断服务函数
{
	IrValue.irtime++;
}

void ir_ex0_interrupt() interrupt 0 //外部中断0 下降沿触发
{   
		static bit flag_start=0;
		static uchar IrCountBit=0;     //位计数器
		if(IrValue.irtime<60&&IrValue.irtime>=40) 
		{
			flag_start=1;引导码 9ms+4.5ms 数据开始接收
			IrCountBit=0;//开始数数
			IrValue.count_repeat=0;//重发码清零
		}
		if(flag_start)
		{
			IrValue.receive>>=1;
			if(IrValue.irtime>6&&IrValue.irtime<10) //逻辑1
			{
				IrValue.receive|=0x80000000;
			}
			else if(IrValue.irtime<513&&IrValue.irtime>=268)
			{
				IrValue.count_repeat++;
			}
			IrCountBit++;
			if(IrCountBit==33)	//接收完成
			{
				IrValueParse(IrValue.receive);	
			}
		}
		IrValue.irtime=0;//清空定时器变量
}

测试实验

为验证驱动程序是否正确,采用红外遥控键值的变化显示到LCD1602上进行验证;
注:LCD驱动代码请参看链接: LCD驱动篇.

main.c文件

#include "IrReceive.h"
#include "lcd1602.h"

void main(void)
{
	uchar buf[16];
	irReceiveInit();
	lcd1602Init();	//LCD初始化
	lcd1602Clear();	//清屏
	
	while(1)
	{
		if(IrValue.ok==1)//接收解码完成
		{
			sprintf(buf,"%d",IrValue.cmd); //组包;
			lcd1602WriteString(0,0,buf); //打印字符串
			IrValue.ok=0;//每按下一次显示一次;
		}
	}
}
©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页