已经有结果了,想追求完美最后还是初完美打败。已经做出了跟原始波形一样的了,但就是不起做用,不明原因,反而是那填充了载波的长条图波形能正常遥控。
把程序里 remoteout=0; //关红外发射 变成 remoteout=1; //开红外发射 波形就从正波变成负波了。
- i=remotedata[n];
- ET1=1;
- TR1=0; //开定时
- 。。。。。。。。。。。
- ET1=0;
- TR1=1;//不发送调制脉冲
复制代码
然后把ET1和TR1改成上面的就可以出线条图而不是填充载波的长条图
整个代码如下,基本全注释了,能搞清楚这代码为什么不实用的大神请M我
- /********学习型遥控器程序*********/
- /*
- 该程序只对红外脉冲波形复制并不解码是真正的万能学习型,程序是根据论坛公开程序资料修改完成的,
- 对多种遥控都能学习包括:电视遥控,机顶盒遥控,空调遥控等....学习到的波形脉冲总宽度几乎一致.
-
- 源码调试:风中有你 2015.11.29
-
-
- 2021年8月25日
- 改为低电平亮灯,芯片用STC8F1K08S2,波形跟原始波一样都是线条形,波形也是负波,但就是无效果
- */
- #include"stc8.h"
- #include<intrins.h> //延时函数
- #define uchar unsigned char
- #define uint unsigned int
- sbit studylamp=P5^4; //学习指示灯
- sbit lamp=P1^1; //发射指示灯
- sbit studykey=P3^4; //学习键
- sbit txkey=P3^5; //发射键
- sbit remotein=P3^2; //遥控信号输入口 高阻
- sbit remoteout=P5^5; //遥控信号输出口 强推
- uint i,j,m=5000,n,k,s;
- uint remotedata[207]; //存脉冲宽度数据用
- uint remdata; //脉冲计数
- bit tag;//学习状态标志
- /****1ms*t延时程序****/
- void delay1ms(uint t)
- {
- for(i=0;i<t;i++)
- for(j=0;j<120;j++)
- ;
- }
- /****2us*t秒延时程序****/
- void Delay2us(uchar y) //@12.000MHz
- {
- unsigned char i;
- i = y;//数越大长度越短
- while (--i);
- }
- void Timer1Init(void) //38Khz@12.000MHz
- {
- AUXR &= 0xBF; //定时器时钟12T模式 1011 1111
- TMOD |= 0x20; //设置定时器模式 10 0000
- TH1=0xf3;//38KHz初值
- TL1=0xf3;
- }
- void clr_ram()
- {
- for(i=0;i<207;i++)
- {
- remotedata[i]=0x00;
- } //清内存
- }
- /////////////////////
- /****初始化程序****/
- void clearmen(void)
- {
- // I/O 口特殊功能寄存器,这里不定义还好,定义后就不可用了,不明白
- //P3M0=0x04; P3M1=0x00;//P3.2 红外输入 高阻
- //P5M0=0x00; P5M1=0x20;//P5.5 红外输出 推挽输出
-
- /*
- P0M0[1:0] P0M1[1:0]
- 0 0 准双向口(传统8051 I/O口模式)灌电流可达20mA
- 0 1 推挽输出(强上拉输出,可达20mA,要加限流电阻)
- 1 0 仅为输入(高阻)
- 1 1 开漏(Open Drain),内部上拉电阻断开,要外加
- */
-
-
-
- studylamp=1;//关学习指示灯
- lamp=1; //关发射指示灯
- remoteout=0; //关遥控输出
- remotein=1; // 遥控输入置高电平
- IE=0x00;//IE是中端允许寄存器,这里面包括了定时器和外部中断还有EA等
- IP=0x01;//IP是中断优先级控制寄存器
- Timer1Init();
- EA=1; //开总中断
- clr_ram();
- }
- /*
- (IP.7:保留)
- (IP.6:保留)
- PT2(IP.5):若=1,定时器2中断设为高优先级(只适用于8052及其增强型)
- PS(IP.4):若=1,串行中断设为高优先级
- PT1(IP.3):若=1,定时器1中断设为高优先级
- PX1(IP.2):若=1,外部中断1设为高优先级
- PT0(IP.1):若=1,定时器0中断设为高优先级
- PX0(IP.0):若=1,外部中断0设为高优先级
- */
- /*****发送键功能函数****/
- void keywork(void)
- {
- if (txkey==0) //如发射按键按下
- {
- delay1ms(10);//延时10毫秒防抖
- while(txkey==0);//等待发射键释放,释放后txkey==1,释放后才继续执行下去就是为了防止按键一按下就无数次循环了
- n=0;//计数用
- lamp=0;//学习灯亮
- while(1) //开始发射调制波形
- {
- i=remotedata[n]; //把读到的数组数据第0个赋给i
- ET1=1;//开启T1中断 关闭也无波
- TR1=0; //关闭定时器T1不发送调制脉冲
- while(i--)
- {
- Delay2us(2);//延时2个2毫秒
- _nop_();//单片机空跑一周期
- _nop_();//单片机空跑一周期
- }
- /*
- 方式1:上面的ET1=1 TR1=1 下面的ET1=0 TR1=0 出有色波,能遥控
-
- 0001不出波
- 0010不出波
- 0011全黄,全输出载波,没得停了
- 0100不出波
- 0101不出波
- 0110一直高电平
- 0111全黄,全输出载波,没得停了
- 1000不出波
- 1001出跟原始波一样的线条波形,方向反,不能遥控
- 1010不出波
- 1011全黄
- 1100出有色波,能遥控
- 1101出有色波,能遥控
- 1110也有色波但跟方式1有点不一样,在遥控码中部有一上电平线,能遥控
- 1111全黄
- */
-
- ET1=0;//关闭T1中断
- TR1=1;//开启定时器T1发送调制脉冲 TR1=0且上面那个TR1=1时波形有填充色且能遥控,灯充满电遥控较远,
- //TR1=1且上面的TR1=0时波形跟原始波一样无填充色,但不能遥控
- remoteout=1; //关红外发射
- n++;//下一组脉冲宽度地址
- i=remotedata[n]; //把读到的数组数据第n个赋给i
- while(i--) //根据i值发送计时
- {
- Delay2us(2);//延时2个2毫秒
- _nop_();//单片机空跑一周期
- _nop_();//单片机空跑一周期
- }
- //等待该位时间结束
- n++; //下一组脉冲宽度地址
- if((remotedata[n]==0)||(n>206))//如果数值为0了或超过了206个//该位地址数据为0或地址计数大于设定值就结束
- {
- delay1ms(10);//延时10毫秒
- break;//结束退出
- }
-
- }
- }
- lamp=1; //灭灯
- }
-
- /****40KHz载波发生函数*****/
- void time_intt(void)interrupt 3 //定时器1
- {
- remoteout=~remoteout;
- }
- /*
- 外部中断0 interrupt 0
- 定时器0 interrupt 1
- 外部中断1 interrupt 2
- 定时器1 interrupt 3
- 串口中断 interrupt 4
- 定时器2 interrupt 5
- */
- //*********学习红外函数*************
- void studywork()
- {
- while(studykey==0)//按键按下放
- {
- while(studykey==1);//等待键释放
- studylamp=0; //学习灯亮
- lamp=1;//发射灯灭
- tag=1; //学习标致置1
- n=0;
- remdata=0x00;//脉宽计数器清零
- while(remotein==1);//等待遥控码输入
- while(tag)//当tag是1在学习状态就一直循环
- {
- while(remotein==0)//当低电平时有遥控码输入
- {
- Delay2us(4);//延时4个2微秒
- remdata++; //记录低电平脉宽时间
- if(remdata>m) //计数大于设定值退出 m设为5000,这个值不懂怎么来的,设为255只有一条竖线
- {
- remotedata[n]=0x00; //肪冲宽度置0
- tag=0;//学习标志置0,结束学习
- goto end;//跳到结束
- }
- }
- remotedata[n]=remdata;//如果低电平肪宽时间remdata不大于5000就把值赋给脉冲宽度数组remotedata[n],就是说这个值有效吧记录下来
- remdata=0x00;//脉宽计数器清零
- n++;//电平脉宽数据个数加1
- if(n>206) //缓存满退出,remotedata[n]设为最大207
- {
- remotedata[n]=0x00;//一组数是206,大于就清0
- tag=0;//学习标志置0,结束学习
- goto end;//跳到结束,两灯都灭了
- }
- while(remotein==1)//当高电平时无遥控码输入
- {
- Delay2us(4);//延时4个2微秒
- remdata++; //高电平计数
- if(remdata>m) //计数大于设定值退出 m设为5000,这个值不懂怎么来的,设为255只有一条竖线
- {
- remotedata[n]=0x00; //肪冲宽度置0
- tag=0;//学习标志置0,结束学习
- goto end;//跳到结束,两灯都灭了
- }
- }
- remotedata[n]=remdata; //存高电平脉宽数据
- remdata=0x00;//脉宽计数器清零
- n++;//电平脉宽数据个数加1
- }
- }
- end:
- {//学习结束
- lamp=1;//发射灯灭
- studylamp=1; //学习灯灭
- }
- }
- /******主函数****/
- void main()
- {
- clearmen();
- remoteout=0; //关红外发射
- studylamp=0; //学习灯灭
- tag=0;
- studykey=1;
- while(1)
- {
- keywork(); // 发射
- studywork(); //学习
- }
- }
复制代码
|