【红外学习 3】【经典】STC12C5A60S2 串口输入和不带串口,红外LED发射 测试可用



/*
STC12C5A60S2 11.0592M  从串口获取数据,红外发射
串口发送请用16进制的格式

这里采用1T周期的STC12C5A60S2单片机,11.0592MHZ
正电源→红外LED→P0.0脚。
串口1默认选T1作为波特率发生器
TO用于中断
*/
#include <STC12C5A60S2.H>
#include <INTRINS.h>
sbit  ISR_LED = P0^0;
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 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){
//串口和中断定时器设置
SCON=0x50;  //串口方式1    01 0 1 0 0 00  模式1,非多机,允许接收,无数据位8,清中断标识TI和RI
TMOD = 0x22; //(定时器0和1:方式2,自动重装,8位)

//串口的波特率设置    
TH1=253;  //11.0592MHZ,9600bps。没有设置SMOD,故波特率没有加倍。即:11.0592/12/3/32=9600bps
TL1=253;
TR1=1;    //启动定时器

//中断的定时器设置    
TH0 = 244; 
TL0 = 244; //(WXL:即计数12次中断一次,即11.0592MHZ晶振,机器周期是1.085us,12次*1.085=13.02us,这样达38KHZ。  13us一次中断,时间太短了,所以单片机要快)
TR0 = 1;   //开始计数
ET0 = 1;   //定时器0中断允许

EA = 1;    //允许CPU中断 
}
 
 
void main(void) {
unsigned char com_data;    //数据字节
  
  count = 0;
  wave_flag = 0;
  wave = 1; 
  ISR_LED = 1;   //LED接电源正极,不点亮

  TimerInit();
 
RI=0;
while(1){
    if(RI==1){
   com_data =SBUF;
   RI=0;                   //要人工清RI
   SendIRdata(com_data);   //发送红外数据

   TI=0;
   SBUF = com_data;   //输出字符
   while(!TI) ;     //空语句判断字符是否发完,TI=1表示发完
   TI = 0;         //要人工清TI
   }
  }
}
 
void timeint(void) interrupt 1 { 
  count++;
  if (wave_flag)    wave=~wave;
  else    wave = 1;    //LED不点亮
  ISR_LED = wave;
}
//编译结果:
//Rebuild target 'Target 1'
//assembling STARTUP.A51...
//compiling send_ISR.C...
//linking...
//Program Size: data=15.3 xdata=0 code=244
//creating hex file from "Send_ISR"...
//"Send_ISR" - 0 Error(s), 0 Warning(s).







12M 红外发射


/*
STC12C5A60S2 11.0592M  从串口获取数据,红外发射
串口发送请用16进制的格式

这里采用1T周期的STC12C5A60S2单片机,11.0592MHZ
正电源→红外LED→P0.0脚。
串口1默认选T1作为波特率发生器
TO用于中断
*/
#include <STC12C5A60S2.H>
#include <INTRINS.h>
sbit  ISR_LED = P0^0;
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;
}




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

你可能感兴趣的:(串口输入和不带串口,红外LED发射,测试可用)