标题:
单片机红外发射程序
[打印本页]
作者:
51黑z
时间:
2016-9-11 22:20
标题:
单片机红外发射程序
0.png
(72.85 KB, 下载次数: 148)
下载附件
2016-9-11 22:17 上传
本例程可以实现用stc的51单片机来控制进行红外线的发射,
完整keil工程文件下载:
http://www.51hei.com/bbs/dpj-55490-1.html
下面是部分程序代码的预览:
主程序:
#include "IR_SendCode.h"
#include "IR_SendDisp.h"
#include "IR_Receive.h"
#include "ChannelShortcutDef.h"
#include "Nokia5110.h"
#include "delay.h"
ChannelKey_TypeDef Channel_ShortKey;//定义通道&快捷键结构体
uint8_t IRSendOrRemote_Flag = Function_IRsend;//定义需要实现的是红外发射还是红外接收
void main(void)
{
IRsend_Init();
IRreceiver_Init();
Nokia5110_Init();
ReadE2P_ChannelShortKey();//读取设置的通道和快捷键
Nokia5110_DispChannelKey();//显示设置的通道和快捷键
while(1)
{
Funtion_KeyScan();
if(IRSendOrRemote_Flag == Function_IRsend) //红外发送功能实现
{
Set_ChannelShortKey();
ShortKeyScan_IRSendCode();
}
if(IRSendOrRemote_Flag == Function_IRremote)//红外接收功能实现
{
IRcode_Disp();
}
}
}
复制代码
STC89Cx_it.c
#include "STC89Cx_it.h"
#include "IR_Receive.h"
//红外解码原理:把红外中的载波解调成低电平,把红外中的低电平解调成高电平输出
//识别原理:识别一个完整周期的高低电平总时间来识别头码和"0"或"1"的值
#define Rev_Header 0x00 //数据接收状态:接收头码0xAA或oxAB
#define Rev_Length 0x01 //数据接收状态:接收头码数据包长度
#define Rev_DataPackage 0x02 //数据接收状态:接收数据包
extern uint8_t IRcode_Type; //声明收到的红外数据类型
extern uint8_t IRdataReceive_Flag;//声明接收红外数据状态,等待or接收中or接收完毕
extern uint32_t IRcode_Buffer; //红外数据缓存
uint8_t CycleTime = 0; //存储完整周期时间(高电平+低电平)
/**********************************************
函数:void INT0_Handler(void);
功能:外部中断0中断处理函数;
***********************************************/
void INT0_Handler(void) interrupt 0
{
}
/**********************************************
函数:void TIME0_Handler(void);
功能:定时器0中断处理函数;
***********************************************/
void TIME0_Handler(void) interrupt 1
{
CycleTime++;
if(CycleTime==255)CycleTime=0;
}
/**********************************************
函数:void INT1_Handler(void);
功能:外部中断1中断处理函数;
***********************************************/
void INT1_Handler(void) interrupt 2
{
static uint8_t EnterINT0_CNT = 0;//存储进入外部中断次数
static uint8_t Rev_State = Rev_Header;//定义接收状态
uint8_t CycleTime_Buffer=0; //周期时间缓冲变量
EnterINT0_CNT++; //每进入中断一次加1
//第一次进入中断周期清零,打开定时器0准备计时
if(EnterINT0_CNT==1)
{
CycleTime=0;
IRcode_Buffer=0;
TR0=1;
}
else//之后先读时间,再进行清零
{
CycleTime_Buffer=CycleTime;
CycleTime = 0;
}
//开始识别头码
if((Rev_State==Rev_Header)&&(EnterINT0_CNT==2))
{
Rev_State = Rev_DataPackage;
if((CycleTime_Buffer>60)&&(CycleTime_Buffer<100)) //头码时间位于6.0ms~10ms则为RCA码(标准8ms)
{
IRcode_Type = IRcode_TypeRCA;
}
else if((CycleTime_Buffer>110)&&(CycleTime_Buffer<160))//头码时间位于11ms~16ms(必须是大于11ms)则为NEC码(标准13.5ms)
{
IRcode_Type = IRcode_TypeNEC8;
}
else//如果都不是,则认为没有收到头码
{
TR0=0;
IRcode_Buffer = 0;
EnterINT0_CNT = 0;
Rev_State = Rev_Header;
}
}
if((Rev_State==Rev_DataPackage)&&(EnterINT0_CNT>2))//开始解码
{
IRcode_Buffer <<= 1;
switch(IRcode_Type)
{
case IRcode_TypeRCA:
{
if((CycleTime_Buffer>10)&&(CycleTime_Buffer<20))//码值时间位于1.0ms~2.0ms则为RCA'1'(标准1.5ms)
{
IRcode_Buffer |= (uint32_t)0x01;
}
else if((CycleTime_Buffer>20)&&(CycleTime_Buffer<30))//码值时间位于1.0ms~2.0ms则为RCA'0'(标准2.5ms)
{
IRcode_Buffer |= (uint32_t)0x00;
}
else
{
TR0=0;
IRcode_Buffer = 0;
EnterINT0_CNT = 0;
Rev_State = Rev_Header;
}
break;
}
case IRcode_TypeNEC8:
{
if((CycleTime_Buffer>6)&&(CycleTime_Buffer<16))//码值时间位于0.6ms~1.6ms则为NEC'0'(标准1.124ms)
{
IRcode_Buffer |= (uint32_t)0x00;
}
else if((CycleTime_Buffer>16)&&(CycleTime_Buffer<28))//码值时间位于1.6ms~2.8ms则为NEC'1'(标准2.25ms)
{
IRcode_Buffer |= (uint32_t)0x01;
}
else
{
TR0=0;
IRcode_Buffer = 0;
EnterINT0_CNT = 0;
Rev_State = Rev_Header;
}
break;
}
}
if(((EnterINT0_CNT==26)&&((IRcode_Type==IRcode_TypeRCA)))||((EnterINT0_CNT==34)&&((IRcode_Type==IRcode_TypeNEC8))))//RCA码加头码25,NEC码加头码33位,解码进入中断次数分别为26和34
{
TR0=0;//解码完毕关闭定时器
EnterINT0_CNT=0;
IRdataReceive_Flag=IRdataReceive_Success;
Rev_State = Rev_Header;//准备下一次接收
}
}
}
/**********************************************
函数:void TIME1_Handler(void);
功能:定时器1中断处理函数;
***********************************************/
void TIME1_Handler(void) interrupt 3
{
}
/**********************************************
函数:void USART_Handler(void);
功能:串口中断处理函数;
***********************************************/
void USART_Handler(void) interrupt 4
{
}
/**********************************************
函数:void TIME2_Handler(void);
功能:定时器2中断处理函数;
***********************************************/
void TIME2_Handler(void) interrupt 5
{
}
复制代码
#include "IR_SendCode.h"
/***********************************************************************************************
函数void IRsend_Init(void)
功能:定时器1初始化
**********************************************************************************************/
void IRsend_Init(void)
{
TMOD |= 0x10; //工作于方式1,16位定时器
TH1 = 0x00;
TL1 = 0x00;
TF1 = 0; //清楚定时器标志位
TR1 = 0; //关闭定时器
}
/***********************************************************************************************
函数void Carrier_38KHz(void)
功能:产生38KHz载波,1/2占空比,12M晶振
**********************************************************************************************/
void Carrier_38KHz(void)
{
IR = 1;
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
IR = 0;
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}
/******************************************RCA编码**********************************************/
/***********************************************************************************************
函数void RCA_LeadCode(void)
功能:产生RCA引导码
**********************************************************************************************/
void RCA_LeadCode(void)
{
TH1 = (65536-TCarrier_RCALeadCode)/256;//定时载波时间
TL1 = (65536-TCarrier_RCALeadCode)%256;
TR1 = 1;//打开定时器0
IR_ON();
while(!TF1)
{
Carrier_38KHz();
}
TF1 = 0;TR1 = 0;
IR_OFF();
TH1 = (65536-TLowLevel_RCALeadCode)/256;//定时低电平时间
TL1 = (65536-TLowLevel_RCALeadCode)%256;
TR1 = 1;//打开定时器0
while(!TF1)IR_OFF();
TF1 = 0;TR1 = 0;
}
/***********************************************************************************************
函数void RCA_1(void)
功能:产生RCA"1"码
**********************************************************************************************/
void RCA_1(void)
{
TH1 = (65536-TCarrier_RCA_1)/256;//定时载波时间
TL1 = (65536-TCarrier_RCA_1)%256;
TR1 = 1;//打开定时器0
IR_ON();
while(!TF1)
{
Carrier_38KHz();
}
TF1 = 0;TR1 = 0;
IR_OFF();
TH1 = (65536-TLowLevel_RCA_1)/256;//定时低电平时间
TL1 = (65536-TLowLevel_RCA_1)%256;
TR1 = 1;//打开定时器0
while(!TF1)IR_OFF();
TF1 = 0;TR1 = 0;
}
/***********************************************************************************************
函数void RCA_0(void)
功能:产生RCA"0"码
**********************************************************************************************/
void RCA_0(void)
{
TH1 = (65536-TCarrier_RCA_0)/256;//定时载波时间
TL1 = (65536-TCarrier_RCA_0)%256;
TR1 = 1;//打开定时器0
IR_ON();
while(!TF1)
{
Carrier_38KHz();
}
TF1 = 0;TR1 = 0;
IR_OFF();
TH1 = (65536-TLowLevel_RCA_0)/256;//定时低电平时间
TL1 = (65536-TLowLevel_RCA_0)%256;
TR1 = 1;//打开定时器0
while(!TF1)IR_OFF();
TF1 = 0;TR1 = 0;
}
/***********************************************************************************************
函数void RCA_EndCode(void)
功能:结束码
**********************************************************************************************/
void RCA_EndCode(void)
{
RCA_1();
}
/***********************************************************************************************
函数void IR_RCACode(uint8_t *pHex_RCA)
功能:RCA发码(系统码+用户码),高位在前发射,传入的参数为RCA系统码+用户码两字节数组
**********************************************************************************************/
void IR_RCACode(uint8_t *pHex_RCA)
{
uint16_t i;
uint8_t SystemCode = pHex_RCA[0];//RCA系统码
uint8_t UserCode = pHex_RCA[1];//RCA用户码
RCA_LeadCode();//RCA引导码
for(i=0x0008;i!=0x0000;i=i>>1)//发送RCA系统码
{
if(SystemCode&i)
{
RCA_1();
}
else
{
RCA_0();
}
}
for(i=0x0080;i!=0x0000;i=i>>1)//发送RCA用户码
{
if(UserCode&i)
{
RCA_1();
}
else
{
RCA_0();
}
}
SystemCode=~SystemCode;
for(i=0x0008;i!=0x0000;i=i>>1)//发送RCA系统反码
{
if(SystemCode&i)
{
RCA_1();
}
else
{
RCA_0();
}
}
UserCode=~UserCode;
for(i=0x0080;i!=0x0000;i=i>>1)//发送RCA用户反码
{
if(UserCode&i)
{
RCA_1();
}
else
{
RCA_0();
}
}
RCA_EndCode();//停止码
}
/******************************************NEC编码**********************************************/
/***********************************************************************************************
函数void NEC_LeadCode(void)
功能:产生NEC引导码
**********************************************************************************************/
void NEC_LeadCode(void)
{
TH1 = (65536-TCarrier_NECLeadCode)/256;//定时载波时间
TL1 = (65536-TCarrier_NECLeadCode)%256;
TR1 = 1;//打开定时器0
IR_ON();
while(!TF1)
{
Carrier_38KHz();
}
TF1 = 0;TR1 = 0;
IR_OFF();
TH1 = (65536-TLowLevel_NECLeadCode)/256;//定时低电平时间
TL1 = (65536-TLowLevel_NECLeadCode)%256;
TR1 = 1;//打开定时器0
while(!TF1)IR_OFF();
TF1 = 0;TR1 = 0;
}
/***********************************************************************************************
函数void NEC_1(void)
功能:产生NEC"1"码
**********************************************************************************************/
void NEC_1(void)
{
TH1 = (65536-TCarrier_NEC_1)/256;//定时载波时间
TL1 = (65536-TCarrier_NEC_1)%256;
TR1 = 1;//打开定时器0
IR_ON();
while(!TF1)
{
Carrier_38KHz();
}
TF1 = 0;TR1 = 0;
IR_OFF();
TH1 = (65536-TLowLevel_NEC_1)/256;//定时低电平时间
TL1 = (65536-TLowLevel_NEC_1)%256;
TR1 = 1;//打开定时器0
while(!TF1)IR_OFF();
TF1 = 0;TR1 = 0;
}
/***********************************************************************************************
函数void NEC_0(void)
功能:产生NEC"0"码
**********************************************************************************************/
void NEC_0(void)
{
TH1 = (65536-TCarrier_NEC_0)/256;//定时载波时间
TL1 = (65536-TCarrier_NEC_0)%256;
TR1 = 1;//打开定时器0
IR_ON();
while(!TF1)
{
Carrier_38KHz();
}
TF1 = 0;TR1 = 0;
IR_OFF();
TH1 = (65536-TLowLevel_NEC_0)/256;//定时低电平时间
TL1 = (65536-TLowLevel_NEC_0)%256;
TR1 = 1;//打开定时器0
while(!TF1)IR_OFF();
TF1 = 0;TR1 = 0;
}
/***********************************************************************************************
函数void NEC_EndCode(void)
功能:结束码
**********************************************************************************************/
void NEC_EndCode(void)
{
NEC_1();
}
/******************************************NEC8编码*******************************************/
/***********************************************************************************************
函数void IR_NEC8Code(uint8_t *pHex_NEC8)
功能:NEC8发码(系统码+用户码),低位在前发射,传入参数为NEC8系统码+用户码两字节数组
**********************************************************************************************/
void IR_NEC8Code(uint8_t *pHex_NEC8)
{
uint16_t i;
uint8_t SystemCode = pHex_NEC8[0];//NEC8系统码
uint8_t UserCode = pHex_NEC8[1];//NEC8用户码
NEC_LeadCode();//NEC8引导码
for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8系统码
{
if(SystemCode&i)
{
NEC_1();
}
else
{
NEC_0();
}
}
SystemCode=~SystemCode;
for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8系统反码
{
if(SystemCode&i)
{
NEC_1();
}
else
{
NEC_0();
}
}
for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8用户码
{
if(UserCode&i)
{
NEC_1();
}
else
{
NEC_0();
}
}
UserCode=~UserCode;
for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8用户反码
{
if(UserCode&i)
{
NEC_1();
}
else
{
NEC_0();
}
}
NEC_EndCode();//停止码
}
/******************************************NEC16编码********************************************/
/***********************************************************************************************
函数void IR_NEC16Code(uint16_t *pHex_NEC16)
功能:NEC16发码(系统码+用户码),低位在前发射
**********************************************************************************************/
void IR_NEC16Code(uint16_t *pHex_NEC16)
{
uint16_t i;
uint16_t SystemCode = pHex_NEC16[0];//NEC16系统码;
uint16_t UserCode = pHex_NEC16[1];//NEC16用户码;
uint16_t SystemCode_High=SystemCode/256;
uint16_t SystemCode_Low =SystemCode%256;
NEC_LeadCode();//NEC8引导码
for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8系统码高八位
{
if(SystemCode_High&i)
{
NEC_1();
}
else
{
NEC_0();
}
}
for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8系统码低八位
{
if(SystemCode_Low&i)
{
NEC_1();
}
else
{
NEC_0();
}
}
for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8用户码
{
if(UserCode&i)
{
NEC_1();
}
else
{
NEC_0();
}
}
UserCode=~UserCode;
for(i=0x0001;i!=0x0100;i=i<<1)//发送NEC8用户反码
{
if(UserCode&i)
{
NEC_1();
}
else
{
NEC_0();
}
}
NEC_EndCode();//停止码
}
复制代码
作者:
vectorxu
时间:
2018-4-18 21:00
不错,下载学习,谢谢楼主!
作者:
127lo
时间:
2018-8-10 16:27
刚好需要,谢谢分享
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1