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).
本文出自 “魂斗罗” 博客,谢绝转载!