基于STM32和EV1527的无线接收解码程序 您所在的位置:网站首页 2262编码芯片 基于STM32和EV1527的无线接收解码程序

基于STM32和EV1527的无线接收解码程序

2023-11-11 06:55| 来源: 网络整理| 查看: 265

一、1527的数据帧结构 无线遥控的编码,从编码类型上来说,分为2类,一类是固定码,也就是编码芯片的地址是不变的,芯片型号以 EV1527、PT2262 为代表。另一种是滚动码,芯片的地址码是变化的,芯片以HS300、HS301为代表。

1 EV1527 数据帧结构 EV1527 是一片由 CMOS 设计制造的可预烧内码的学习码编码IC ,由软件解码;内码共有 20 个位元可预烧 1048576 组内码组合,降低使用上编码重复的机率。 EV1527 每帧数据由 24 个数据位组成,前 20 位为地址码,对于一个芯片来说,地址位的内容是固定的,是出厂前就预制好的,并且理论上每个芯片的地址码是唯一的。后面 4 位为按键码,对应芯片上的K0-K3 4 根数据线,数据线的状态不同,按键码就不同。 在数据位之前,还有一个同步脉冲,也就是每帧数据都是从同步 脉冲开始的。数据位的“1”和“0”是由高低电平宽度(脉冲宽度)的比例决定的。如果高电平宽度为低电平宽度的 3 倍,就表示逻辑“1”,反过来如果低电平为高电平宽度的 3 倍,就表示逻辑“0”。同步脉冲高电平和低电平的比例固定为 4:124. 1527时序 这里写图片描述 这里写图片描述 这里写图片描述

二、中断方式的解码 把串行输入的编码数据帧,还原成编码之前的状态,读取其中 的地址码和按键码,称之为解码。 数据帧都是由同步头开始,然后是 24位的数据码,并且此数据帧在遥控器按键的过程中是重复出现的,我们首先要判断同步码,判断出了同步码,就知道数据码是从那一位开始了。对于一款量产的无线遥控器来说,他的编码芯片匹配的电阻是一个固定值,也就是说它发射的数据帧的脉冲宽度是不变的,所以我们可以通过测量高低脉冲宽度的方式来分辨同步码、逻辑“1”、逻辑“0”。 具体的方法是这样的,首先启用定时器,装入一个初值,打开 定时器中断,让其以固定的间隔进入中断程序。在中断程序中,我们查询数据输入管脚的状态,如果为高电平,就在高电平状态累加计数,反之就在低电平状态计数,当电平发生上升沿变化的时候,判断接收到的高低电平宽度的值是否符合同步信号的要求,如果符合就进入数据位的接收,以同样的方式判断逻辑“1”或逻辑“0”。如果接受过程中出现不符合要求的电平状态,就退出接收,为了增加可靠性,我们一般要求规定时间内,成功接收到完全相同的 2 帧数据才算有效。 接收完成后,24 个数据位被放入 3 个字节中。下一步我们要对接收到的数据进行处理,判断编码的类型,分离地址码和按键码。

三、程序代码

/*main.c*/ #include "stm32f10x.h" #include "uart.h" #include "led.h" #include "delay.h" #include "sys.h" #include "timer.h" uint8_t rf_data[4]; extern uint8_t decode_ok; //解码成功标志位 extern uint8_t RF; int main(void) { LED_Init(); Uart_Init(); delay_init(); //延时初始化一定要加上!!!!!! EV1527_GPIO_Init(); TIM6_NVIC_Init(); TIM6_Mode_Init(); while(1) { if(decode_ok == 1) //解码成功 { switch(rf_data[2]) { case 0xf8: //解码为0xf8,点亮LED { LED1 = LED_ON; LED2 = LED_ON; LED3 = LED_ON; break; } case 0xf2: //解码为0xf2,熄灭LED { LED1 = LED_OFF; LED2 = LED_OFF; LED3 = LED_OFF; break; } } } /***调试用代码,查看接收到的编码***/ // printf("\r\n EV1527 \r\n"); // delay_ms(500); // printf("i get %x ",rf_data[0]); // delay_ms(500); // printf("i get %x ",rf_data[1]); // delay_ms(500); // printf("i get %x ",rf_data[2]); // delay_ms(500); // printf("i get %x ",rf_data[3]); // delay_ms(500); } } /************** END OF FILE *****************/ /*Timer.c*/ #include "stm32f10x.h" // Device header #include "timer.h" #include "led.h" #include "uart.h" #include "delay.h" void EV1527_GPIO_Init() //EV1527 IO口初始化 { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // PB9 输入端 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); } //中断函数使用定时器6 void TIM6_NVIC_Init() //中断分组初始化 { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //TIM6中断 NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //先占优先级2级 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //从优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //IRQ通道被使能 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 NVIC_Init(&NVIC_InitStructure); } void TIM6_Mode_Init() { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //使能TIM6时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //初始化定时器6 //设定计数器自动重装值 TIM_TimeBaseStructure.TIM_Period = 100; //时钟预分频系数 驱动计数器的时钟 CK_CNT=CK_INT/(71+1) = 1M //计数器计数1次时间等于1/CK_CNT = 1us TIM_TimeBaseStructure.TIM_Prescaler =71; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //TIM向上计数模式 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //根据指定的参数初始化TIMx的时间基数单位 TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //允许更新中断 TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); TIM_ClearFlag(TIM6,TIM_FLAG_Update); //使能定时器6 TIM_Cmd(TIM6,ENABLE ); } uint8_t RF; uint8_t decode_ok; //解码成功 uint8_t hh_w,ll_w; //高,低电平宽度 uint8_t ma_x; //接收到第几位编码了 uint8_t bma1,bma2,bma3,bma4; //用于接收过程存放遥控编码,编码比较两次,这是第一次 uint8_t mma1,mma2,mma3,mma4; uint8_t mmb1,mmb2,mmb3,mmb4; // 用于接收过程存放遥控编码,第二次 //extern uint8_t mmb1,mmb2,mmb3,mmb4; uint8_t rf_ok1,rf_ok2,rf_ok; //解码过程中的临时接收成功标志,接收到一个完整的遥控命令后置1,通知解码程序可以解码了 uint8_t old_rc5; //保存上一次查询到的电平状态 uint8_t tb_ok; //接收到同步的马时置1 uint8_t D0,D1,D2,D3 ; uint16_t s ,s1; uint8_t bt_auto; //自动设置遥控接收波特率标志 extern uint8_t rf_data[4]; void TIM6_IRQHandler() { if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM6, TIM_IT_Update); //接收数据的电平 PB9 RF = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9); if (!RF) { ll_w++; // 检测到低电平 低电平时间加1,记录本 // 次电平状态old_rc5 old_rc5=0; } else // 检测到高电平 { hh_w++; if (!old_rc5) // 检测到从低到高的跳变,已检测 // 到一个完整(高-低)电平周期 { //判同步码 2/5 100/130 if (((hh_w>=2)&&(hh_w=100)&&(ll_w=8)&& (ll_w23) { if(!rf_ok1) //rf_ok1临时接收成功 { //将接收到的编码复制到解码寄存器中 mma1=bma1; mma2=bma2; mma3=bma3; mma4=bma4; // 通知解码子程序可以解码了 rf_ok1=1; tb_ok=0; s=1000; } else {//将接收到的编码复制到解码寄存器中 mmb1=bma1; mmb2=bma2; mmb3=bma3; mmb4=bma4; // 通知解码子程序可以解码了 rf_ok2=1; tb_ok=0; } } } else if ((tb_ok)&&((ll_w>=2)&& (ll_w


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有