大家好,欢迎来到IT知识分享网。
-
EV1527无线通信
先说一下这个通信协议的数据格式,这个图片是我在手册里截的。
- 大家按照单片机类型计算周期,我的是STM32f103vb (4CLK大致等于350um)
- 发送时按照 先发同步码后发DATA 的顺序 逻辑1或者逻辑0按照以上高低电平延时时间长度发送
-
无线通信发送模式
- 发送很简单,按照数据格式发就行,就是在处理数据上有所变化。无论想发什么数据,16进制10进制最后都要转化成2进制,01发送,从低位向高位发送。
- 初始化函数在发送模式里。
/* @Description 输出高低电平按EV1527协议 @mode 逻辑0或1 */ void S433_SendBit(u8 mode){ if(mode==1) { PEout(9)=1; SysTick_Delay_Us(350*3); PEout(9)=0; SysTick_Delay_Us(350); }else if(mode==0) { PEout(9)=1; SysTick_Delay_Us(350); PEout(9)=0; SysTick_Delay_Us(350*3); }else{ debug_led(1, LED_TOGGLE); } } /* @Description 同步脉冲(或叫引导) */ //同步脉冲 4:124 void Sync_Pulse(){ PEout(9)=1; SysTick_Delay_Us(350); PEout(9)=0; SysTick_Delay_Us(350*31); } /* @Description 发送码函数调用 @num 24位二进制的 10进制数 */ //对发送过来的10进制数进行处理 , 根据需求可以更改 void S433_Send(u32 num){ u8 i; u32 result=24,temp; temp = num; Sync_Pulse(); while(result){ i = temp%2; //对十进制数取余 结果等于最低位二进制数 S433_SendBit(i); temp = temp/2;//除二取整 result--; } }
-
无线通信接收模式
接收要比发送复杂得多,思路就是
通过触发外部中断处理函数,来检测数据,每触发一次上升或下降沿,记一下时间,根据时间长度来判段杂波,同步波还是数据波,接收关键在于判断。
下面一段是一些值的初始化,和IO引脚的初始化
static volatile unsigned long long rx433_previous_time = 0;//上一次进入中断时间 static volatile unsigned char Sync_Pulse_begin =0;//检测同步脉冲完整性 1是同步脉冲 static volatile unsigned char rx433_begin= 0;//同步脉冲开启标志1开启 0没开 static volatile unsigned short interval_previous_time=0;//上一个间隔时间 //////////// static volatile u8 Rx433Cnt=0; static volatile u8 Rx433bit[30]={0}; static volatile u8 rxbit=0; static volatile u8 firstbit=0; static volatile u32 Rx433[64]={0}; /////////// //对管脚初始化 参考普通IO管脚用通信 void S433_SR_Init(){ GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); //使能GPIOE时钟 //E9使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); GPIO_ResetBits(GPIOE, GPIO_Pin_9);// 引脚拉低 //接收 E7 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //输入为低 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource7); EXTI_InitStructure.EXTI_Line=EXTI_Line7; EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; NVIC_InitStructure.NVIC_IRQChannelSubPriority=2; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); }
是否是同步波判断,以及检测发送完成度
/* @Description 判断是否是同步脉冲 @pre 之前时间段数 @now 现在时间段数 @return rebit开启同步 success同步成功 synerror 不是同步脉冲 */ u8 Sync_PulseRx(u8 pre,u8 now){ if(!PEin(7)){//每次下降沿开始测 Sync_Pulse_begin=1;//开始检测同步脉冲 }else if(Sync_Pulse_begin==1&&(pre==1)&&(now==31)){//满足条件则判断出时间脉冲 Sync_Pulse_begin=0;//同步成功将同步码关掉 rx433_begin=1;//正式开始传输数据 rxbit=0;//将数据位数清零 firstbit=1;//置一等待下个跳变正式开始 return success; }else{ Sync_Pulse_begin=0;//不是脉冲置0 return synerror; } return rxbit; } /* @Description 判断逻辑0和1 @pre 之前时间段数 @now 现在时间段数 @return rxerror 接收超位 */ u8 RX433_Bit(u8 pre,u8 now){ if(firstbit==1){ firstbit=0;//此步骤防止引导完成后直接进入此函数 }else if(rx433_begin==1&&PEin(7)){//上升沿检测 if(rxbit>24){//能加到24 说明一帧数据获取到了 rxbit=0;//归零 rx433_begin=0;//归零 及下一组做准备 } if(now==3&&pre==1){//逻辑0 Rx433bit[rxbit]=0; rxbit++; }else if(now==1&&pre==3){//逻辑1 Rx433bit[rxbit]=1; rxbit++; }else{ //跑飞 rx433_begin=0; rxbit=0; return rxerror; } return rxbit-1; } return 0; }
外部中断处理函数,常常被触发,因为接收各种杂波,但进入不了关键的处理函数。
//先判断同步脉冲 //如果是同步脉冲,begin开启判断数据接收并判断情况情况 //如果数据接收位超过预期24位,数据位数接收超量(状态) //如果从一半开始接收,无视这一段,从下一段开始 void EXTI9_5_IRQHandler(void){ if(EXTI_GetITStatus(EXTI_Line7)!=RESET) { unsigned char skip_index = 0;//这次几个数据位 unsigned char skip_pervious_index=0;//之前几个数据位 unsigned long long now_time=sys_micros();//此刻时间 unsigned short interval_time = now_time - rx433_previous_time;//计算一个电平状态持续的时长 rx433_previous_time = now_time;//为下次计算时长做准备 skip_index = (interval_time/349);//得出某个电平持续时长的倍数 计算出几段高或低电平 skip_pervious_index=(interval_previous_time/349);//同上 不过是前一次的 Sync_PulseRx(skip_pervious_index,skip_index);//同步脉冲 RX433_Bit(skip_pervious_index,skip_index);//数据位 if(interval_time<45000){ interval_previous_time = interval_time; }else{ interval_previous_time = 0; } EXTI_ClearITPendingBit(EXTI_Line7);//清除中断挂起标志位 } }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/32122.html