STM32 EV1527无线通信(433)
阅读原文时间:2023年07月16日阅读:3
  • EV1527无线通信
    ==========

先说一下这个通信协议的数据格式,这个图片是我在手册里截的。

  1. 大家按照单片机类型计算周期,我的是STM32f103vb (4CLK大致等于350um)
  2. 发送时按照 先发同步码后发DATA 的顺序   逻辑1或者逻辑0按照以上高低电平延时时间长度发送
  • 无线通信发送模式
    ========
  1. 发送很简单,按照数据格式发就行,就是在处理数据上有所变化。无论想发什么数据,16进制10进制最后都要转化成2进制,01发送,从低位向高位发送。
  2. 初始化函数在发送模式里。

/*
@Description 输出高低电平按EV1527协议
@mode 逻辑0或1
*/
void S433_SendBit(u8 mode){

if(mode==)  
{  
    PEout()=;  
    SysTick\_Delay\_Us(\*);  
    PEout()=;  
    SysTick\_Delay\_Us();

}else if(mode==)  
{  
    PEout()=;  
    SysTick\_Delay\_Us();  
    PEout()=;  
    SysTick\_Delay\_Us(\*);

}else{  
    debug\_led(, LED\_TOGGLE);  
}

}

/*
@Description 同步脉冲(或叫引导)
*/
//同步脉冲 4:124
void Sync_Pulse(){

PEout()=;  
SysTick\_Delay\_Us();  
PEout()=;  
SysTick\_Delay\_Us(\*);

}

/*
@Description 发送码函数调用
@num 24位二进制的 10进制数
*/
//对发送过来的10进制数进行处理 , 根据需求可以更改
void S433_Send(u32 num){
u8 i;
u32 result=,temp;
temp = num;

Sync_Pulse();

while(result){  
    i = temp%; //对十进制数取余 结果等于最低位二进制数  
    S433\_SendBit(i);  
    temp = temp/;//除二取整  
    result--;  
}

}

  • 无线通信接收模式

      接收要比发送复杂得多,思路就是

      通过触发外部中断处理函数,来检测数据,每触发一次上升或下降沿,记一下时间,根据时间长度来判段杂波,同步波还是数据波,接收关键在于判断。

      下面一段是一些值的初始化,和IO引脚的初始化

static volatile unsigned long long rx433_previous_time = ;//上一次进入中断时间
static volatile unsigned char Sync_Pulse_begin =;//检测同步脉冲完整性 1是同步脉冲
static volatile unsigned char rx433_begin= ;//同步脉冲开启标志1开启 0没开
static volatile unsigned short interval_previous_time=;//上一个间隔时间
////////////
static volatile u8 Rx433Cnt=;
static volatile u8 Rx433bit[]={};
static volatile u8 rxbit=;
static volatile u8 firstbit=;
static volatile u32 Rx433[]={};
///////////

//对管脚初始化 参考普通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=;  
NVIC\_InitStructure.NVIC\_IRQChannelSubPriority=;  
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()){//每次下降沿开始测

Sync\_Pulse\_begin=;//开始检测同步脉冲

}else if(Sync\_Pulse\_begin==&&(pre==)&&(now==)){//满足条件则判断出时间脉冲

Sync\_Pulse\_begin=;//同步成功将同步码关掉  
rx433\_begin=;//正式开始传输数据  
rxbit=;//将数据位数清零  
firstbit=;//置一等待下个跳变正式开始  
return success;  
}else{

Sync\_Pulse\_begin=;//不是脉冲置0  
return synerror;  
}  
return rxbit;

}

/*
@Description 判断逻辑0和1
@pre 之前时间段数
@now 现在时间段数
@return rxerror 接收超位
*/
u8 RX433_Bit(u8 pre,u8 now){
if(firstbit==){
firstbit=;//此步骤防止引导完成后直接进入此函数
}else if(rx433_begin==&&PEin()){//上升沿检测

if(rxbit>){//能加到24 说明一帧数据获取到了  
rxbit=;//归零  
rx433\_begin=;//归零 及下一组做准备

}

if(now==&&pre==){//逻辑0  
    Rx433bit\[rxbit\]=;  
    rxbit++;  
}else if(now==&&pre==){//逻辑1  
    Rx433bit\[rxbit\]=;  
    rxbit++;  
}else{  
//跑飞  
rx433\_begin=;  
rxbit=;  
return rxerror;  
} 

return rxbit-;
}
return ;
}

外部中断处理函数,常常被触发,因为接收各种杂波,但进入不了关键的处理函数。

//先判断同步脉冲
//如果是同步脉冲,begin开启判断数据接收并判断情况情况
//如果数据接收位超过预期24位,数据位数接收超量(状态)
//如果从一半开始接收,无视这一段,从下一段开始
void EXTI9_5_IRQHandler(void){

if(EXTI\_GetITStatus(EXTI\_Line7)!=RESET)  
{  
    unsigned char skip\_index = ;//这次几个数据位  
    unsigned char skip\_pervious\_index=;//之前几个数据位  
    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/);//得出某个电平持续时长的倍数 计算出几段高或低电平  
    skip\_pervious\_index=(interval\_previous\_time/);//同上 不过是前一次的

    Sync\_PulseRx(skip\_pervious\_index,skip\_index);//同步脉冲  
    RX433\_Bit(skip\_pervious\_index,skip\_index);//数据位

    if(interval\_time<){  
    interval\_previous\_time = interval\_time;

    }else{  
    interval\_previous\_time = ;    

    }  
    EXTI\_ClearITPendingBit(EXTI\_Line7);//清除中断挂起标志位

}

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章