SAA3010T红外遥控解码和中国农历(略讲)

目录 

SAA3010T红外遥控介绍

SAA3010使用RC-5编码,有2位起始位(11)、1位控制位(X)、5位系统码(00000)、6位指令码(XXXXXX)。一帧数据共占14位,在第一次按下遥控按键后芯片要经过16位的防抖时间和2位扫描时间才会发送一帧数据,发送的信号被调制在37.91KHz:

位的解读

两位起始位:11(可以和系统码共用,作为判断读取一次按键的依据)

一位控制位:x(第n次是0,则第n+1次就是1,就是1/0交替)

五位系统码:00000(可以和起始位共用,作为判断读取一次按键的依据)

六位指令码:XXXXXX(这个指令码才是你要解读的东西)

看看波形

例子: 

 

 

看看模块

 

解码思路

首先你让上面那个模块的OUT连接到随便一个IO上面,然后开启他的外部中断,下降沿触发哦,因为你在没有接收到遥控器按键数据(就是你没有按下遥控器的时候),这个脚是需要一直是高电平的哦;

接下来你需要一个比较精准的定时器(不要问我为什么要比较精准)10us中断,20us中断都可以,你开心就行,如果是大一点的工程的话,可以选择开优先级,(反正我就开了,因为我开了许多中断);

后面两步可以看下图再理解:

 

然后接收到了下降沿信号的话,就可以开始在定时器的中断里面计数了,分别要记两次,第一次是起始位的第一个1,第二次则是后面的13个x(1/0),我建议可以放在一个16位的数据里面存储,每次接收到数据前都左移一位就可以获取到完整的14位数据;

最后就是阿巴阿巴,看代码好理解一点,如果有不懂的可以评论,我是战犬,我回信息超快。

示例代码

// 遥控器的初始化
void ir_init(void)
{
    // 配置外部中断 EXI1
    GPIO_Init(IR_DATA_PORT, IR_DATA_PIN, 1);
    GPIO_IntGroup_Set(PB0, 1, Selete_EXI_PIN1);
    GPIOB0_EXI_Init(EXI1);
    EXTI_trigger_CMD(ENABLE, EXI_PIN1, _EXIFT);
    EXTI_interrupt_CMD(ENABLE, EXI_PIN1);
    GPIO_EXTI_interrupt(GPIOB0, EXI_PIN1);
    EXI1_Int_Enable();

    //一些有用的标志位
    ir_timercount = 0;   //定时器中断的计时标志
    ir_start = 0;        //起始位
    ir_con = 0;          //控制位
    ir_sys = 0;          //系统码
    ir_cmd = 0;          //指令码
    ir_down = false;     //检测到下降沿标志位
    ir_ok = false;       //查看起始位和系统码是否符合要求的bool型变量
}

// 定时器的初始化我这里用了10us,就是在测试过程中其实这个定时器还是不太精准的
void BT0_init(void)
{
    BT_DeInit(BT0);
    BT_Configure(BT0, BTCLK_EN, 47, BT_IMMEDIATE, BT_CONTINUOUS,
                 BT_PCLKDIV); // TCLK=PCLK/(0+1)
    BT_Period_CMP_Write(BT0, 10 - 1, 0);
    BT_Start(BT0);
    BT_ConfigInterrupt_CMD(BT0, ENABLE, BT_PEND);
    BT0_INT_ENABLE();
}

//外部中断服务函数
void EXI1IntHandler(void)
{
	// ISR content ...
	if ((SYSCON->EXIRS & EXI_PIN1) == EXI_PIN1) // EXT1 Interrupt
	{
		SYSCON->EXICR = EXI_PIN1;
		ir_down = true;
		ir_timercount = 0;
	}
}

static bool ir_first = true;	   // 第一次进入和后面十三次进入中断红外遥控的判断
volatile uint32_t IR_DATA_NEW;     // 存放遥控器的按键码的全局变量
static uint8_t ir_getdata_cnt = 0; // 代表红外遥控获取的每一位数据位置

//定时器的中断函数
void BT0IntHandler(void)
{
	// ISR content ...
	if ((BT0->MISR & BT_PEND) == BT_PEND) // BT0 PEND interrupt
	{
		BT0->ICR = BT_PEND;

        //检测到下降沿就开始++
		if (ir_down)
		{
			ir_timercount++;
		}
        //没有检测到就一直为0
		else
		{
			ir_timercount = 0;
		}

        //第一次加到42的时候,也就是跑了42次中断——大约420us
		if (ir_timercount == 42 && ir_first)
		{
			ir_first = false;    //进去就false它,防止下次进入
			EXI1_Int_Disable(); // 先取消外部中断
			// 判断电平状态有没有是1的,因为是反过来的,如果是1就是0,是零的话就可以直接退出,因为起始码一定是11,下面那个IR_DATA_READ()是读取那个接到模块out的io脚的电平,这里是一个宏定义
			if (IR_DATA_READ())
			{
				EXI1_Int_Enable();        //开启外部中断
				IR_DATA_NEW = 0x00;       //清空变量
				ir_down = false;          //重新获取下降沿
				ir_first = true;          //第一次进入为真,
				ir_getdata_cnt = 0;       //日常清零
				ir_timercount = 0;        //日常清零
				return;                   //退出
			}
			IR_DATA_NEW = 0x00;           //清零准备接收后面13位数据
			ir_timercount = 0;            //准备计算后面13位的周期
		}

		// 这里代表外部中断触发后,已经经历了1/4周期然后开始计算新的周期,要求13次
		else if (ir_timercount > 171 && !ir_first)
		{
			ir_getdata_cnt++;            //获取第一位

			IR_DATA_NEW <<= 1;           //左移1位
			IR_DATA_NEW |= IR_DATA_READ();    //获取电平状态存入变量中
			ir_timercount = 0;            //清零计时标志
			// 接收了13位数据之后
			if (ir_getdata_cnt == 13)
			{
				// 接收到的数据是发送数据的反码,取反还原为发送的数据
				IR_DATA_NEW = ~IR_DATA_NEW;

				// 起始位 控制位 系统码 指令码:11 X 00000 XXXXXX
				ir_start = 0x02 | (uint8_t)((IR_DATA_NEW & 0x1000) >> 12);

				if ((IR_DATA_NEW & 0x800) > 0)
				{
					ir_con = 1;
				}
				else
				{
					ir_con = 0;
				}

				ir_sys = (uint8_t)((IR_DATA_NEW & 0x07c0) >> 6);
				ir_cmd = (uint8_t)(IR_DATA_NEW & 0x3f);

				// 等待校验
				if (ir_start == 0x03 && ir_sys == 0x00)
				{
					ir_ok = true;
				}

				// 等待变成高电平
				// while (!IR_DATA_READ())
				// {
				// 	;
				// }

				// 清除标志,哥们
				ir_getdata_cnt = 0;
				ir_first = true;
				ir_down = false;
				EXI1_Int_Enable();
			}
		}
	}
}

最后我给大家一个正确的中国农历数组:

static const uint32_t lunar200y[199] = {
    0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544,
    0x46AAB9, 0x056A4D, 0x09AD42, 0x24AEB6, 0x04AE4A, /*1901-1910*/
    0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E,
    0x0D6A43, 0x296D37, 0x095B4B, 0x749BC1, 0x049754, /*1911-1920*/
    0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8,
    0x02B64D, 0x095742, 0x2497B7, 0x04974A, 0x664B3E, /*1921-1930*/
    0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644,
    0x393738, 0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48, /*1931-1940*/
    0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D,
    0x092D42, 0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51, /*1941-1950*/
    0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8,
    0x052B4C, 0x8A953F, 0x0E9552, 0x06AA48, 0x6AD53C, /*1951-1960*/
    0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642,
    0x3E9335, 0x0D9549, 0x75AABE, 0x056A51, 0x096D46, /*1961-1970*/
    0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B,
    0x8D52BF, 0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50, /*1971-1980*/
    0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554,
    0x06D449, 0x6ADA3D, 0x0AB651, 0x095746, 0x5497BB, /*1981-1990*/
    0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF,
    0x05AC53, 0x0AB647, 0x5936BC, 0x092E50, 0x0C9645, /*1991-2000*/
    0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49,
    0x7AADBD, 0x025D52, 0x092D47, 0x5C95BA, 0x0A954E, /*2001-2010*/
    0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53,
    0x0A5B48, 0x652BBC, 0x052B50, 0x0A9345, 0x474AB9, /*2011-2020*/
    0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x6A573D,
    0x0A4E51, 0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43, /*2021-2030*/
    0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48,
    0x6D25BC, 0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C, /*2031-2040*/
    0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51,
    0x0AA546, 0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37, /*2041-2050*/
    0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C,
    0x0EA54F, 0x06AA44, 0x4AB638, 0x0AAE4C, 0x092E42, /*2051-2060*/
    0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545,
    0x55AABA, 0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B, /*2061-2070*/
    0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F,
    0x055A45, 0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6, /*2071-2080*/
    0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA,
    0x04B64E, 0x0A5743, 0x452738, 0x0D264A, 0x8E933E, /*2081-2090*/
    0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45,
    0x4A4EB9, 0x0A4D4C, 0x0D1541, 0x2D92B5            /*2091-2099*/
};//经过我验证过的,别怕,有用到的放心用,有错的请指一下,谢谢大佬们

最后没什么好讲的,也是记录一下自己实习生活和有希望能帮到你们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值