【红外学习 4】【最终版】STC15f104W 红外led发射,导线交互 2种方式 测试成功

STC15f104W 红外led发射,导线交互 2种方式


/*

单片机:STC15f104W
红外发射:
接线:VCC -- 红外LED--第3号引脚

STC15F104W ,晶振设定12M
1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3
*/
#include <STC15F104E.H>
#include <INTRINS.h>
sbit  ISR_LED = P3^5;
static bit wave;                   //载波标志
static unsigned int count;         //中断次数计数器
static unsigned int g_endcount;    //终止延时计数
static bit wave_flag;              //载波发送标志
unsigned char code usercode1=0x48;           //十六位地址的第一个字节
unsigned char code usercode2=0x77;           //十六位地址的第二个字节

void DELAY_MS (unsigned int a)
    {
    unsigned int i;
    while ( --a != 0 )
       {
        for (i=0;i<=600;i++);
       }
}
        
void SendIRdata_38KHZ(unsigned int temp1, bit temp2){
  g_endcount=temp1; 
  wave_flag=temp2;
  EA=0; 
    count=0; 
    EA=1;  //避免中断影响count置数
  while(1){   
     EA=0; 
   if( count < g_endcount ) EA=1;  //避免中断影响count比较
   else{EA=1; break;}  
  }  
}
 
void SendIRdata_BYTE(unsigned char irdata){
  unsigned char i;
  for(i=0;i<8;i++)  {
    //先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)
    SendIRdata_38KHZ(43, 1);   //13.02*43=0.56ms
 
        //判断最低位为1还是0。   低位先发送!!
     if(irdata & 1)  SendIRdata_38KHZ(130, 0);         //1为宽电平,13.02*130=1.693ms
     else  SendIRdata_38KHZ(43, 0);   //0为窄电平,13.02*43=0.560ms
     irdata=irdata>>1;  //数据右移,原先的最低位移出
  }
}
 
void SendIRdata(unsigned char p_irdata){
  //有的遥控器会发一个前脉冲,如果不灵,可试试加上前脉冲
  //发送起始码前脉冲,高电平有38KHZ载波
  //SendIRdata_38KHZ(18, 1);
  //发送起始码前脉冲,低电平无38KHZ载波
  //SendIRdata_38KHZ(18, 0);
 
  //发送9ms的起始码,高电平有38KHZ载波
  SendIRdata_38KHZ(692, 1); //13.02*692=9.010ms
 
  //发送4.5ms的结果码,低电平无38KHZ载波
  SendIRdata_38KHZ(346, 0);    //13.02*346=4.505ms
 
  //发送十六位地址的前八位
  SendIRdata_BYTE(usercode1);
 
  //发送十六位地址的后八位
  SendIRdata_BYTE(usercode2);
 
  //发送八位数据
  SendIRdata_BYTE(p_irdata);
 
  //发送八位数据的反码
  SendIRdata_BYTE(~p_irdata);  
 
  //发送总的结束位1bit
  SendIRdata_38KHZ(43, 1);     //13.02*43=0.56ms

  wave_flag=0;
}

void TimerInit(void){  // 12M @12T  13微秒中断
//串口和中断定时器设置
TMOD = 0x02; //(定时器0 方式2,8位自动重装)

//  1S/38K=26.31微秒 ,1/2的占空比方波,需要13微秒的中断
TH0 = 0xF3; 
TL0 = 0xF3;   
TR0 = 1;   //开始计数
ET0 = 1;   //定时器0中断允许
EA = 1;    //允许CPU中断 
}
 
 
void main(void) {
  count = 0;
  wave_flag = 0;
  wave = 1; 
  ISR_LED = 1;   
  TimerInit();
 
while(1){
     DELAY_MS(1000);
     SendIRdata(0x00);   //发送红外数据
  }
}
 
void timeint(void) interrupt 1 { 
  count++;
  if (wave_flag)    wave=~wave;
  else    wave = 1;    //LED不点亮
  ISR_LED = wave;
}


=============================================================================














/*

单片机:STC15f104W
红外发射:
接线:VCC -- 红外LED--第3号引脚

STC15F104W ,烧录晶振设定12M


功能:通过导线,与机顶盒交互
单片机GND 接 机顶盒的GND
单片机第3号引脚 接 机顶盒红外接收的OUT引脚

1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3

*/

#include <STC15F104E.H>
#include <INTRINS.h>
sbit  ISR_LED = P3^5;
static bit wave;                   //载波标志
static unsigned int count;         //中断次数计数器
static unsigned int g_endcount;    //终止延时计数
static bit wave_flag;              //载波发送标志
unsigned char code usercode1=0x48;           //十六位地址的第一个字节
unsigned char code usercode2=0x77;           //十六位地址的第二个字节

void DELAY_MS (unsigned int a)
    {
    unsigned int i;
    while ( --a != 0 )
       {
        for (i=0;i<=600;i++);
       }
}
        
void SendIRdata_38KHZ(unsigned int temp1, bit temp2){
  g_endcount=temp1; 
  wave_flag=temp2;
  EA=0; 
    count=0; 
    EA=1;  //避免中断影响count置数
  while(1){   
     EA=0; 
   if( count < g_endcount ) EA=1;  //避免中断影响count比较
   else{EA=1; break;}  
  }  
}
 
void SendIRdata_BYTE(unsigned char irdata){
  unsigned char i;
  for(i=0;i<8;i++)  {
    //先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)
    SendIRdata_38KHZ(43, 1);   //13.02*43=0.56ms
 
        //判断最低位为1还是0。   低位先发送!!
     if(irdata & 1)  SendIRdata_38KHZ(130, 0);         //1为宽电平,13.02*130=1.693ms
     else  SendIRdata_38KHZ(43, 0);   //0为窄电平,13.02*43=0.560ms
     irdata=irdata>>1;  //数据右移,原先的最低位移出
  }
}
 
void SendIRdata(unsigned char p_irdata){
  //有的遥控器会发一个前脉冲,如果不灵,可试试加上前脉冲
  //发送起始码前脉冲,高电平有38KHZ载波
  //SendIRdata_38KHZ(18, 1);
  //发送起始码前脉冲,低电平无38KHZ载波
  //SendIRdata_38KHZ(18, 0);
 
  //发送9ms的起始码,高电平有38KHZ载波
  SendIRdata_38KHZ(692, 1); //13.02*692=9.010ms
 
  //发送4.5ms的结果码,低电平无38KHZ载波
  SendIRdata_38KHZ(346, 0);    //13.02*346=4.505ms
 
  //发送十六位地址的前八位
  SendIRdata_BYTE(usercode1);
 
  //发送十六位地址的后八位
  SendIRdata_BYTE(usercode2);
 
  //发送八位数据
  SendIRdata_BYTE(p_irdata);
 
  //发送八位数据的反码
  SendIRdata_BYTE(~p_irdata);  
 
  //发送总的结束位1bit
  SendIRdata_38KHZ(43, 1);     //13.02*43=0.56ms

  wave_flag=0;
}

void TimerInit(void){  // 12M @12T  13微秒中断
//串口和中断定时器设置
TMOD = 0x02; //(定时器0 方式2,8位自动重装)

//  1S/38K=26.31微秒 ,1/2的占空比方波,需要13微秒的中断
TH0 = 0xF3; 
TL0 = 0xF3;   
TR0 = 1;   //开始计数
ET0 = 1;   //定时器0中断允许
EA = 1;    //允许CPU中断 
}
 
 
void main(void) {
  count = 0;
  wave_flag = 0;
  wave = 1; 
  ISR_LED = 1;   
  TimerInit();
 
while(1){
     DELAY_MS(1000);
     SendIRdata(0x00);   //发送红外数据
  }
}
 
void timeint(void) interrupt 1 { 
  count++;
//  if (wave_flag)    wave=~wave;
  if (wave_flag)    wave=0;
  else    wave = 1;    //LED不点亮
  ISR_LED = wave;
}



【最终版】STC12C5A60S2 12M 导线代替 红外发射  

/*
项目名称:机顶盒频道锁定
日期:2016年1月31日  23:33
版本:2.0
设计:chunli
博客:http://990487026.blog.51cto.com/
邮箱:[email protected]
编码环境:GBK2312简体中文
μVision 版本:4.72.9.0 
代码类型:C语言
功能:用导线的方式实现红外控制功能

更新说明:
1, 废弃弃原来模拟按键的方式去控制机顶盒的频道,因为这种方式不稳定。
2,采用红外控制的思想,用导线代替红外发射,频道锁定迅速

为什么要这么设计?
   因为该环境内有7个同批次机顶盒同时在工作,如果只想控制其中的一个机顶盒,
     用发射红外的方式,必然带来对其他机顶盒的干扰。
     
     用导线的方式代替发射红外,彻底杜绝红外发射对其他机顶盒的干扰。、
     而且频道锁定迅速,


单片机:STC15f104W
烧录晶振设定12M

接线:
1,单片机的GND 接 机顶盒的 GND
1,单片机的3号脚 接 机顶盒红外接收一体化的OUT引脚

STC15f104W引脚
1 P3.4
2 VCC  3.8--5.5V
3 P3.5
4 GND
5 P3.0 接烧录器的TXD
6 P3.1 接烧录器的RXD
7 P3.2
8 P3.3

*/

#include <STC15F104E.H>
#define waiting 70     //开机初始化的时间  值应该为60,单位秒钟  范围:0--65535秒
#define rollback 15    //轮询锁定频道,    值应该为30,单位分钟  范围:0--255分钟
//在 void channel(void)函数内   设定频道锁定

sbit  ISR_Single = P3^5;
static unsigned int count;        //中断次数计数器
static unsigned int End_Times;    //终止延时计数
static bit Single_flag;           //0、1电平 标志

unsigned char code usercode1=0x48;           //用户码前8位
unsigned char code usercode2=0x77;           //用户码后8位

unsigned char code key_0=0x10; 
unsigned char code key_1=0x11; 
unsigned char code key_2=0x12; 
unsigned char code key_3=0x13; 
unsigned char code key_4=0x14; 
unsigned char code key_5=0x15; 
unsigned char code key_6=0x16; 
unsigned char code key_7=0x17; 
unsigned char code key_8=0x18; 
unsigned char code key_9=0x19; 

unsigned char code key_menu=0x07; 
unsigned char code key_back=0x1C; 
unsigned char code key_ok=0x1F; 
unsigned char code key_up=0x00; 
unsigned char code key_down=0x01; 
unsigned char code key_left=0x03; 
unsigned char code key_right=0x02; 


void DELAY_MS (unsigned int a)    {
    unsigned int i;
    while ( --a != 0 )       {
        for (i=0;i<=600;i++);
       }
}

void sleep_s (unsigned int a){
   unsigned int i;
     for (i=0;i<a;i++){
   DELAY_MS(1000);
   }
}

void sleep_m (unsigned int a){
   unsigned int i;
     for (i=0;i<a;i++){
   sleep_s(60);
   }
}


void SendSingle(unsigned int temp1, bit temp2){  //电信号持续时间控制
  End_Times=temp1; 
  Single_flag=temp2;
  EA=0; 
    count=0; 
    EA=1;                            //避免中断影响count置数
  while(1){   
     EA=0; 
   if( count < End_Times ) EA=1;  //避免中断影响count比较
   else{EA=1; break;}  
  }  
}
 
void SendI_Byte(unsigned char irdata){    //发射一个8为数据
  unsigned char i;
  for(i=0;i<8;i++)  {
    //先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)
    SendSingle(43, 1);   //13.02*43=0.56ms
 
        //判断最低位为1还是0。   低位先发送!!
     if(irdata & 1)  SendSingle(130, 0);         //1为宽电平,13.02*130=1.693ms
     else  SendSingle(43, 0);   //0为窄电平,13.02*43=0.560ms
     irdata=irdata>>1;  //数据右移,原先的最低位移出
  }
}
 
void Send_Code(unsigned char Code){
  //有的遥控器会发一个前脉冲,如果不灵,可试试加上前脉冲
  //SendSingle(18, 1);   //发送起始码前脉冲,高电平有38KHZ载波
  //SendSingle(18, 0);   //发送起始码前脉冲,低电平无38KHZ载波
  SendSingle(692, 1);    //13.02*692=9.010ms   //发送9ms的起始码,高电平有38KHZ载波
  SendSingle(346, 0);    //发送4.5ms的结果码,低电平无38KHZ载波 //13.02*346=4.505ms    
  SendI_Byte(usercode1); //发送十六位地址的前八位
  SendI_Byte(usercode2); //发送十六位地址的后八位
  SendI_Byte(Code);      //发送八位数据
  SendI_Byte(~Code);     //发送八位数据的反码
  SendSingle(43, 1);     //发送总的结束位1bit  //13.02*43=0.56ms  
  Single_flag=0;
}

void TimerInit(void){  // 12M @12T  13微秒中断
TMOD = 0x02; //(定时器0 方式2,8位自动重装)
//  1S/38K=26.31微秒 ,1/2的占空比方波,需要13微秒的中断
TH0 = 0xF3; 
TL0 = 0xF3;   
TR0 = 1;   //开始计数
ET0 = 1;   //定时器0中断允许
EA = 1;    //允许CPU中断 
}

void channel(void){
// CCTV 5  体育  20  CCTV5 是20号频道,先按2 再按0
// CCTV 13 新闻  22
// CCTV 14 少儿  87
// 湖南卫视      39
// 安徽卫视      55
// 东方卫视      33
// 黑龙江卫视    25
    DELAY_MS(500); 
      Send_Code(key_down);   
    DELAY_MS(500);      
      Send_Code(key_down);   
      DELAY_MS(500); 
}

void main(void) {
  count = 0;
  Single_flag = 0;
  ISR_Single = 1;   
  TimerInit();
  sleep_s(waiting);   //等待机顶盒初始化完成
  channel();          //开始锁定频道
    while(1){
     sleep_m(rollback);
  channel();           //再次锁定频道
 }
}
 
void timeint(void) interrupt 1 { 
  count++;
  if (Single_flag) ISR_Single=0;
  else           ISR_Single=1;    
    
}

//编译结果
//Rebuild target 'Target 1'
//assembling STARTUP.A51...
//compiling send_ISR.C...
//linking...
//Program Size: data=17.2 xdata=0 code=358
//creating hex file from "Send_ISR"...
//"Send_ISR" - 0 Error(s), 0 Warning(s).





本文出自 “魂斗罗” 博客,谢绝转载!

你可能感兴趣的:(测试成功,2种方式,【最终版】STC15f104W,红外LED发射,导线交互)