单片解码红外遥控器lcd显示

合集下载

红外解码管数码管显示 (用户码和数据码)

红外解码管数码管显示 (用户码和数据码)

基于STC89C54单片机设计的红外解码数码管显示1.红外解码原理红外遥控器发送数据时,是将二进制数据调制成一系列的脉冲信号红外发射管发射出去,红外载波为频率38KHz的方波,红外接收端在收到38KHz的载波信号时,会输出低电平,否则输出高电平,从而可以将“时断时续”的红外光信号解调成一定周期的连续方波信号,再经过1838一体化红外接收头解调便可以恢复出原数据信号。

如图所示,我们可以通过单片机的定时器给红外接收管接收的每个点电平计时,并把每个点电平的时间存起来。

根据时间的不同来分辨是引导码、“0”还是“1”。

下面是我做的实验原理图上图式数码管显示原理图,下面是红外接收管与单片机的连接原理图。

注:上图的J27是和单片机的P3^2相连的。

程序中用到的定时器1、定时器0和外部中断0.下面是实验的C语言程序:/*-----------------------------------------------名称:遥控器红外解码数码管晶显示论坛:无编写:yang-baoan日期:2011.10修改:无内容:按配套遥控器按键,液晶显示4组码值,分别是用户码用户码数据码数据反码显示如下:1E1E00FF------------------------------------------------*/#include<reg52.h>//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义sbit IR=P3^2;//红外接口标志#define DataPort P0//定义数据端口程序中遇到DataPort则用P0替换sbit LATCH1=P2^2;//定义锁存使能端口段锁存sbit LATCH2=P2^3;//位锁存unsigned char Tab[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};unsigned char TempWei[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};/*------------------------------------------------全局变量声明------------------------------------------------*/unsigned char irtime;//红外用全局变量bit irpro_ok,irok;unsigned char IRcord[4];unsigned char irdata[33];unsigned char TempData[8];/*------------------------------------------------函数声明------------------------------------------------*/void Ir_work(void);void Ircordpro(void);void Display(unsigned char FirstBit,unsigned char Num);/*------------------------------------------------定时器0中断处理------------------------------------------------*/void tim0_isr(void)interrupt1using1//using表示工作寄存器,后跟0—3个数分别表示工作寄存器组{irtime++;//用于计数2个下降沿之间的时间}/*------------------------------------------------外部中断0中断处理------------------------------------------------*/void EX0_ISR(void)interrupt0//外部中断0服务函数{static unsigned char i;//接收红外信号处理static bit startflag;//是否开始处理标志位if(startflag){if(irtime<63&&irtime>=33)//引导码TC9012的头码,9ms+4.5ms,此if语句只对下一条语句起作用i=0;irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1irtime=0;i++;if(i==33){irok=1;i=0;}}else{irtime=0;startflag=1;}}/*------------------------------------------------定时器0初始化------------------------------------------------*/void TIM0init(void)//定时器0初始化{TMOD|=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值TH0=0x00;//重载值TL0=0x00;//初始化值ET0=1;//开中断TR0=1;}/*------------------------------------------------外部中断0初始化------------------------------------------------*/void EX0init(void){IT0=1;//指定外部中断0下降沿触发,INT0(P3.2)EX0=1;//使能外部中断EA=1;//开总中断}/*------------------------------------------------定时器1初始化------------------------------------------------*/void Init_Timer0(void){TMOD|=0x10;//使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响TH1=(65536-2000)/256;//给定初值TL1=(65536-2000)%256;EA=1;//总中断打开ET1=1;//定时器中断打开TR1=1;//定时器开关打开}/*------------------------------------------------定时器1中断子程序------------------------------------------------*/void Timer0_isr(void)interrupt3{TH1=(65536-2000)/256;//重新赋值2ms TL1=(65536-2000)%256;Display(0,8);//调用数码管扫描}/*-----------------------------------------------------------数码管显示函数,动态扫描-----------------------------------------------------------*/void Display(unsigned char FirstBit,unsigned char Num) {static unsigned char i=0;DataPort=0;//清空数据,防止有交替重影LATCH1=1;//段锁存LATCH1=0;DataPort=TempWei[i+FirstBit];//取位码LATCH2=1;//位锁存LATCH2=0;DataPort=TempData[i];//取显示数据,段码LATCH1=1;//段锁存LATCH1=0;i++;if(i==Num)i=0;}/*------------------------------------------------键值处理------------------------------------------------*/void Ir_work(void){unsigned int t=200;TempData[0]=Tab[IRcord[0]/16];TempData[1]=Tab[IRcord[0]%16];TempData[2]=Tab[IRcord[1]/16];TempData[3]=Tab[IRcord[1]%16];TempData[4]=Tab[IRcord[2]/16];TempData[5]=Tab[IRcord[2]%16];TempData[6]=Tab[IRcord[3]/16];TempData[7]=Tab[IRcord[3]%16];irpro_ok=0;//处理完成标志}/*------------------------------------------------红外码值处理------------------------------------------------*/void Ircordpro(void)//红外码值处理函数{unsigned char i,j,k;unsigned char cord,value;k=1;for(i=0;i<4;i++)//处理4个字节{for(j=1;j<=8;j++)//处理1个字节8位{cord=irdata[k];if(cord>8)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差value|=0x80;if(j<8){value>>=1;}k++;}IRcord[i]=value;value=0;}irpro_ok=1;//处理完毕标志位置1}/*------------------------------------------------延时函数,含有输入参数unsigned int t,无返回值unsigned int是定义无符号整形变量,其值的范围是0~65535------------------------------------------------*//*------------------------------------------------主函数------------------------------------------------*/void main(void){EX0init();//初始化外部中断TIM0init();//初始化定时器Init_Timer0();while(1)//主循环{if(irok)//如果接收好了进行红外处理{Ircordpro();irok=0;}if(irpro_ok)//如果处理好后进行工作处理,如按对应的按键后显示对应的数字等{Ir_work();}}}。

红外解码1602显示按键值

红外解码1602显示按键值

/********************************************************************* 文件名: 红外解码LCD.c* 描述: 实现了红外解码遥控器上的按键的值并在1602上显示出来。

按遥控器的“0”会在数码管的最后一位显示0.按遥控器的“1”会在数码管的最后一位显示1.。

按遥控器的“8”会在数码管的最后一位显示8.按遥控器的“9”会在数码管的最后一位显示9.* 创建人:东流,2012年2月10日* 版本号:1.0***********************************************************************/#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar LCD_ID_1[16] = {"Red Control"};uchar LCD_ID_2[16] = {"You press the:-"};void delay(uchar x); //x*0.14MSvoid delay1(int ms);uchar distemp = 0;sbit IRIN = P3^3; //红外接收器数据线uchar IRCOM[7];sbit E=P2^7; //1602使能引脚sbit RW=P2^6; //1602读写引脚sbit RS=P2^5; //1602数据/命令选择引脚/********************************************************************* 名称: Delay()* 功能: 延时,延时时间大概为1毫秒* 输入: 无* 输出: 无***********************************************************************/ void Delay_1ms(uint i){uint x,j;for(j=0;j<i;j++)for(x=0;x<=148;x++);}/********************************************************************* 名称: delay()* 功能: 延时,延时时间大概为140US。

基于单片机的红外解码.温度及液晶显示

基于单片机的红外解码.温度及液晶显示

中国矿业大学徐海学院技能考核培训姓名:顾嘉诚学号: 22110818专业:信息11-2班题目:基于单片机的红外解码.温度及液晶显示专题:红外解码指导教师:宥鹏老师翟晓东老师设计地点:电工电子实验室时间: 2014 年 4 月通信系统综合设计训练任务书学生姓名顾嘉诚专业年级信息11-2班学号22110818设计日期:2014年4 月5日至2014 年4 月10 日同组成员:姜怀修,刘剑桥,顾嘉诚,彭传锁,何子豪,王业飞设计题目:基于单片机的红外无线控制设计专题题目:红外解码设计主要内容和要求:1.主要内容:2.单片机内部结构红外遥控解码C语言程序设Ds18b20的使用Lcd1602的使用2. 功能扩展要求环境温度液晶显示指导教师签字:目录正文 (5)1.概述 (5)1.1功能描述 (5)1.2单片机资源 (5)2.1管脚图 (5)3.1. 使用资源 (5)2.原理篇 (6)2.1红外发送及接收 (6)2.1.1红外接收概述 (6)2.1.2硬件及原理图 (7)2.1.3红外中断接收部分程序 (8)2.2温度原理 (9)2.2.1 DS18B20 的主要特性 (9)2.2.2原理图与硬件 (10)2.2.3 DS18B20时序和程序 (10)2.3 QC1602A (12)2.3.1 1602外部结构及管脚说明 (12)2.3.2 写命令/数据时序与部分程序 (13)3.效果图 (15)4.软件篇 (15)4.1程序框图 (15)4.1.1 Main函数 (15)4.1.2 中断 (16)4.1.3 60ms定时中断 (16)4.2 完整程序 (16)4.2.1 Project.c文件 (16)4.2.2 onewire.c 文件 (23)5.参考文献 (26)技能考核培训摘要:利用单片机所学内容进行拓展,我们实现了基于单片机的红外解码.温度及液晶显示。

Lcd液晶显示实时环境温度和接收显示红外遥控器的键值,在收到红外信号时会用蜂鸣器作为反馈,以提醒红外一体接收头有接到信号。

单片机STM32F103C8T6的红外遥控器解码系统设计

单片机STM32F103C8T6的红外遥控器解码系统设计

单片机STM32F103C8T6的红外遥控器解码系统设计一、本文概述本文旨在详细阐述基于STM32F103C8T6单片机的红外遥控器解码系统的设计和实现过程。

随着科技的不断进步和智能化设备的普及,红外遥控器作为一种常见的遥控设备,已经广泛应用于家电、安防、玩具等多个领域。

然而,红外遥控器发出的红外信号往往需要通过解码器才能被设备正确识别和执行,因此,设计一款高效、稳定、可靠的红外遥控器解码系统具有重要意义。

本文将首先介绍红外遥控器的基本原理和信号特点,然后详细阐述STM32F103C8T6单片机的性能特点和在红外遥控器解码系统中的应用优势。

接着,将详细介绍红外遥控器解码系统的硬件设计,包括红外接收头的选择、电路设计和PCB制作等。

在软件设计部分,将详细阐述如何通过STM32F103C8T6单片机的编程实现红外信号的接收、解码和处理,以及如何将解码后的数据通过串口或其他通信方式发送给主控制器。

本文还将对红外遥控器解码系统的性能进行测试和分析,包括信号接收距离、解码速度和稳定性等方面的测试。

将总结本文的主要工作和创新点,并对未来的研究方向进行展望。

通过本文的研究和实现,旨在为红外遥控器解码系统的设计提供一种新的思路和方法,同时也为相关领域的研究人员提供有益的参考和借鉴。

二、红外遥控器基础知识红外遥控器是一种常见的无线遥控设备,它利用红外光作为信息载体,通过发射和接收红外光信号实现对设备的远程控制。

这种遥控方式因其简单、低成本和无需视线连接等优点,在各类消费电子产品中得到了广泛应用,如电视机、空调、音响等。

红外遥控器的工作原理主要基于红外辐射和光电器件的检测。

遥控器内部通常包含一个或多个红外发射管,当按下按键时,发射管会发射出特定频率和编码的红外光信号。

接收端则配备有红外接收头,该接收头内部有一个光敏元件(如硅光敏三极管或光敏二极管),用于检测红外光信号并将其转换为电信号。

为了区分不同的按键操作,红外遥控器通常采用特定的编码方式对按键信号进行编码。

一种基于单片机的红外遥控信号解码新方法

一种基于单片机的红外遥控信号解码新方法

控 方 式 时 不 会 干 扰 其 他 电器 的正 常 使 用 , 不 会 影 响 临 近 也
的无 线 电设 备 。 另 外 , 外 遥 控 器 件 具 有 体 积 小 、 耗 ] 红 功 低 、 价 比高 的优 点 , 理 想 的人 机 输 入设 备 , 常 适 合 电 性 是 非 子 工 程 师 和 电子 爱 好 者 DI 开 发 与 制 作 。红 外 遥 控 系 统 Y
主 要 由发 射 和 接 收 两 大部 分 组 成 , 于 发 射 部 分 使 用 的是 由
I e Rr s
购 买 来 的遥 控 器 成 品 , 以本 文 的 重 点 是 红 外 接 收 、 码 所 解 部 分 。下 面 将 从 硬 件 结 构 和 软件 编 程 两 个 方 面 出发 , 绍 介
Absr c ta t:I f a e e ot o r lr r dey u e n us ho d e e t ia ppl nc s I f a e i na c di e hod r a i s i n r r d r m ec ntole s a e wi l s d i ho e l l c rc la i e . n r r d sg lde o ng m t a s a e v rou n
功 能 寄存 器单 元 进行 定 义 , 时 对 相 关 工 作 单 元 进 行 初 始 同
化 。初 始 化 代 码 如 下 :
; 定 义 , 存 器 定 义 位 寄 I Ke Re d B T R y ay I I oe RC d I i R: nt I Oh O ; 义 “ 得 到键 值 ” 志 位 定 已 标 ; 义 4字 节 红 外 码 寄 存 器 定 ; 开 外 部 中断 1 打 ; 降 沿 触 发 下

红外解码+lcd显示

红外解码+lcd显示

红外遥控解码+LCD1602显示完全资料【精】2009-2-9 10:03:00点击:458来源:作者:佚名红外遥控解码实验一.实验目的1. 了解红外遥控编码并用单片机捕捉信号及解码2. 熟悉LCD1602的驱动二.红外遥控器编码遥控器编码分好几种,常见的32位编码码和42位编码码,目前我手中遥控器就是42位编码,如图1所示,当有按键时就会产一个9.12ms低电平和4.5ms高电平的起始码,紧接着是26位系统码,此系统码能区别不同的电器设备,防止不同机种遥控码互相干扰,接下来是8位数据码和8位数据反码,间隔23ms的高电平后,再发一个与启始码完全一样的结束码:以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”,其波形如图2所示:再回头看图1,大家不难看出,图1是遥控器按键1的一串编码三.硬件连接接收电咱我们使用一化红外接红外接收管1838,不需要任何外接无件,就能完成从红外线接收到输出与TTL电平信号兼容的所有工作,实物如图所示:电路图如下:四.解码以上我们了解了红外遥控的编码及硬件连接,现在就对其进行解码,所谓解码就是能用单片机把以不同宽度的脉冲区别开来,一种比较好思路就是计算两次下降沿间隔时间,当单片机外部中断1口有下降沿时中断一次,并启动定时器,定时器定50us,当下次下降沿到来时我们计算定时器中断的次数,这样我们就能很好的区分不同宽度的脉冲了。

大家可能已经迫不急待的要开始解码了,别急,我们先把注意事项先讲一下,实际上,我们红外接收头收到的信号的是有毛刺的,放大后就如下图,所以在下降沿中断触发后,要做延时去抖处理:*************************************以下是完整解码程序********************************/***********************************************项目:红外遥控解码(EE01学习板演示程序)**作者:一线工人**网站:电子工程师之家**本程序适合42位码遥控器,即26位系统码,16位数据码,如:57L5,55K2,54B4,KD-29,55K8,5Z26A,等型号的遥控器,转贴请保持代码的完整性*********************************************/#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit ir=P3^3;//红外端口sbit dm=P1^4;//数码管段码控制位sbit wm=P1^5;//数码管位码控制位sbit led_cs=P1^6;//LED控制位sbit rs=P3^5;//1602数据命令选择端sbit en=P3^4;//1602使能信号uchar num;uchar key_code=0;//遥控键值uchar new_code=0;//有无新按键uint buf_key_code=0;//键值暂存uchar key_bit_count=0;//键编码脉冲计数uint count=0;//定时中断次数计数uint buf_count=0;//定时中断计数暂存uchar common_code_count=0;//前导码脉冲计数uchar ir_status=0;//脉冲接收器所处的状态,0:无信号,1:系统码接收区,2:数据编码接收区uchar code table[]="EE01 DEMO:IR";uchar code table1[]="code:";uchar code table2[]={'0','1','2','3','4','5','6','7','8','9',};void delay_10us(unsigned char y)///延时子程序10us{unsigned char x;for(x=y;x>0;x--);}void delay_ms(uint z)//延时子程序1ms{uint x,y;for(x=z;x>0;x--)for(y=113;y>0;y--);}void init(void)/////初始化{ir=1; //红外端口写1led_cs=0; //关闭LEDEA=1; //开总中断TMOD=0x02; //定时器0,模式2,8位自动装载模式TH0=0Xd1; //定时50usTL0=0Xd1;IT1=1; //INT1下降沿触发ET0=1; //允许定时器中断EX1=1; //允许外部中断}/***********************************************定时器中断***********************************************/void time0() interrupt 1///定时器中断{count++;//定时器中断次数累加}/**********************************************外部中断,红外解码程序**********************************************/void int1() interrupt 2///外部中断{TR0=1;//开定时器中断if(count>12&&count<270)//如果信号合法,则放入buf_count,count清0,对下一个脉冲信号计时{buf_count=count;count=0;}delay_10us(10);//延时100us以消除下降沿跳变抖动if(ir==0)//INT1引脚稳定为低电平,则表法确实是信号,count重新计时,因上面延时了50us,故要补偿1次TO中断{count=2;}if(buf_count>12&&buf_count<270)//若收到的信号合法,则再进行信号分析{if(ir_status==0)//如果之前未收到引导码{if(buf_count>210&&buf_count<270)//判断是否引导码13.5ms{ir_status=1;//系统标记buf_count=0;//}}else if(ir_status==1)///收到引导码{if(common_code_count>=25)//若收完26个脉冲{ir_status=2;//数据解码标记common_code_count=0;//系统码计算清零buf_count=0;//中断计数暂存清0}else if((buf_count>40&&buf_count<70)||(buf_count>12&&buf_count<32)){buf_count=0;common_code_count++;//每收到一个信号自加1}}else if(ir_status==2)//进入数据编码接收{if(key_bit_count<8)//收到数据少于8位,则将收到的数据写入buf_key_code{if(buf_count>40&&buf_count<70){buf_count=0;buf_key_code>>=1;buf_key_code|=0x80;//收到1key_bit_count++;//数据脉冲累加}else if(buf_count>12&&buf_count<32)//收到0{buf_count=0;buf_key_code>>=1;//收到0key_bit_count++;}}else //若收完8位数据则做以下处理{ir_status=0;//接收状态返回到空闲key_code=buf_key_code;key_bit_count=0;buf_key_code=0;buf_count=0;TR0=0;new_code=1;}}}}/**********************************************1062驱动程序**********************************************/void wirte_cmd(uchar cmd)//写命令{rs=0;P0=cmd;en=1;delay_ms(5);en=0;}void wirte_data(uchar dat)//写数据{rs=1;P0=dat;en=1;delay_ms(5);en=0;}void wirte_string(const unsigned char *s)//在第二行第5个字开始写字符串{wirte_cmd(0x80+0x40+0x05);while(*s){wirte_data(*s);s++;}}void init_1602()///1602初始化{dm=0;wm=0;led_cs=0;wirte_cmd(0x38);delay_ms(5);wirte_cmd(0x0c);delay_ms(5);wirte_cmd(0x06);}/*************************************主程序*************************************/void main(){init(); ///初始化init_1602(); //1602初始化while(!new_code);//判断是否有新按键,如果有则执行下面程序,没有则一直循环wirte_cmd(0x01);//1602清屏delay_ms(5);wirte_cmd(0x80);//在第一行写入EE01 DEMO:IRfor(num=0;num<12;num++){wirte_data(table[num]);delay_ms(1);}wirte_cmd(0x80+0x40);//在第二行写入code:for(num=0;num<5;num++){wirte_data(table1[num]);delay_ms(1);}if(key_code<10)//如果按鍵小于10则写入相应的数字{wirte_data(table2[key_code]);delay_ms(2);}else if(key_code<50)//大于10则写入字符,与遥控器对应{switch(key_code){case 21:wirte_string("mute");break;case 28:wirte_string("power");break;case 10:wirte_string("-/--");break;case14:wirte_cmd(0x80+0x40+0x05);wirte_data(0x7f);wirte_data(0x7e);break;//先写字符位置,然后写字符,case 25:wirte_string("SLEEP");break;case 19:wirte_string("P.P");break;case 15:wirte_string("TV/AV");break;case 30:wirte_string("VOL-");break;case 31:wirte_string("VOL+");break;case 27:wirte_string("P+");break;case 26:wirte_string("P-");break;case 16:wirte_string("MENU");break;case 24:wirte_string("A-MODE");break;case 13:wirte_string("SYS");break;case 12:wirte_string("GAME");break;case 20:wirte_string("DISP");break;delay_ms(2);}new_code=0;}}。

遥控器红外解码数码管显示

void tim0_isr (void) interrupt 1 using 1
{
irtime++; //用于计数2个下降沿之间的时间
}
/*------------------------------------------------
外部中断0中断处理
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
sbit IR=P3^2; //红外接口标志
#define DataPort P0 //定义数据端口程序中遇到DataPort则用P0替换
sbit LATCH1=P2^2;//定义锁存使能端口段锁存
{
for(j=1;j<=8;j++) //处理1个字节8位
{
cord=irdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
value|=0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord[i]=value;
value=0;
}
irpro_ok=1;//处理完毕标志位置1
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)

单片机STM32F103C8T6的红外遥控器解码系统设计

78M i c r o c o n t r o l l e r s &E m b e d d e d S ys t e m s 2019年第10期w w w .m e s n e t .c o m .c n单片机S T M 32F 103C 8T 6的红外遥控器解码系统设计胡进德(仙桃职业学院科研处,仙桃433000)摘要:设计了一种适用于N E C 红外传输协议的解码系统㊂系统以单片机S TM 32F 103C 8T 6为核心,采用外部中断和定时器进行软件解码,解码结果通过串口调试软件在P C 机上进行了验证㊂详细介绍了N E C 红外传输协议和解码方法,包括系统软硬件设计㊁软件设计流程图㊁核心功能函数和程序代码㊂关键词:S TM 32F 103C 8T 6;N E C 红外传输协议;红外解码;外部中断;定时器中图分类号:T P 31 文献标识码:AD e s i g n o f D e c o d i n g S ys t e m f o r I n f r a r e d R e m o t e C o n t r o l l e r B a s e d o n S T M 32F 103C 8T 6H u J i n d e(S c i e n t i f i c R e s e a r c h D e p a r t m e n t ,X i a n t a o V o c a t i o n a l C o l l e ge ,X i a n t a o 433000,C h i n a )A b s t r a c t :A d e c o d i n g s y s t e m of i n f r a r e d r e m o t e c o n t r o l l e r s u i t a b l e f o r N E C i n f r a r e d t r a n s p o r t p r o t o c o l i s d e s ig n e d .Th e s ys t e m t a k e s M C U S TM 32F 103C 8T 6a s t h e c o r e t o c o m p l e t e s o f t w a r e d e c o d i n g b y e x t e r n a l i n t e r r u p t a n d t i m e r ,a n d t h e d e c o d i n g re s u l t s a r e v e r if i e d o n P C b y s e r i a l d e b ug g i n g s o f t w a r e .N E C i n f r a r e d t r a n s p o r t p r o t o c o l a n d d e c o d i n g m e th o d a r ei n t r o d u c e d i n d e t a i l ,i n c l u d i n gt h e s o f t w a r e a n d h a r d w a r e d e s i g n ,t h e f l o w c h a r t o f s o f t w a r e d e s i g n ,c o r e f u n c t i o n s a n d p r o gr a m c o d e .K e y wo r d s :S TM 32F 103C 8T 6;N E C i n f r a r e d t r a n s p o r t p r o t o c o l ;i n f r a r e d d e c o d i n g ;e x t e r n a l i n t e r r u p t ;t i m e r 引 言红外遥控具有体积小㊁信息传输可靠㊁功耗低㊁成本低等显著特点,越来越多地应用于嵌入式系统㊂红外遥控系统一般由发射和接收两大部分组成,红外遥控器所发射的信号编码格式不同,其解码的方法也会随之发生变化㊂目图1 N E C 红外传输协议的帧数据格式前市场上所用红外遥控器广泛使用两种形式的编码格式,一种是采用N E C 红外传输协议的P WM (脉冲宽度调制)方式,一种是采用P h i l i ps 红外传输协议的P P M (脉冲位置调制)方式[1]㊂通过对市场上一种名为T E L E S K Y 的红外遥控器[2]所发射的信号进行测试,研究表明,其信号波形和脉冲间隔时间符合N E C 红外传输协议,无重复码㊂本文依项目需要针对T E L E S K Y 红外遥控器设计了基于单片机S TM 32F 103C 8T 6的解码系统㊂1 N E C 红外传输协议N E C 红外传输协议的主要特征是:一帧数据包含8位用户编码(地址码)和8位按键数据码(命令码);用户编码和按键数据码均传送两次,一次是原码,一次是反码,以确保可靠传送;采用P WM (脉冲宽度调制)方式,以发射红外载波的占空比代表比特 0 和比特 1;载波频率是38k H z ;一个数据位的传输时间是, 0 用时1.125m s, 1 用时2.25m s [1]㊂N E C 红外传输协议的帧数据格式如图1所示,其位定义如图2所示㊂图2 N E C 红外传输协议的位定义在图1中红外遥控器发射的每帧数据有32位,由16位用户编码(含低8位用户编码和高8位用户编码)㊁8位按键数据码和8位按键数据码的反码组成㊂每帧数据发敬请登录网站在线投稿 2019年第10期79送前有一个引导码(同步码),引导码由一个9m s 的高电平和一个4.5m s 的低电平组成㊂每帧数据按照低位在前㊁高位在后顺序发送[3]㊂帧数据中采用反码是为了增加传输的可靠性,因此,反码可用于解码时进行校验对比㊂需要注意的是,遵循N E C 红外传输协议的发射芯片可有两种用户编码方式,一种是8位用户码原码加8位用户码的反码,另一种是16位用户编码,通过改变红外发射芯片外部电路来选择不同的用户编码方式[1]㊂在图2中比特 1 由一个0.56m s 的脉冲和1.69m s的低电平构成,比特 0 由一个0.56m s 的脉冲和0.56m s 的低电平构成㊂一个0.56m s 的脉冲对应0.56m s 的连续载波[1]㊂2 解码系统硬件设计单片机解码红外遥控器常用的方法有查询法㊁外部中断法和定时器捕获法[4]㊂本系统采用外部中断法,即通过外部中断检测红外信号利用单片机定时器测量帧数据中每一位数据的传输时间,从而识别数据位是比特 1还是比特 0[3],解码系统硬件设计如图3所示㊂图3 红外信号接收与解码电路图3中U 1为S TM 32F 103C 8T 6处理器,这是一款以A R M C o r t e x M 3为内核的32位单片机,具有运行速度快㊁处理能力强㊁外设接口丰富㊁价格低廉等特点,专门应用于对性能要求较高㊁成本要求较低以及低功耗的场合,其最高工作频率为72MH z ,工作电压为2~3.6V ,64K B的闪存和20K B 的S R AM ,37个I /O ,与通用端口G P I O映射的外部中断E X T I 有16个,1个16位高级控制定时器,3个16位通用定时器,3个U S A R T 串口通信模块等[5]㊂本系统通过S TM 32F 103C 8T 6的P A 7引脚以外部中断方式检测红外信号,使用通用定时器T I M 2测量帧数据中每一位数据的传输时间,解码结果通过U S A R T 1(P A 9为发送引脚)和串口调试软件在P C 机上显示㊂图3中U 2为一体化红外接收头H S 0038B ,它负责将调制在38k H z 上的红外编码信号接收和解调后送给S TM 32F 103C 8T 6的P A 7引脚进行检测㊂H S 0038B 第1引脚为正电源引脚,工作电压为2.7~5.5V ,实际工作电压为3.3V ,与S TM 32F 103C 8T 6工作电压相同;第2引脚为负电源引脚,接地;第3引脚为输出端,连接S TM 32F 103C 8T 6的P A 7引脚㊂当H S 0038B 没有接收到红外遥控信号时,第3引脚输出保持高电平;当接收到红外遥控信号时,第3引脚输出从高电平变为低电平,其下降沿触发S TM 32F 103C 8T 6的外部中断[6-7]㊂需要注意的是,一体化红外接收头输出解调后的脉冲信号电平与红外遥控器发送的编码格式电平反相[8],即S TM 32F 103C 8T 6的P A 7引脚接收到的帧数据格式电平与图1反相,其数据位定义也与图2反相:比特 1 由一个0.56m s 的低电平和1.69m s 的高电平构成,传输比特 1 需要2.25m s ;比特 0 由一个0.56m s 的低电平和0.56m s 的高电平构成,传输比特 0 需要1.125m s [9]㊂因此,通过外部中断E X T I 和定时器T I M 2统计P A 7引脚接收到的帧数据中2个下降沿之间的间隔时间就可得到帧数据中每一位数据的传输时间,从而识别数据位是比特 1 还是比特 0㊂3 解码系统软件设计在A R M 嵌入式系统开发中,对处理器功能模块的操作既可以通过对芯片底层的寄存器,也可以使用S T 公司提供的标准函数库[10],本系统采用标准函数库操作S T M 32F 103C 8T 6相关寄存器㊂解码系统软件设计主要涉及5个方面㊂3.1 配置红外脉冲信号输入引脚P A 7为下降沿触发中断通过初始化通用端口G P I O ㊁外部中断E X T I 和嵌套向量中断控制器N V I C 的相关寄存器,配置P A 7为下降沿触发中断㊂3.1.1 初始化G P I O 的相关寄存器将P A 7配置为浮空输入[10],开启端口时钟和A F I O 时钟,相关初始化程序如下:G P I O _I n i t T y pe D ef G P I O _I n i t S t r u c t u r e ; //声明结构体变量以便初始化G P I O 相关寄存器R C C _A P B 2P e r i p h C l o c k C m d (R C C _A P B 2P e r i p h _G P I O A |R C C _A P B 2P e r i ph _A F I O ,E N A B L E );//开启G P I O 端口时钟,用到E X T I 必须开启A F I O 时钟G P I O _I n i t S t r u c t u r e .G P I O _P i n =G P I O _P i n _7;//选中当前端口的引脚7G P I O _I n i t S t r u c t u r e .G P I O _M o d e =G P I O _M o d e _I N _F L O A T -I N G ;//设定为浮空输入G P I O _I n i t (G P I O A ,&G P I O _I n i t S t r u c t u r e);//初始化G P I O A 相关寄存器80M i c r o c o n t r o l l e r s &E m b e d d e d S ys t e m s 2019年第10期w w w .m e s n e t .c o m .c n3.1.2 初始化E X T I 的相关寄存器应将P A 7与外部中断线连接[10],并配置为下降沿触发中断请求,相关初始化程序如下:E X T I _I n i t T y pe D ef E X T I _I n i t S t r u c t u r e ;//声明结构体变量以便初始化E X T I 相关寄存器G P I O _E X T I L i n e C o n f i g (G P I O _P o r t S o u r c e G P I O A ,G P I O _P i n -S o u r c e 7);//将P A 7与外部中断线连接E X T I _I n i t S t r u c t u r e .E X T I _L i n e =E X T I _L i n e 7; //使用外部中断输入线7E X T I _I n i t S t r u c t u r e .E X T I _M o d e =E X T I _M o d e _I n t e r r u pt ; //设置E X T I 线路为中断请求E X T I _I n i t S t r u c t u r e .E X T I _T r i g g e r =E X T I _T r i g g e r _F a l l i n g ;//设置E X T I 线路为下降沿触发中断请求E X T I _I n i t S t r u c t u r e .E X T I _L i n e C m d =E N A B L E ; //开放E X T I 线路中断请求E X T I _I n i t (&E X T I _I n i t S t r u c t u r e );//初始化E X T I 相关寄存器3.1.3 初始化N V I C 的相关寄存器程序中用到了2个中断源:来自P A 7引脚的E X T I 下降沿触发中断和定时器T I M 2计数溢出中断㊂设定E X T I 中断优先级高于T I M 2中断,使用v o i d N V I C _P r i o r i t y-G r o u p C o n f i g (u i n t 32_t N V I C _P r i o r i t y G r o u p )函数设定优先级分组为第1组,E X T I 中断抢占优先级为1,T I M 2中断抢占优先级为0,相关初始化程序如下:N V I C _I n i t T y pe D ef N V I C _I n i t S t r u c t u r e ;//声明结构体变量以便初始化N V I C 相关寄存器N V I C _P r i o r i t y G r o u p C o n f i g (N V I C _P r i o r i t y G r o u p_1);//选择第1组 N V I C _I n i t S t r u c t u r e .N V I C _I R Q C h a n n e l =E X T I 9_5_I R Q n ;//配置中断源N V I C _I n i t S t r u c t u r e .N V I C _I R Q C h a n n e l P r e e m p t i o n P r i o r i t y =1;//抢占优先级为1N V I C _I n i t S t r u c t u r e .N V I C _I R Q C h a n n e l S u b P r i o r i t y =1;//子优先级为1N V I C _I n i t S t r u c t u r e .N V I C _I R Q C h a n n e l C m d =E N A B L E ;//使能中断通道N V I C _I n i t (&N V I C _I n i t S t r u c t u r e );//初始化N V I C 相关寄存器3.2 配置定时器T I M 2每0.1m s 产生一次溢出中通过初始化定时器T I M 2和N V I C 的相关寄存器,配置T I M 2每0.1m s 产生一次溢出中断,以便在其中断处理程序中统计帧数据中每一位数据的传输时间㊂3.2.1 初始化T I M 2的相关寄存器设定系统时钟为72MH z ,预分频值P r e s c a l e r 为3600,计数器自动重装值P e r i o d 为2,此时定时器T I M 2每0.1m s 产生一次溢出中断[10]㊂相关初始化程序如下:S ys t e m I n i t (); //设置系统时钟为72MH z T I M _T i m e B a s e I n i t T y pe D ef T I M _S t r u c t I n i t ;//声明结构体变量以便初始化T I M 2寄存器R C C _A P B 1P e r i p h C l o c k C m d (R C C _A P B 1P e r i ph _T I M 2,E N A -B L E );//开启T I M 2时钟T I M _S t r u c t I n i t .T I M _P e r i o d =2;//设定计数器自动重装值T I M _S t r u c t I n i t .T I M _P r e s c a l e r =3600;//设定预分频值T I M _S t r u c t I n i t .T I M _C l o c k D i v i s i o n =T I M _C K D _D I V 1;//设置时钟分割T I M _S t r u c t I n i t .T I M _C o u n t e r M o d e =T I M _C o u n t e r M o d e _U p;//设置向上计数模式T I M _T i m e B a s e I n i t (T I M 2,&T I M _S t r u c t I n i t );//初始化T I M 2寄存器T I M _I T C o n f i g (T I M 2,T I M _I T _U p d a t e ,E N A B L E ); //使能T I M 2中断T I M _C m d (T I M 2,E N A B L E );//启动T I M 2T I M _C l e a r F l a g (T I M 2,T I M _F L A G _U pd a te ); //清除T I M 2的待处理标志位3.2.2 初始化N V I C 的相关寄存器配置定时器T I M 2为中断源,设置其优先级,相关初始化程序如下:N V I C _P r i o r i t y G r o u p C o n f i g (N V I C _P r i o r i t y G r o u p _1);//选择第1组N V I C _S t r u c t I n i t .N V I C _I R Q C h a n n e l =T I M 2_I R Q n;//配置中断源N V I C _S t r u c t I n i t .N V I C _I R Q C h a n n e l C m d =E N A B L E ;//使能中断通道N V I C _S t r u c t I n i t .N V I C _I R Q C h a n n e l P r e e m p t i o n P r i o r i t y=0;//抢占优先级为0N V I C _S t r u c t I n i t .N V I C _I R Q C h a n n e l S u b P r i o r i t y=1;//子优先级为1N V I C _I n i t (&N V I C _S t r u c t I n i t ); //初始化N V I C 相关寄存器3.3 统计帧数据中每一位脉冲的传输时间定时器T I M 2每0.1m s 产生一次溢出中断,在T I M 2中断服务程序中,全局变量i r _t i m e 每0.1m s 自动加1㊂通过i r _t i m e 可统计P A 7引脚接收的帧数据中相邻的2个下降沿之间的间隔时间,同时也获得帧数据中每一位脉冲的传输时间㊂程序如下:v o i d T I M 2_I R Q H a n d l e r (v o i d ) //T I M 2中断服务程序{T I M _C l e a r I T P e n d i n g B i t (T I M 2,T I M _I T _U pd a te );//清除T I M 2中断标志位以便下一个0.1m s 到来时触发T I M 2//中断i r _t i m e ++;//全局变量i r _t i m e 的计数值自动加1}3.4 存储从引导码开始的33个脉冲传输时间当H S 0038B 没有接收到红外信号时,系统默认处在敬请登录网站在线投稿 2019年第10期81图4 E X T I 中断服务流程图空闲 状态,P A 7引脚一直是高电平㊂当H S 0038B 接收到红外信号时,P A 7引脚由高电平变为低电平,此时将触发外部中断E X T I ,在E X T I 中断服务程序中先判断采集到的脉冲信号是否为引导码,如果i r _t i m e 计数值大于90(9m s )且小于150(15m s),则可视为引导码(引导码传输时间理论值为13.5m s,考虑到S TM 32F 103C 8T 6和红外遥控发射器的晶振频率与标称值会有一定的偏差,以及H S 0038B 红外接收头输出波形的轻微畸变,在程序设计时要留有一定的容限误差[4]),并将从引导码开始的33个脉冲传输时间(i r_t i m e 的计数值)保存到事先定义好的数组i r d a t a [33](全局变量)中㊂E X -T I 外部中断服务程序流程图如图4所示㊂3.5 从数组i r d a t a [33]中提取比特 1和比特 0并形成4个字节的按键码数组i r d a t a [33]存放了33个脉冲传输时间,其中数组元素i r d a t a [0]存放的是引导码传输时间,其他32个数组元素i r d a t a [1]~i r d a t a [32]存放了4个字节按键码的传输时间㊂比特 1 的传输时间为2.25m s,其对应的数组元素取值为22或23;比特 0 的传输时间为1.125m s,其对应的数组元素取值为11或12㊂在程序设计时同样要留有一定的容限误差,当数组元素i r d a t a [1]~i r d a t a [32]取值为20~25时,可认为接收到比特 1,否则认为接收到比特 0 ㊂因此从数组i r d a t a [33]中可提取4个字节按键码:i r -d a t a [1]~i r d a t a [16]提取16位用户编码,i r d a t a [17]~i r d a t a [24]提取8位按键数据码,i r d a t a [25]~i r d a t a [32]提取8位按键数据码的反码㊂提取4个字节按键码的函数流程图如图5所示㊂4 解码结果验证为了验证解码方案的正确性,通过串口调试软件将实验结果显示在P C 机上㊂图6是T E L E S K Y 遥控器外观和对应的按键数据码,图7是显示在P C 机上的实验结果㊂图7中有84个数据码,从左向右每4个数据码(对应4个字节共32位比特)一组对应一个按键,分别指示按键的用户码原码㊁用户码的反码㊁按键数据码和按键数据码的反码㊂如遥控器左上角第一个按键 C H- 的解码为00F F 45B A ,按键 C H图5 提取4个字节按键码的函数流程图图6 遥控器外观和按键数据码的解码为00F F 46B 9,其他按键的解码依此类推㊂从解码的实验结果可以看出,32位比特的前16位为用户码,后16位为8位按键数据码和按键数据码的反码,符合N E C 红外传输协议,且图7中21个按键数据码与图6中21个按键的数据码相同,相互依次对应,从而验证了解码方法的正确性㊂图7 串口调试软件显示的按键码结 语本文介绍的红外遥控器解码方法原理直观㊁简单可靠,已经应用于实际项目中,可为无线遥控嵌入式系统学习者提供一个应用范例㊂该方法不仅适用于N E C 红外传输协议,对于其他传输协议的解码同样有很好85敬请登录网站在线投稿2019年第10期85表4使用H M M在嘈杂环境下识别结果控制指令1号正确次数/总次数2号正确次数/总次数3号正确次数/总次数4号正确次数/总次数闭合拇指7/106/105/104/10伸开拇指6/107/105/106/10手腕逆时针7/106/107/108/10手腕归位6/104/104/105/10伸开手掌5/105/106/107/10握紧拳头6/104/105/106/10结语HMM算法实现的前提是需要大量的语音样本训练,不仅需要考虑到语音语调的差别,还要考虑非特定人性别年龄的差异,这样才能够适应实际语音中的不同情况,因此HMM算法具有良好的识别性和抗噪性㊂参考文献[1]周艳萍.机器人嵌入式语音识别系统设计与开发[D].广州:华南理工大学,2012.[2]周慧芳.基于HMM的嵌入式语音识别系统的研究[D].广州:广东工业大学,2011.[3]黄岗.马尔可夫及隐马尔可夫模型的应用[J].电子设计工程,2013,21(17):6062.[4]任昕.基于隐马尔可夫模型和卷积神经网络的W e b安全检测研究[D].长沙:湖南大学,2018.[5]王稚慧.基于HMM建模的语音识别算法的研究[D].西安:西安建筑科技大学,2005.[6]曹冠彬.基于HMM的连续语音识别技术研究[D].南京:南京理工大学,2018.[7]袁腾,李秋红,杨国斌,等.基于Z i g B e e和3G技术的W S N s 环境监控系统设计[J].传感器与微系统,2012,31(6):128129,133.[8]田泽,智爱娟,阎效莺,等.U D A1341T S在嵌入式语音系统中的应用[J].西北大学学报:自然科学版,2006(2):214220.[9]周夕良.嵌入式语音识别系统研究[J].电脑与信息技术,2014,22(1):5658.张起浩㊁蒋少国,主要研究方向为智能硬件设计;赵鹏(助理实验师),通讯作者,主要研究方向为智能硬件设计㊁语音识别㊂(责任编辑:薛士然收稿日期:2019-04-23)[5]U n d e r w o o d C,P e l l e g r i n o S,L a p p a s V J,e t a l.U s i n gC u b e S a t/m i c r o s a t e l l i t e t e c h n o l o g y t o d e m o n s t r a t e t h e A u-t o n o m o u s A s s e m b l y o f a R e c o n f i g u r a b l e S p a c e T e l e s c o p e(A A R e S T)[J].A c t a A s t r o n a u t i c a,2015(114):112122.[6]韩忠辉.基于G P I B的无线通信计量自动测试系统[J].自动化与仪器仪表,2016(6):110.[7]刘倩茜,王格芳.基于多总线结构的电路板测试系统设计研究[J].价值工程,2016,35(32):131133.[8]S h l a d o v e r S E.C o n n e c t e d a n d a u t o m a t e d v e h i c l e s y s t e m s:I n-t r o d u c t i o n a n d o v e r v i e w[J].J o u r n a l o f I n t e l l i g e n t T r a n s p o r-t a t i o n S y s t e m s,2018,22(3):190200.[9]张凯,李涵,姜静.基于A T E与B I T组合的N AM P自动测试与故障诊断系统设计[J].海军航空工程学院学报,2015,30(4):321325.[10]刘鹏飞,谢森,姚玉山,等.某型制导武器通用自动测试系统方案设计[J].计算机测量与控制,2017,25(6):9599.[11]曹兴冈,韩晨.基于P X I航电计算机测试设备的设计与实现[J].电子技术,2016(2):6.[12]刘新飞,李亚利,王东,等.通用航管二次雷达功放模块自动测试系统研制[J].计算机测量与控制,2016,24(9):4749.[13]L i u Y,P e n g Y,W a n g B,e t a l.R e v i e w o n c y b e r p h y s i c a ls y s t em s[J].I E E E/C A A J o u r n a l o f A u t o m a t i c a S i n i c a,2017,4(1):2740.[14]郭栋梁,刘新妹,殷俊龄,等.通用电路板自动故障诊断系统的设计与实现[J].中国测试,2016,42(7):112116.[15]宋丽涵,张琴.基于总线技术的仪器仪表自动检定系统设计[J].兰州文理学院学报:自然科学版,2016(2):5256.何进(讲师),主要从事电子技术㊁电力电子技术等教学研究㊂(责任编辑:薛士然收稿日期:2019-05-06)的参考价值㊂参考文献[1]李幸泽.基于W E B方式的智能家电控制网关的硏究[D].广州:广东工业大学,2012.[2]T E L E S K Y.红外线遥控器,2019.[3]李雪莹.基于单片机的空调红外线编解码系统的设计和实现[D].成都:电子科技大学,2014.[4]何乃味.单片机定时器捕获模式解码红外遥控器的方法[J].现代电子技术,2012(18):1113.[5]意法半导体(S T).S TM32F103x8d a t a s h e e t,2019.[6]圣狄豹.H S0038B红外线接收发射对管,2019.[7]管芳绍,徐志江,孟利民.基于嵌入式系统的抗干扰红外软解码方法[J].计算机技术与应用,2010(10):3033.[8]杨萍.基于F P G A的功放遥控控制系统的设计与实现[D].成都:电子科技大学,2015(3):2933.[9]胥加林,游安华,皮大伟.基于单片机的智能红外遥控开关[J].机械制造与自动化,2016(4):200201.[10]肖广兵,万茂松,羊玢.A RM嵌入式开发实例[M].北京:电子工业出版社,2013.胡进德(副教授),主要研究方向为嵌入式系统㊁机电一体化㊂(责任编辑:薛士然收稿日期:2019-05-27)。

自己调试的遥控器红外解码(1602)液晶显示

/*-----------------------------------------------名称:遥控器红外解码液晶显示公司:上海浩豚电子科技有限公司编写:师访日期:2009.5修改:无内容:------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include<stdio.h>#include<intrins.h>#define TURE 1#define FALSE 0sbit IR=P3^2; //红外接口标志sbit RS = P2^4;//Pin4sbit RW = P2^5;//Pin5sbit E = P2^6;//Pin6#define Data P0//数据端口unsigned int hour,minute,second,count;char code Tab[16]="0123456789ABCDEF";char data TimeNum[]=" ";char data Test1[]=" ";/******************************************************************//* 变量声明*//******************************************************************/unsigned char irtime;//红外用全局变量bit irpro_ok,irok;unsigned char IRcord[4]; //处理后的红外码,分别是客户码,客户码,数据码,数据码反码unsigned char irdata[33]; //33个高低电平的时间数据/******************************************************************//* 函数声明*/void Ir_work(void);void Ircordpro(void);void ShowString (unsigned char line,char *ptr);/******************************************************************//* 定时器0中断服务函数*//******************************************************************/void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数{irtime++; //用于计数2个下降沿之间的时间}/******************************************************************//* 外部中断0函数*//******************************************************************/ void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数{static unsigned char i; //接收红外信号处理static bit startflag; //是否开始处理标志位if(startflag){if(irtime<63&&irtime>=33)//引导码TC9012的头码,9ms+4.5msi=0;irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1irtime=0;i++;if(i==33){irok=1;i=0;}}else{irtime=0;startflag=1;}}/******************************************************************//* 定时器0初始化*/void TIM0init(void)//定时器0初始化{TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值TH0=0x00; //重载值TL0=0x00; //初始化值ET0=1; //开中断TR0=1;}/******************************************************************/ /* 外部中断初始化*/ /******************************************************************/ void EX0init(void){IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)EX0 = 1; //使能外部中断EA = 1; //开总中断}/******************************************************************/ /* 红外键值处理*/ /******************************************************************/void Ir_work(void) //红外键值散转程序{TimeNum[5] = Tab[IRcord[0]/16]; //处理客户码并显示TimeNum[6] = Tab[IRcord[0]%16];TimeNum[8] = Tab[IRcord[1]/16]; //处理客户码并显示TimeNum[9] = Tab[IRcord[1]%16];TimeNum[11] = Tab[IRcord[2]/16]; //处理数据码并显示TimeNum[12] = Tab[IRcord[2]%16];TimeNum[14] = Tab[IRcord[3]/16]; //处理数据反码并显示TimeNum[15] = Tab[IRcord[3]%16];ShowString(1,TimeNum);//显示处理过后的码值irpro_ok=0; //处理完成后清楚标志位}/******************************************************************/ /* 红外解码函数处理*/ /******************************************************************/ void Ircordpro(void)//红外码值处理函数{unsigned char i, j, k;unsigned char cord,value;k=1;for(i=0;i<4;i++) //处理4个字节{for(j=1;j<=8;j++) //处理1个字节8位{cord=irdata[k];if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差{value=value|0x80;}else{value=value;}if(j<8){value=value>>1;}k++;}IRcord[i]=value;value=0;} irpro_ok=1;//处理完毕标志位置1}/******************************************************************//* 微秒延时函数*//******************************************************************/void DelayUs(unsigned char us)//delay us{unsigned char uscnt;uscnt=us>>1;/* Crystal frequency in 12MHz*/while(--uscnt);}/******************************************************************//* 毫秒函数声明*//******************************************************************/void DelayMs(unsigned char ms)//delay Ms{while(--ms){DelayUs(250);DelayUs(250);DelayUs(250);DelayUs(250);}}/******************************************************************/ /* 写入命令函数*/ /******************************************************************/ void WriteCommand(unsigned char c){DelayMs(5);//操作前短暂延时,保证信号稳定E=0;RS=0;RW=0;_nop_();E=1;Data=c;E=0;}/******************************************************************/ /* 写入数据函数*/ /******************************************************************/ void WriteData(unsigned char c){DelayMs(5); //操作前短暂延时,保证信号稳定E=0;RS=1;RW=0;_nop_();E=1;Data=c;E=0;RS=0;}/******************************************************************/ /* 写入字节函数*/ /******************************************************************/ void ShowChar(unsigned char pos,unsigned char c){unsigned char p;if (pos>=0x10)p=pos+0xb0; //是第二行则命令代码高4位为0xcelsep=pos+0x80; //是第二行则命令代码高4位为0x8WriteCommand (p);//写命令WriteData (c); //写数据}/******************************************************************/ /* 写入字符串函数*/ /******************************************************************/ void ShowString (unsigned char line,char *ptr){unsigned char l,i;l=line<<4;for (i=0;i<16;i++)ShowChar (l++,*(ptr+i));//循环显示16个字符}/******************************************************************/ /* 初始化函数*/ /******************************************************************/ void InitLcd(){DelayMs(15);WriteCommand(0x38); //display modeWriteCommand(0x38); //display modeWriteCommand(0x38); //display modeWriteCommand(0x06); //显示光标移动位置WriteCommand(0x0c); //显示开及光标设置WriteCommand(0x01); //显示清屏}/******************************************************************/ /* 主函数*/ /******************************************************************/void main(void){EX0init(); //初始化外部中断TIM0init();//初始化定时器InitLcd(); //初始化液晶DelayMs(15);sprintf(Test1," "); //显示第一行固定信息ShowString(0,Test1);sprintf(TimeNum,"Code ");//显示第二行固定信息ShowString(1,TimeNum);while(1)//主循环{if(irok) //如果接收好了进行红外处理{Ircordpro();irok=0;}if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等{Ir_work();}}}。

STC15单片机红外遥控编码采集在LCD1602上显示程序

敬告:没有51单片机基础的人请慎重下载高质量实用性51单片机STC15W系列程序(5),STC8A系列可参考STC15单片机红外遥控编码采集在LCD1602上显示程序注:此程序比较复杂,但非常有助于提高编程水平,程序中有些小技巧希望大家能够学会用法/*******************************************///main.c#include "Library.h"void ValToStr(unsigned char *str,unsigned char *tmp);void main(){unsigned char rec_buf[4];unsigned char tmpbuf[4];unsigned char strbuf[8];bit fra;P5M1 &= 0xDF; P5M0 &= 0xDF;P2M1 &= 0xE5; P2M0 &= 0xE5;P0M1 = 0x00; P0M0 = 0x00;Timer0_config();LCD1602_init();LCD1602_wBytes(0,0,"usercode:",sizeof("usercode:")-1);LCD1602_wBytes(0,1,"key code:",sizeof("keycode:")-1);EA = 1;while(1){fra = Rep_pro(rec_buf);if(fra){fra = 0;tmpbuf[0] = rec_buf[0];tmpbuf[1] = rec_buf[2];tmpbuf[2] = rec_buf[3];tmpbuf[3] = rec_buf[1];if((~tmpbuf[2])==tmpbuf[1]){ValToStr(strbuf,tmpbuf);LCD1602_wBytes(10,0,strbuf,2);LCD1602_wBytes(13,0,strbuf+6,2);LCD1602_wBytes(10,1,strbuf+2,2);LCD1602_wBytes(13,1,strbuf+4,2);}}}}//void ValToStr(unsigned char *str,unsigned char *tmp)//{// str[0] = tmp[0]/10 + '0';// str[1] = tmp[0]%10 + '0';// str[2] = tmp[1]/10 + '0';// str[3] = tmp[1]%10 + '0';// str[4] = tmp[2]/10 + '0';// str[5] = tmp[2]%10 + '0';// str[6] = tmp[3]/10 + '0';// str[7] = tmp[3]%10 + '0';////}void ValToStr(unsigned char *str,unsigned char *tmp) {if(((tmp[0]>>4)&0x0F)<=9){str[0] = ((tmp[0]>>4)&0x0F)+ '0';}else{str[0] = ((tmp[0]>>4)&0x0F) - 10 + 'A';}if((tmp[0]&0x0F)<=9){str[1] = (tmp[0]&0x0F) + '0';}else{str[1] = (tmp[0]&0x0F) - 10 + 'A';}if(((tmp[1]>>4)&0x0F)<=9){str[2] = ((tmp[1]>>4)&0x0F) + '0';}else{str[2] = ((tmp[1]>>4)&0x0F) - 10 + 'A'; }if((tmp[1]&0x0F)<=9){str[3] = (tmp[1]&0x0F) + '0';}else{str[3] = (tmp[1]&0x0F) - 10 + 'A';}if(((tmp[2]>>4)&0x0F)<=9){str[4] = ((tmp[2]>>4)&0x0F)+ '0';}else{str[4] = ((tmp[2]>>4)&0x0F) - 10 + 'A'; }if((tmp[2]&0x0F)<=9){str[5] = (tmp[2]&0x0F)+ '0';}else{str[5] = (tmp[2]&0x0F) - 10 + 'A';}if(((tmp[3]>>4)&0x0F)<=9){str[6] = ((tmp[3]>>4)&0x0F)+ '0';}else{str[6] = ((tmp[3]>>4)&0x0F) - 10 + 'A'; }if((tmp[3]&0x0F)<=9){str[7] = (tmp[3]&0x0F) + '0';}else{str[7] = (tmp[3]&0x0F) - 10 + 'A';}}/*******************************************///红外程序//Infrared.c/**********************************guide code: 9ms low +4.5ms highbit 0 : 560us low + 560us highbit 1 : 560us low + 1.68ms highguide code,user code,user inverse code,key code,key inverse code,stop bit**********************************/#include "Library.h"bit guideflag = 1;bit bitHH;bit bitH;bit bitM;bit bitL;bit flagH1;//bit flagH2;bit IR1;bit IR2;bit rep;unsigned int cnt;unsigned char tmpbuf[32];bit frameflag;bit bitval;bit win;bit rep_back;unsigned char recbuf[4];bit Infrared_monitor(){bit ack;cnt++;IR2 = IR1;IR1 = inf;if(IR2&&(!IR1)){if(cnt>280){IR2 = 0;IR1 = 0;cnt = 0;ack = 0;return 0;}}else if((!IR2)&&IR1){if((cnt>=170)&&(cnt<=190)){flagH1 = 1;}else{return 0;}}if(flagH1){if(IR2&&(!IR1)){if((cnt>=260)&&(cnt<=280)){guideflag = 0;flagH1 = 0;IR2 = 0;IR1 = 0;cnt = 0;ack = 1;}}}return ack;}void Rec_bit(){cnt++;IR2 = IR1;IR1 = inf;if(IR2&&(!IR1)){if(cnt>50){IR2 = 0;IR1 = 0;cnt = 0;return;}}if((!IR2)&&IR1){if((cnt>=10)&&(cnt<=14)){bitH = 1;}{return;}}if(bitH){if(IR2&&(!IR1)){if((cnt>=40)&&(cnt<=50))//2240{bitH = 0;IR2 = 0;IR1 = 0;cnt = 0;win = 1;bitval = 1;}elseif((cnt>=20)&&(cnt<=25))//1120{bitH = 0;IR2 = 0;IR1 = 0;cnt = 0;win = 1;bitval = 0;}}}// else if(!bitH)// {//// }// if(inf&&bitH)// {// }// else if((cnt>=40)&&(cnt<=50))//2240// {// bitH = 0;// cnt = 0;// win = 1;// bitval = 1;// }// else if((cnt>=20)&&(cnt<=25))//1120 // {// bitH = 0;// cnt = 0;// win = 1;// bitval = 0;// }}unsigned char Rec_dat(){// bit 0 : 560us low + 560us high// bit 1 : 560us low + 1680ms high unsigned char codeval;unsigned char mask;static unsigned char j=0;for(mask=0x80;mask!=0;mask>>=1){if(tmpbuf[j]){codeval |= mask;}else{codeval &= ~mask; }j++;if(j>=32){j = 0;}}return codeval;}bit Rep_pro(unsigned char *rbuf)bit fram;static unsigned char i = 0;if(win){win = 0;tmpbuf[i] = bitval;i++;if(i>=32){i = 0;frameflag = 1;rep_back = 0 ;rbuf[0] = Rec_dat();rbuf[1] = Rec_dat();rbuf[2] = Rec_dat();rbuf[3] = Rec_dat();frameflag = 0;guideflag = 1;fram = 1;}}return fram;//void Infrared_receive(unsigned char *buf) //{// buf[0] = Rec_dat();// buf[1] = Rec_dat();// buf[2] = Rec_dat();// buf[3] = Rec_dat();// rep = 1;//}void Timer0_config(){// unsigned long tmp;// tmp = (MAIN_Fosc*us)/1000;// tmp = tmp /1000;// tmp = 65536 - tmp;// TH0 = (unsigned char)(tmp>>8);// TL0 = (unsigned char)tmp;TH0 = 0xFD;TL0 = 0xD7;TMOD &= 0xF0;TMOD |= 0x01;AUXR |= 0x80;ET0 = 1;TR0 = 1;}void Timer0_interrupt() interrupt 1{TH0 = 0xFD;TL0 = 0xD7;if(guideflag){rep_back = Infrared_monitor();// if(rep_back==0)// {// cnt = 0;// flagH1 = 0;// flagH2 = 0;// }}if((!guideflag)&&(!frameflag)){Rec_bit();}}/********************************************* //LCD1602.c#include "Library.h"void LCD1602_rsta(){unsigned char tmp;P0 = 0xFF;//this is a mustrs = 0;rw = 1;do{en = 1;//Delay1us();tmp = P0;//Delay1us();en = 0;}while(tmp&0x80);}void LCD1602_wdat(unsigned char dat) {LCD1602_rsta();rs=1;rw=0;P0 = dat;en = 1;//Delay1us();en = 0;}void LCD1602_wcmd(unsigned char cmd){LCD1602_rsta();rs=0;rw=0;P0 = cmd;en = 1;//Delay1us();en = 0;}void Setcursor(unsigned char x,unsigned char y) {if(y==0)x = x + 0x00;else if(y==1)x = x + 0x40;LCD1602_wcmd(x|0x80);}void LCD1602_wBytes(unsigned char x,unsigned char y,unsigned char *buf,unsigned char buf_len){Setcursor(x,y);while(buf_len>0){LCD1602_wdat(*buf++); buf_len--;}}void OnCursor(){LCD1602_wcmd(0x0F);}void OffCursor(){LCD1602_wcmd(0x0C);}void LCD1602_init(){// Delay15ms();// LCD1602_wcmd(0x38);// Delay5ms();LCD1602_wcmd(0x38);// LCD1602_wcmd(0x08);LCD1602_wcmd(0x06);LCD1602_wcmd(0x0C);LCD1602_wcmd(0x01);}/****************************************///Library.h#ifndef _Library_H#define _Library_H#include <STC15.h>#include <intrins.h>#define MAIN_Fosc 11059200Lsbit inf = P5^5;void Timer0_config();bit Infrared_monitor();//void Infrared_monitor();bit Rep_pro(unsigned char *rbuf);sbit rs = P2^4;sbit rw = P2^3;sbit en = P2^1;void LCD1602_init();void LCD1602_wBytes(unsigned char x,unsigned char y,unsigned char *buf,unsigned char buf_len);#endif。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机原理课程设计与调试课题名称:遥控器红外解码数液晶显示专业班级:电子信息科学与技术(2)班学生学号: 1114040218 学生姓名:刘家玲设计时间:2013年6月17日遥控器红外解码数液晶显示一.红外遥控器编码遥控器编码分好几种,常见的32位编码码和42位编码码,目前我手中遥控器就是42位编码,如图1所示,当有按键时就会产一个9.12ms低电平和4.5ms高电平的起始码,紧接着是26位系统码,此系统码能区别不同的电器设备,防止不同机种遥控码互相干扰,接下来是8位数据码和8位数据反码,间隔23ms的高电平后,再发一个与启始码完全一样的结束码:控制整个电路的运行。

其外围电路主要有两部分:复位电路和晶体振荡器。

二、电路图三、调试四、解码 就对其进行解码,所谓解码就是能用单片机把以不同宽度的脉冲区别开来,一种比较好思路就是计算两次下降沿间隔时间,当单片机外部中断1口有下降沿时中断一次,并启动定时器,定时器定50us,当下次下降沿到来时我们计算定时器中断的次数,这样我们就能很好的区分不同宽度的脉冲了。

实际上,我们红外接收头收到的信号的是有毛刺的,放大后就如下图,所以在下降沿中断触发后,要做延时去抖处理:五、完整解码程序ORG 0000HAJMP MAIN;转入主程序ORG 0003H ;外部中断P3.2 脚INT0 入口地址AJMP INTMAIN: SETB EA ;打开CPU 总中断请求SETB IT0 ;设定INT0 的触发方式为脉冲负边沿触发SETB EX0LJMP STARTUP1(C:01FD)LJMP EX0_ISR(C:00A2)INC irtime(0x22)RETINOPNOPINTO: LJMP tim0_isr(C:0006)MOV A,IRcord(0x33) //处理客户码十六进制高位 SWAP AANL A,#0x0FMOV DPTR,#Tab(0x0145)MOVC A,@A+DPTRMOV TempData(0x23),AMOV A,IRcord(0x33)ANL A,#0x0FMOVC A,@A+DPTRMOV 0x24,AMOV 0x25,#0x2D //处理客户码 MOV A,0x34SWAP AANL A,#0x0FMOVC A,@A+DPTRMOV 0x26,AMOV A,0x34MOVC A,@A+DPTRMOV 0x27,AMOV 0x28,#0x2D //处理数据码 MOV A,0x35SWAP AANL A,#0x0FMOVC A,@A+DPTRMOV 0x29,AMOV A,0x35ANL A,#0x0FMOVC A,@A+DPTRMOV 0x2A,AMOV 0x2B,#0x2D //处理数据反码MOV A,0x36SWAP AANL A,#0x0FMOVC A,@A+DPTRMOV 0x2C,AMOV A,0x36ANL A,#0x0FMOVC A,@A+DPTRMOV 0x2D,AMOV R3,#0x00MOV R2,#0x00TempData: MOV R1,#TempData(0x23)MOV R5,#0x01MOV R7,#0x05LCALL LCD_Write_String(C:0155)//处理完成标志 CLR irpro_ok(0x20.1) //初始化外部中断RETLCALL EX0init(C:0215) //初始化定时器LCALL TIM0init(C:01F0) //初始化液晶LCALL LCD_Init(C:0109)MOV R7,#0x14 //延时有助于稳定MOV R6,#0x00LCALL DelayMs(C:0198)LCALL LCD_Clear(C:0209) //清屏MOV R3,#0xFFMOV R2,#0x01MOV R1,#0x30LCALL : LCD_Write_String(C:0155)MOV R3,#0xFFMOV R2,#0x01MOV R1,#0x3FMOV R5,#0x01CLR AMOV R7,ALCALL LCD_Write_String(C:0155)//如果接收好了进行红外处理JNB irok(0x20.0),C:009A //红外码处理LCALL Ircordpro(C:00D8)CLR irok(0x20.0)//如果处理好后进行工作处理,如按对应的按键后显示对应的数字等JNB irpro_ok(0x20.1),C:0092LCALL Ir_work(C:000E)SJMP C:0092//外部中断0服务函数PUSH : PUSH ACC(0xE0)//接收红外信号处理PUSH PSW(0xD0)MOV PSW(0xD0),#0x00PUSH 0x00MOV A,irtime(0x22)CLR CSUBB A,#0x21JC C:00BBIrtime : MOV A,irtime(0x22)SUBB A,#0x3FJNC C:00BBMOV 0x21,#0x00 //存储每个电平的持续时间,用于以后判断是0还是1ADD A,0x21MOV R0,AMOV @R0,irtime(0x22)MOV irtime(0x22),#0x00MOV A,0x21CJNE A,#0x21,C:00D1SETB irok(0x20.0)MOV 0x21,#0x00POP 0x00POP PSW(0xD0)POP ACC(0xE0)RETI //红外码值处理函数MOV R6,#0x01CLR AMOV R5,AMOV R4,#0x01MOV A,#irdata(0x37)ADD A,R6MOV R0,AMOV A,@R //大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差SETB CSUBB A,#0x07JC C:00EBORL 0x07,#P0(0x80)CLR CMOV R7,AINC R6INC R4CJNE R4,#0x09,C:00DEMOV A,#IRcord(0x33)ADD A,R5CJNE R5,#0x04,C:00DC//处理完毕标志位置1SETB irpro_ok(0x20.1)/*显示模式设置*/LCALL C:0179MOV R7,#0x05MOV R6,#0x00LCALL DelayMs(C:0198)LCALL C:0179 /*显示关闭*/MOV R7,#0x08LCD_Write_Com: LCALL LCD_Write_Com(C:0187) //显示清屏 MOV R7,#0x01LCALL LCD_Write_Com(C:0187)//显示光标移动设置MOV R7,#0x06LCALL LCD_Write_Com(C:0187)LCALL DelayMs(C:0198)MOV R7,#0x0CLJMP LCD_Write_Com(C:0187)MOV @R1,#0x77MOV @R1,#0x2EJNB 0x26.1,C:017AADDC A,#0x35ORL A,@R0MOV R6,0x07MOV A,R5JNZ C:015F //表示第一行ADD A,#P0(0x80)SJMP C:0162 //表示第二行MOV A,R6ADD A,#0xC0LCALL LCD_Write_Com(C:0187)LCALL C?CLDPTR(C:01B6)MOV R7,AJZ C:0178LCD_Write_Data: LCALL LCD_Write_Data(C:01CF) MOV A,#0x01SJMP C:0166MOV R7,#0x38LCALL LCD_Write_Com(C:0187)MOV R7,#0x05MOV R6,#0x00LCALL DelayMs(C:0198)MOV R7,#0x38LCD_Check_Busy(C:01E0)LCD_Write_Com(C:0187)CLR RS(0x90.0)CLR RW(0x90.1)JNZ DelayMs(C:0198)DEC R6SJMP DelayMs(C:0198)CJNE R3,#0x01,C:01BFMOV DPL(0x82),R1MOV DPH(0x83),R2CJNE R3,#0xFE,C:01C8MOVX A,@R1MOV DPL(0x82),R1MOV DPH(0x83),R2MOVC A,@A+DPTRBUSY: LCALL LCD_Check_Busy(C:01E0) //忙则等待 JC LCD_Write_Data(C:01CF)SETB RS(0x90.0)CLR RW(0x90.1)SETB EN(0x90.2)MOV P0(0x80),R7CLR EN(0x90.2)MOV P0(0x80),#0xFFCLR RS(0x90.0)SETB RW(0x90.1)CLR EN(0x90.2)SETB EN(0x90.2)MOV A,P0(0x80)MOV TMOD(0x89),#0x02 //定时器0初始化CLR A//重载值MOV TH0(0x8C),A//定时器0工作方式2,TH0是重装值,TL0是初值MOV TL0(0x8A),A //初始化值SETB ET0(0xA8.1) //开中断SETB TR0(0x88.4)//计时开始MOV R0,#IDATALEN - 1MOV R0,#0x7FMOV @R0,AMOV @R0,ADJNZ R0,IDATALOOPDJNZ R0,IDATALOOP(C:0200)MOV SP(0x81),#0x57LJMP main(C:0066)MOV R7,#0x01LCALL LCD_Write_Com(C:0187)MOV R7,#0x05MOV R6,#0x00LJMP DelayMs(C:0198)SETB IT0(0x88.0) //使能外部中断SETB EX0(0xA8.0) //开总中断SETB EA(0xA8.7)RETEND六、心得体会通过单片机解码红外遥控lcd1602的显示,让我对红外模块有了新的认识。

这次设计运用到的知识很多方面,尤其是单片机,像AT89C51,引脚多,硬件内部线路接通,所以用起来很方便,还有lcd1602与单片机之间的连接,以及如入使用lcd。

要对其时序图有深入的了解。

相关文档
最新文档