STM32 EV1527無線通信(433)


 

  • 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==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);//清除中斷掛起標志位

    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM