|
本帖最后由 cx_star 于 2020-8-28 11:16 编辑
刷到了这个帖子都说守时的人靠谱,但首先你得有个走时精准的钟表(RX8025应用),买了RX8025改了自己的时钟,又想要一个频率计
又搜到了这个帖子:STC89C52单片机等精度频率计(带仿真),没有M币啊
发个自己改的程序,骗点打赏
共三个版本:参考版本、记录原始定时器值的第二个版本、优化ram版本,可识别格力YB0F2、YAD0F,美的R05d,其他NEC等各种红外
原始程序:格力空调遥控器(YB0F2)单片机解码程序,复制是乱码,清楚乱码后的效果:
- /* 格力空调遥控器(YB0F2)解码
- CUP:STC89C52RC 晶振:11.0569MHz
- 直接由串口输出 波特率:57600
- ************************************ 说 明 **********************************************
- 解码方式:
- 以一个9ms的低电平和4.5ms的高电平为引导码,后跟35位二进制代码 接着0.565ms低电平和20MS高电平跟32位二进制代码
- 前4个字节每个字节为8位,中间1个字节只有3位,接着为20MS高电平,跟后4个字节每个字节为8位
- 以低电平为0.565ms、高电平为0.56ms、 周期为1.125ms的组合表示"0";
- 以低电平为0.565ms、高电平为1.685ms、周期为2.25ms的组合表示"1"。;
- 注意:经过红外接收头解调后单片机接收到的高低电平是和遥控器发射时是相反的一个过程
- * 兼容 1T-12T单片机中断方式红外接收数据,并通过串口发送
- 程序编辑: lbq691477940 22/07/2011
- */
- /*******************************************************************************************/
- #include "STC_NEW_8051.H"
- #include "intrins.h"
- #include "stdio.h"
- typedef unsigned char uint8;
- #define FOSC 22118400L
- #define T1RE (256-FOSC/12/19200/32)
- #define T0MS30 1/FOSC*12*1000*30
- sbit Ir_Pin = P3^2;
- sbit LED = P1^0;
- sbit LED1 = P1^1;
- sbit LED2 = P1^2;
- sbit LED3 = P1^3;
- uint8 Ir_Buf[9]; //用于保存解码结果
- uint8 r,t;
- unsigned int tttt;
- /*******************************************************************************************
- * 外部中断0初始化
- /*******************************************************************************************/
- void int1_init(void)
- {
- IT0 = 1; //下降沿有效
- EX0 = 1;
- EA = 1;
- }
- void T0Init(){
- TMOD |= 0x01;//工作模式:16位重装
- }
- void Delay500ms() //@22.1184MHz
- {
- unsigned char i, j, k;
- _nop_();
- i = 8;
- j = 1;
- k = 243;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- /*******************************************************************************************
- * UART初始化
- /*******************************************************************************************/
- void UartInit(void) //115200bps@22.1184MHz
- {
- SCON = 0x50; //8位数据,可变波特率
- AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
- AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
- TMOD &= 0x0F; //设定定时器1为16位自动重装方式
- TL1 = 0xFC; //设定定时初值
- TH1 = 0xFF; //设定定时初值
- ET1 = 0; //禁止定时器1中断
- TR1 = 1; //启动定时器1
- }
- /****************************** 延时21ms子程序 ************************************/
- void Delay20ms() //@22.1184MHz
- {
- unsigned char i, j;
- i = 72;
- j = 181;
- do
- {
- while (--j);
- } while (--i);
- }
- /*******************************************************************************************/
- /*******************************************************************************************
- * UART发送一字节
- /*******************************************************************************************/
- void UART_Send_Byte_Inverted (uint8 dat)
- {
- uint8 t,i;
-
- for(i=0;i<8;i++){
- t += dat&1;
- t <<= 1;
- dat >>= 1;
- }
- SBUF = t;
- while (TI == 0);
- TI = 0;
- }
- void UART_Send_Byte (uint8 dat)
- {
- SBUF = dat;
- while (TI == 0);
- TI = 0;
- }
- void UART_Send_String(uint8 *dat)
- {
- while(*dat!=0)
- UART_Send_Byte(*dat++);
- }
- char putchar(char c)
- {
- UART_Send_Byte(c);
- return c;
- }
- /*******************************************************************************************
- * 获取低电平时间/
- /*******************************************************************************************/
- unsigned int Ir_Get_Low()
- {
- TL0 = 0;
- TH0 = 0;
- TR0 = 1;
- //while (!Ir_Pin && (TH0 & 0x80)==0);//一直计到Ir_Pin不等0与计到大于1.085*32768=35553.28us
- while (!Ir_Pin && (TH0<0xF0) ) // 1/22118400*12*0xf000 = 33333.33us
- ;
- TR0 = 0;
- return (TH0 * 256 + TL0); //返回T1 高八位和低八位计数值
- }
- /*******************************************************************************************
- * 获取高电平时间
- /*******************************************************************************************/
- unsigned int Ir_Get_High()
- {
- TL0 = 0;
- TH0 = 0;
- TR0 = 1;
- //while (Ir_Pin && (TH0 & 0x80)==0);//一直计到Ir_Pin不等1与计到大于1.085*32768=35553.28us
- while (Ir_Pin && (TH0<0xF0) )
- ;
- TR0 = 0;
- return (TH0 * 256 + TL0); //返回T1 高八位和低八位计数值
- }
- /********************************** 主函数 ****************************************/
- //#define MY_DEBUG
- main()
- {
- int i=1;
- UartInit();
- int1_init();
- T0Init();
- while(i--){
- Delay500ms();
- UART_Send_String("hello\r\n");
- LED = ~LED;
- }
- while (1){
- #ifdef MY_DEBUG
- if(r!=0) {
- t = r;
- printf("r:%bx %u\r\n",t, tttt);
- r=0;
- }
- #endif
- };
- }
- /**************************** 外部中断0解码函数 ****************************************/
- // 1/11.0569*12 = 1.085295155061545
- // 1/22.1184*12 = 0.5425347222222222
- // 8500us 8500*22.1184/12 15667.2
- #define us8500 15667
- // 9500us 22.1184/12*9500 17510.4
- #define us9500 17510
- // 4000us 22.1184/12*4000 7372.8
- #define us4000 7372
- // 5000us 22.1184/12*5000 9216
- #define us5000 9216
- // 200us 22.1184/12*200 368.64
- #define us200 368
- // 800us 22.1184/12*800 1474.56
- #define us800 1474
- // 2000us 22.1184/12*2000 3686.4
- #define us2000 3686
- // 1120us 22.1184/12*1120 2064.384
- #define us1120 2064
- // 19ms 22.1184/12*19000 35020.8
- #define ms19 35020
- // 21ms 22.1184/12*21000 38707.2
- #define ms21 38707
- void int1_isr() interrupt 0
- {
- unsigned int temp=0;
- char i,j;
- LED1 = ~LED1;
- temp = Ir_Get_Low();
- if ((temp < us8500) || (temp > us9500)) //引导脉冲低电平8500~9500us (1/11.0569*12*8500)
- {
- #ifdef MY_DEBUG
- r = 1;
- tttt = temp;
- #endif
- return; //不在9ms范围则说明出错 //1.085*7833=8498us ~ 1.085*8755=9499us
- }
- temp = Ir_Get_High();
- if ((temp < us4000) || (temp > us5000)) //引导脉冲高电平4000~5000us
- {
- #ifdef MY_DEBUG
- r = 2;
- tttt = temp;
- #endif
- return; //不在4ms范围则说明出错 //1.085*3686=3999us ~ 1.085*4608=4999us
- }
- /*******************************************************************************************/
- for (i = 0; i < 4; i++) //4个字节
- {
- for (j = 0; j < 8; j++) //每个字节8位
- {
- temp = Ir_Get_Low();
- if ((temp < us200) || (temp > us800)) //200~800us
- {
- #ifdef MY_DEBUG
- r = 3;
- tttt = temp;
- #endif
- return; //不在这范围则说明出错 //1.085*200=217us ~ 1.085*800=868us
- }
- temp = Ir_Get_High();
- if ((temp < us200) || (temp > us2000)) //200~2000us
- {
- #ifdef MY_DEBUG
- r = 4;
- tttt = temp;
- #endif
- return; //不在这范围则说明出错 //1.085*200=217us
- }
- Ir_Buf[i] >>= 1; //先将它自动补0
- if (temp > us1120) //1120us //1.085*1032=1119us
- Ir_Buf[i] |= 0x80; //如果大于1119us才将它设为1
- }
- }
- /************************** 第5个字节只有三位故只读其低三位即可 ************************/
- for (i = 4; i <= 4; i++) //1个字节
- {
- Ir_Buf[i] = 0;
- for (j = 0; j < 3; j++) //每个字节8位
- {
- temp = Ir_Get_Low();
- if ((temp < us200) || (temp > us800)) //200~800us
- {
- #ifdef MY_DEBUG
- r = 5;
- tttt = temp;
- #endif
- return; //不在这范围则说明出错 //1.085*200 = 217us ~ 1.085*800 = 868us
- }
- temp = Ir_Get_High();
- if ((temp < us200) || (temp > us2000)) //200~2000us
- {
- #ifdef MY_DEBUG
- r = 6;
- tttt = temp;
- #endif
- return; //不在这范围则说明出错 //1.085*200 = 217us ~ 1.085*2000 = 2170us
- }
- Ir_Buf[i] <<= 1; //先将它自动补0
- if (temp > us1120) //1120us //1.085*1032 = 1119us
- Ir_Buf[i] |= 0x01; //如果大于1119us才将它设为1
- }
- }
- /*******************************************************************************************/
- temp = Ir_Get_Low();
- if ((temp < us200) || (temp > us800)) //200~800us
- {
- #ifdef MY_DEBUG
- r = 7;
- tttt = temp;
- #endif
- return; //不在565us范围则说明出错 //1.085*200 = 217us ~ 1.085*800 = 868us
- }
- //delay21ms(); //实测波形只20ms但如果只延时20ms读出会出错故延时21ms
- //Delay20ms();
- temp = Ir_Get_High();
- if ((temp < ms19) || (temp > ms21)) //19~21ms
- {
- #ifdef MY_DEBUG
- r = 8;
- tttt = temp;
- #endif
- return; //不在这范围则说明出错 //1.085*17498 = 18985us ~ 1.085*19354 = 20999us
- }
- /*******************************************************************************************/
- for (i = 5; i < 9; i++) //4个字节3
- {
- for (j = 0; j < 8; j++) //每个字节8位8
- {
- temp = Ir_Get_Low();
- if ((temp < us200) || (temp > us800)) //200~800us
- {
- #ifdef MY_DEBUG
- r = 9;
- tttt = temp;
- #endif
- return; //不在565us范围则说明出错 //1.085*200 = 217us ~ 1.085*800 = 868us
- }
- temp = Ir_Get_High();
- if ((temp < us200) || (temp > us2000)) //200~2000us
- {
- #ifdef MY_DEBUG
- r = 10;
- tttt = temp;
- #endif
- return; //不在这范围则说明出错 //1.085*200 = 217us ~ 1.085*2000 = 2170us
- }
- Ir_Buf[i] >>= 1; //先将它自动补0
- if (temp > us1120) //1120us //1.085*1032 = 1119us
- Ir_Buf[i] |= 0x80; //如果大于1119us才将它设为1
- }
- }
- /*******************************************************************************************/
- for(i = 0;i < 9;i++) //通过串口将代码发出
- {
- UART_Send_Byte_Inverted(Ir_Buf[i]); //将9个字节的遥控键值通过串口输出
- }
- }
复制代码 修改后的第一个版本(只记录定时器原始数据):
上面一个版本挺要RAM的,又修改了一个版本://格力
//YB0F2编码 9ms+4.5ms 35位(0.565ms+0.56ms/1.685) 0.565ms+20ms 32位 [0.565ms+Nms] 2+70+2+64 = 138 (+2)
//YAD0F编码 YB0F2 0.565ms+40ms YB0F2 [0.565ms+Nms] 138+2+138 = 278 (+2)
//美的
//R05d L,A,A’,B,B’,C,C’, S, L,A,A’,B,B’,C,C’
// 4.4ms+4.4ms 2*8*3(0.54ms+0.54ms/1.62ms) 0.54ms+5.22ms 4.4ms+4.4ms 2*8*3(0.54ms+0.54ms/1.62ms) 0.54ms+Nms
//NEC遥控器
// 9ms低+4.5ms高 32位(0.58+0.55/1.66) 0.565ms+40ms (9ms低+2.25ms高+0.56ms低+高 )
- uint8 Ir_Buf_PWM[IR_BUF_SIZE]; //用于保存解码结果
复制代码
补充内容 (2020-8-31 14:24):
程序效果见5楼
https://www.mydigit.cn/forum.php ... 734&pid=5876234 |
打赏
-
查看全部打赏
|