标签:
[注]:
一眨眼,大学接近尾声,具有找工作需要,所以把大学做的电子设计“劣作”放上来。希望考研失意,还能赶上“好工作”的春招班车。如果大伙有什么工作推荐也可以联系我哦,因为一年考研少接触了这方面,所以难免有些生疏。但请相信我!给我机会我会很认真学的!
邮箱:lydmom@163.com
转载请注明出处呀!
基于51单片机的红外遥控课程设计
目录
第一章 设计简介... 3
第二章 系统方案... 3
一、设计方案对比... 3
二、方案设计... 4
第三章 硬件设计... 5
一、红外遥控器... 5
二、红外接收模块部分... 7
第四章 软件设计... 8
一、红外遥控器软件设计... 8
二、红外接收模块软件设计... 11
三、程序代码... 11
第五章 测试及分析... 11
第六章 结论... 11
第七章 参考文献... 12
附录一(程序代码):... 13
本设计分为红外遥控器与红外接收模块两部分。红外遥控器包括矩阵键盘、增强型51单片机(STC11L04E)、红外发射电路组成。单片机扫描矩阵键盘后,将按键状态进行信源编码与信道编码,载波(38k脉冲)后由红外发射器发射。红外接收模块部分由传统51单片机、数码管、一体化红外接收头组成。一体化红外接收头将信号进行限幅放大、带通滤波、解调、积分、整形后输出解调信号至单片机,并由单片机输出解调信号。
2.1.1 主控芯片
方案一:HT6222
方案二:STC11L04E
分析 :传统红外遥控器芯片HT6222具有性价比高、功能强大、稳定可靠、使用简单等特点,但该芯片难以零购。STC11L04E为增强型51单片机,控制灵活(载波频率可调、通信协议可变更、用户码可变换)、价格较HT6222稍贵。STC11L04E最大的特别是低功耗,功作电压低3.3V,易于应用于移动设备。
结论 :由于STC11L04E单片机的灵活性以及学习性(可增强我们对一个完整通信系统的理解)。因此我们采用方案二。
2.1.2 矩阵键盘
方案一:3*6*2.5 贴片轻触开关
方案二:6*6*6 直插轻触开关
分析 :3*6*2.5贴片轻触开关虽然体积小巧、美观,但与6*6*6直插轻触开关对比,在制板布线上较繁锁。
结论 :综上,我们采用6*6*6直插轻触开关,使得整体布线简单,可布单面版,简化制板流程。
2.1.3电源模块
方案一:钮扣电池CR2032
方案二:可充电锂电池18650
分析 : 可充电锂电池18650容量大,节能环保(可多次利用),但体积大。钮扣电池CR2032价格低廉、替换容易、体积轻巧。
结论 :基于红外遥控器的便携性考虑,我们采用方案一。
2.1.4 红外发射管
方案一:3mm 红外发射管
方案二:5mm 红外发射管
分析 :方案一与方案二的区别在于直径越大发射管发射距离更远、信号稳定。
结论 :鉴于发射距离,我们采用5mm 红外发射管。
2.1.5电源电路
方案一:线性电源AMS1117。AMS1117系列。
方案二:开关电源LM2576。
分析 :AMS1117系列含有可调(ADJ)与固定输出两种。AMS1117具有性价比高、体积小、外部电路简单、输出电流大(800mA)、最大输入电压达16V等特点。其固定输出AMS1117-5.0甚至可以在仅加一个SS14二极管的情况下稳定工作,但为了增强其稳定性,我们在其输出输入端各加一个10uF电解电容。LM2576系列开关,稳压集成电路是线性三端稳压器件的替代品,它具有可靠的工作性能,较高的工作效率,和较强的输出电流驱动能力,从而可为单片机的稳定可靠工作提供强有力的保证。
结论 :虽然LM2576性能极佳,但在本系统对于体积、外部电路、性价比的要求上进行衡量。我决定采用AMS1117-5.0作为供电系统。
(图2.2.a红外遥控器部分)
(图2.2.b红外接收模块部分)
单片机由CR2032钮扣电池供电。STC11L04E对矩阵键盘进行按键扫描,并将按键状态进行信源编码、信道编码,载波后由红外发射管向外发射信号。
(图3.1.a )
单片机电源由AMS1117-5.0芯片供电。STC89C52将一体化红外接收器传来的信号进行解调,并输出显示至数码管。
(图3.1.a )
(图4.1.a 主函数)
(图4.1.b 发送一串数据)
(图4.1.c 定时器0中断)
(图4.1.d 发送一字节)
(略)
(见附录一)
测试量 |
参数 |
传输距离 |
|
误码率 |
|
[1] 《HT6122.pdf》 NEC著
[2] 《全面了解红外遥控》 San Bergmans著
[3] 《STC11L04E.pdf》 宏晶科技著
[4] 《例说51单片机(C语言版)(第3版)》 张义和著
[5] 《模拟电子技术基础(第四版)》 华成英.童诗白著
[6] 《Altium Designer原理图与PCB设计》 穆秀春著
[7] 《通信原理》 樊昌信著
[8] 《通信原理》 周烔槃著
红外遥控器程序
/*----------------------Item Description----------------------------------- - Project Name : IR_Remote/基于单片机的红外遥控课程设计 - Files : - Description : 本设计基于单片机的红外遥控,具有稳定可靠、指令、 地址可自定义、控制距离远等特点。 - IDE : Keil uVision4 - Author : Mason 别名:小菜 - Email Address : 1609099954@qq.com - Create Date : 2013/6/7 - Performance : Finished - ------------------------------------------- - Revision History - No. Date Revised by Item Description - -------------------------------------------------------------------------*/ /*----------------------------Head---------------------------------------*/ #include <reg52.H> #include "keyboard3_3.H" #include "IR_Tran.H" /*----------------------------Grobal Variable----------------------------*/ char cmd=0,lastcmd=0,ctemp; /*----------------------------Code---------------------------------------*/ void main() { IRtimer_Init(); while(1) { ctemp = scankeyboard3_3(); if(ctemp!=NULL) cmd = ctemp;
if(cmd != lastcmd){ IR_send(cmd); lastcmd = cmd; } } } |
/*----Head Description---- - File Name : IR_Tran.H - Author : Mason 别名:小菜 - Create Date : 2013/6/7 - ------------------------------------------- - Revision History - No. Date Revised by Item Description - -------------------------------------------------------------------------*/ #ifndef _IR_TRAN_H_ #define _IR_TRAN_H_
#include "MICRO.H"
void IRtimer_Init(void); // 定时器初使化 void IR_Pulse(void); // 频率为精准38k方波(截波) void IR_send(char cmd); // 发送指令
#endif |
/*----File Description---- - File Name : IR_Tran.c - Functions : void IRtimer_Init(void);void IR_Pulse(void); void timer0() interrupt 1 void IR_send(char cmd); - Description : 红外遥控的驱动程序,调节IR_Pulse函数中的dt可将 程序从传统51单片机移殖至增强型(1T)51单片机。 更改iraddr的值可以改变遥控器的地址。 本设计的晶振采用12M,但实际中只有11.89M,因此为了 使遥控器反应更准确,需根据实际振荡频率调节 void IR_Pulse(void)的延时环节,最终使用频率计测试. - Author : Mason 别名:小菜 - Create Date : 2013/6/7 - Performance : Finished - Global Variable : None - File static Variable : None - ------------------------------------------- - Revision History - No. Date Revised by Item Description - -------------------------------------------------------------------------*/ /*----------------------------Head---------------------------------------*/ #include <reg52.H> #include "MICRO.H" #include "intrins.H" /*----------------------------Micro--------------------------------------*/ // 由于晶振有误差,以下测量值是用示波器调试出来的,晶振此时频率11.89M #define TH0_0P ((65536-544)/256) // 560us #define TL0_0P ((65535-544)%256) #define TH0_0 ((65536-515)/256) // 560us #define TL0_0 ((65536-515)%256) #define TH0_1 ((65536-1650)/256) // 1690us #define TL0_1 ((65535-1650)%256)
sbit IR_OP = P3^7; /*----------------------------Grobal Variable----------------------------*/ bit timer_f = 1; // 定时器计时状态位 char const iraddr = 0xff; // 遥控器本机地址 char temp; // 程序引用的临时变量 /*----------------------------Code---------------------------------------*/ void IRtimer_Init(void) // 定时器初使化 { TMOD = 0x01; // 16 bit timer EA = 1; ET0 = 1; }
void IR_Pulse(void) // 频率为精准38k方波(截波) { // 需根据实际原器件而定。 unsigned char dt ; // 本设计实际晶振频率为11.89M IR_OP = 0; // 增强型单片机请将延时环节的 for(dt = 71;dt>0;dt--); // 延时系数"dt = 7"改为"dt = _nop_(); // 71" IR_OP = 1; // 由于发射管采用共射放大电路, } // 故载波为下降沿脉冲。
void timer0() interrupt 1 // 定时器中断 { timer_f = 0; } void IR_Send_Byte(char ca) // cmd or addr { for(temp = 0x01;temp != 0x00;temp <<= 1) { TR0 = 0; TH0 = TH0_0P; // 560us高电平 TL0 = TL0_0P; timer_f = 1; TR0 = 1; while(timer_f) IR_Pulse();
if((temp&ca) == 0){ TH0 = TH0_0; // 560us低电平 TL0 = TL0_0; }else{ TH0 = TH0_1; // 1690us低电平 TL0 = TL0_1; } timer_f = 1; while(timer_f); } }
void IR_send(char cmd) // 发送指令 { TH0 = (65536-9000)/256; // 9ms前导高电平 TL0 = (65535-9000)%256; TR0 = 1; timer_f = 1; while(timer_f) IR_Pulse(); // 载波 TH0 = (65536-4500)/256; // 4.5ms前导低电平 TL0 = (65535-4500)%256; timer_f = 1; while(timer_f); // 延时
// 发送地址原码 IR_Send_Byte(iraddr);
// 发送地址反码 IR_Send_Byte(~iraddr);
// 发送操作原码 IR_Send_Byte(cmd);
// 发送操作反码 IR_Send_Byte(~cmd);
TR0 = 0; // 560us后导脉冲序列 TH0 = TH0_0P; TL0 = TL0_0P; timer_f = 1; TR0 = 1; while(timer_f) IR_Pulse();
TR0 = 0; } |
/*----Head Description---- - File Name : keyboard3_4.h - Author : Mason 别名:小菜 - Create Date : 2013/6/7 - ------------------------------------------- - Revision History - No. Date Revised by Item Description - -------------------------------------------------------------------------*/ #ifndef __KEYBOARD3_3_H__ #define __KEYBOARD3_3_H__
/*********************************************************** *scankeyboard3*4:return 0_12 by every touch, else return 16* ***********************************************************/
#define NULL -1 extern char scankeyboard3_3(void);
#endif |
/*----File Description---- - File Name : keyboard3_3.c - Functions : - Description : None
- Author : Mason 别名:小菜 - Create Date : 2013/6/7 - Performance : Finished - Global Variable : None - File static Variable : None - ------------------------------------------- - Revision History - No. Date Revised by Item Description - -------------------------------------------------------------------------*/ /*----------------------------Head---------------------------------------*/ #include "keyboard3_3.h" #include <keyboard3_3.h> #include <reg52.h>
/*----------------------------Micro--------------------------------------*/ /********************************************************* *keyboard3*3:return 0-12 by every touch, else return null* *********************************************************/ #define KEYB P1 char scannum[3]={0xfe,0xfd,0xfb};
/*----------------------------Code---------------------------------------*/ /*Oscillator frequence choose 11.0592MHz ,the debouncert is 600 Oscillator frequence choose 12MHz,the debouncert is 700*/ void debouncer() { unsigned int debouncert; for(debouncert=328;debouncert>0;debouncert--); } char scankeyboard3_3(void) { char column,row; for(row = 0;row < 3;row++) { KEYB = scannum[row]; debouncer(); column = (~KEYB)&0x0f; if(column != 0){ switch(column) { case 0x20:{column = 0; break;} case 0x40:{column = 1; break;} case 0x80:{column = 2; break;} } while((~KEYB&0x0e)!=0); // 去除长按 debouncer(); return (row*3+column); } } return NULL; } |
/*----Head Description---- - File Name : MICRO_H - Author : Mason 别名:小菜 - Create Date : 2013/3/5 - ------------------------------------------- - Revision History - No. Date Revised by Item Description - -------------------------------------------------------------------------*/
#ifndef _MICRO_H_ #define _MICRO_H_
//#include <STC12C5A.H> #include <reg52.H>
//MICRO typedef unsigned int uint16; typedef int WORD; typedef long int DWORD; typedef unsigned char uchar; typedef char BYTE;
// ADC 启动转换 #define EN_ADC0 0xf8 // 选择 P1.n ADC引脚,并使能 ADC_START. #define EN_ADC1 0xf9 #define EN_ADC2 0xfa #define EN_ADC5 0xfd #define EN_ADC6 0xfe #define EN_ADC7 0xff
#endif |
红外接收模块程序
/*----------------------Item Description----------------------------------- - Project Name : IR_Receiver - Files : - Description : None
- IDE : Keil uVision4 - Author : Mason 别名:小菜 - Email Address : 1609099954@qq.com - Create Date : 2013/6/10 - Performance : Finished - ------------------------------------------- - Revision History - No. Date Revised by Item Description - -------------------------------------------------------------------------*/ /*----------------------------Head---------------------------------------*/ #include <reg52.H> #include "NixieTube.H" #include "MICRO.H" #include "IR.H" /*----------------------------Grobal Variable----------------------------*/ extern uchar IR_value[6];
/*----------------------------Code---------------------------------------*/ void main() { IR_init();
while(1); } |
/*----Head Description---- - File Name : IR.H - Author : Mason 别名:小菜 - Create Date : 2013/4/22 - ------------------------------------------- - Revision History - No. Date Revised by Item Description - -------------------------------------------------------------------------*/ /* 对应按键编码 - 45 46 47 - 44 40 43 - 07 15 09 - 16 19 0D - 0C 18 5E - 08 1C 5A - 42 52 4A -------------*/
#ifndef _IR_H_ #define _IR_H_
#define uchar unsigned char #define uint unsigned int
sbit IRIN = P3^2; // 红外传感器引脚
void IR_init(void); void IR_Delay(uchar t1); // 0.15ms
#endif |
/*----File Description---- - File Name : IR.c (infrared remoted control) - Functions : 该文件用于处理红外传感器信号。适用于传统51单片机 增强型51单片机需适当调速延时函数。晶振频率为12M。 占用外部中断0;不需定时器中断。只需调用IR_init(void); 便可从全局变量IR_value[4]/IR_value[5]分别读取红外用 户码(0x00)与操作码。 - Description : 对应按键编码: - 45 46 47 - 44 40 43 - 07 15 09 - 16 19 0D - 0C 18 5E - 08 1C 5A - 42 52 4A - Author : Mason 别名:小菜 - Create Date : 2013/4/22 - Performance : Finished - Global Variable : uchar IR_value[6]; - File static Variable : None - ------------------------------------------- - Revision History - No. Date Revised by Item Description - -------------------------------------------------------------------------*/ #include <reg52.H> #include "NixieTube.H" #include "IR.H"
uchar IR_value[6]; uint t = 0;
void IR_init(void) { IE |= 0x81; // EA = 1;EX0 =1;ET0=1; TCON |= 0x01; // IT0 = 1;下降沿触发 IRIN = 1; // 将引脚拉高 }
/*----Function Description---- - Function Name : void IR_Delay(uchar t1) - Description : 线性延时子函数 延时 t1*0.15ms - Return Code : None - Parameters/Arguments : None - Global Variable : None - static Variable : None -------------------------------------------------------------------------*/ void IR_Delay(uchar t1) // t1*0.15ms { uchar t2; while(t1--) for(t2=0;t2<13;t2++); }
/*----Function Description---- - Function Name : void IR_Get(void) - Description : 外部中断读到红外前导信号后调用。将4个字节的用 户码与操作码放于IR_value[0:3]中。 - Return Code : IR_value[0:3] - Parameters/Arguments : None - Global Variable : IR_value[0:3] - static Variable : None -------------------------------------------------------------------------*/ void IR_Get(void) { uchar i,j,k=0; IR_Delay(5); // 稍做延时,去除干扰,增强型单片机将5改为10 if(IRIN == 1) return; // 检测低电平是否有效 while(!IRIN); // 去除9ms前导低电平 while(IRIN) ; // 去除4.5ms前导高电平 for(i=0;i<4;i++) // 4个字节数据 { for(j=0;j<8;j++) // 8个位 { //while(IRIN) IR_Delay(1); while(!IRIN); // 去除560us while(IRIN) // 软件计时 { IR_Delay(1);// 将 1 改为 9 可移殖至12M 1T 单片机 k++; // 如STC 12C5A60S2 if(k>=30) {k=0; return;} // 时间过长自动返回 } IR_value[i] = IR_value[i] >> 1; if(k>=8) // k值可以有误差,但 k*软件计时(ms)>=0.56ms IR_value[i] = IR_value[i] | 0x80; k=0; // 清零 } } }
/*----Function Description---- - Function Name : 外部中断0 服务子程序 - Description : 用于检测红外前导电平信号,调用IR_Get(); 验证数据有效性,并将最终用户码与操作码分别存放于 IR_value[4:5]中。 - Return Code : IR_value[4:5] - Parameters/Arguments : None - Global Variable : IR_value[4:5] - static Variable : None -------------------------------------------------------------------------*/ void IR_ISR(void) interrupt 0 { EX0 = 0; // 关闭 外部中断0 IR_value[0] = IR_value[1] = IR_value[2] = IR_value[3] = 0 ; IR_Get(); // 读IR if(IR_value[0]==~IR_value[1] && IR_value[2]==~IR_value[3]){ IR_value[5] = IR_value[2]; // 保存指令 IR_value[4] = IR_value[0]; // 有效性验证,保存用户码 } Dis_Tube(IR_value[5]%16);
IE0 = 0; // 清空中断标志,防止在数据处理过程中产生中断请求 EX0 = 1; // 打开 外部中断0,准备接收下一条指令 } |
/*----Head Description---- - File Name : NixieTube.H - Author : Mason 别名:小菜 - Create Date : 2013/4/19 - ------------------------------------------- - Revision History - No. Date Revised by Item Description - -------------------------------------------------------------------------*/ #ifndef _NIXIETUBE_H_ #define _NIXIETUBE_H_
#include "MICRO.H" void Dis_Tube(uchar dat);
#endif |
/*----File Description---- - File Name : Nixietube.c - Functions : 数码管驱动程序 - Description : None
- Author : Mason 别名:小菜 - Create Date : 2013/4/19 - Performance : Finished - Global Variable : smg_table[18] - File static Variable : None - ------------------------------------------- - Revision History - No. Date Revised by Item Description - 1 6/11 mason none add -------------------------------------------------------------------------*/ /*----------------------------Head---------------------------------------*/ #include <reg52.h> #include "NixieTube.H" #include "MICRO.H" /*------------------------------Code Variable----------------------------*/ //共阴 char code smg_table[16]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x19, 0x11,0xc1,0xe5,0x85,0x61,0x71}; /*----------------------------Code---------------------------------------*/
void Dis_Tube(uchar dat) { P2 = smg_table[dat]; } |
标签:
原文地址:http://www.cnblogs.com/lydmom/p/4318121.html