新手村中打满级大BOSS 2025-07-09 14:02 采纳率: 0%
浏览 8
已结题

433无线接收出现问题

433无线接收的程序如下

#include "stm32f0xx.h"
#include <stdio.h>
#include "main.h"
#include "stm32f0xx_rcc.h"
#include "delay.h"
#include "stm32f0xx_exti.h"  
#include "stm32f0xx_syscfg.h" 

// 硬件配置
#define DATA_PIN     GPIO_Pin_15  //B  15
#define DATA_PORT    GPIOB

// 示波器测量
#define LEAD_CODE_HIGH_US   450   
#define LEAD_CODE_LOW_US    14000 

#define BIT_HIGH_US         1200   
#define BIT_LOW_US          400   

// 同步头容差
#define TOLERANCE_MIN 0.9f
#define TOLERANCE_MAX 1.1f


// 定义数据解码状态枚举
typedef enum {
      START,
    LEAD_CODE_H,     
    LEAD_CODE_L, 
    HIGH_BIT, 
    LOW_BIT,    
    COMPARE,    
} Decode_State_t;

// 全局变量和缓冲区
volatile uint32_t Bit_Count = 0;                 // 接收数据位计数
volatile uint32_t Received_Data = 0;             // 接收到的数据
volatile Decode_State_t RF_Decode_State = START; // 数据解码状态
volatile uint8_t Frame_Ready = 0;                // 帧接收完成标志
uint32_t stored_pairing_id = 0;                 // 存储配对成功的ID
uint8_t collected_digits[3] = {0};              // 收集的数字(百、十、个)
uint8_t digit_count = 0;                        // 已收集的数字个数
uint32_t last_time = 0;                         // 上次脉冲时间
uint8_t bit_val = 0;                            // 收集的值

static uint32_t last_received_id = 0;
static uint8_t last_received_key = 0xB;         // 配对模式的按键值

uint32_t H_duration=0;  //高电平脉冲宽度
uint32_t L_duration=0;  //低电平脉冲宽度


// 初始化接收
void RF_RX_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    
    // 配置DO引脚为输入
    GPIO_InitStruct.GPIO_Pin = DATA_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DATA_PORT, &GPIO_InitStruct);
      SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource15);
    
    EXTI_InitTypeDef EXTI_InitStruct;
    EXTI_InitStruct.EXTI_Line = EXTI_Line15;
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//触发 CPU 的中断处理流程
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //双边沿触发
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStruct);
    
    // 配置中断优先级
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = EXTI4_15_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPriority =2;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    // 初始化定时器
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    
    TIM_TimeBaseInitTypeDef TIM_InitStruct;
    TIM_InitStruct.TIM_Prescaler = (SystemCoreClock / 1000000) - 1; 
    TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;    
    TIM_InitStruct.TIM_Period = 0xFFFF;
    TIM_TimeBaseInit(TIM3, &TIM_InitStruct);
      TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//中断使能

    // 配置中断优先级
    NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPriority =0;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);
      
    TIM_Cmd(TIM3, ENABLE);
}
// 定时器溢出计数
volatile uint32_t overflow_count = 0;

// 定时器溢出中断
void TIM3_IRQHandler(void) {
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
        overflow_count++;
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    }
}

// 获取当前时间,微秒
uint64_t micros(void) {
    uint32_t cnt, overflow;
    do {
        overflow = overflow_count;
        cnt = TIM_GetCounter(TIM3);
    } while(overflow != overflow_count); 
    return ((uint64_t)overflow << 16) | cnt;
}


//接收到的数据
void print_received_data(uint32_t data, uint32_t bit_count) {
    char bin_str[25] = {0};
    for (int i = 0; i < 24; i++) {
        uint32_t mask = 1UL << (23 - i);
        bin_str[i] = (data & mask) ? '1' : '0';
    }
    printf("Bit[%d]: %s\n", bit_count, bin_str);
}                        


// 轮询接收函数
void Poll_RF_Receiver(uint16_t current_state) {
   uint32_t current_time = micros();
    uint32_t duration = current_time - last_time;
    last_time = current_time;
        

    switch (RF_Decode_State) {
        case START:
            if (current_state == 0) {
                RF_Decode_State = LEAD_CODE_L;
            }
            break;

        case LEAD_CODE_L:
            if (current_state == 1) {                
                if (duration >= (LEAD_CODE_HIGH_US * TOLERANCE_MIN) && duration <= (LEAD_CODE_HIGH_US * TOLERANCE_MAX)) {
//printf("Dur3=%d\n",duration);    
                                    
                    RF_Decode_State = LEAD_CODE_H;
                } else {
                    RF_Decode_State = START;
                }
            }
            break;

        case LEAD_CODE_H:
            if (current_state == 0) {
                        
                if (duration >= (LEAD_CODE_LOW_US * TOLERANCE_MIN) && duration <= (LEAD_CODE_LOW_US * TOLERANCE_MAX)) {
//printf("Dur4=%d\n",duration);        
                         
                    Received_Data = 0;
                    Bit_Count = 0;
                    RF_Decode_State = LOW_BIT;
                } else {
                    RF_Decode_State = START;
                }
            }
            break;

        case LOW_BIT:
                        
            if (current_state == 1) {     
printf("Dur5=%d\n",duration);
                             if (duration > 1400) { // 1.4ms超时
                                    RF_Decode_State = START;
                                    break;
                            }
                                        L_duration = duration;
                                        RF_Decode_State = HIGH_BIT;
            }
            break;

        case HIGH_BIT:
            if (current_state == 0) { 
printf("Dur6=%d\n",duration);
                             if (duration > 1400) { // 1.4ms超时
                                    RF_Decode_State = START;
                                    break;
                            }
                                        H_duration = duration;
                                        RF_Decode_State = COMPARE;
            }
            break;

                 case COMPARE: 
                    if (  H_duration<L_duration ) {    
                                    bit_val = 1;
                            } else if ( H_duration>L_duration ) {
                                    bit_val = 0;
                            } else {
                                    RF_Decode_State = START;
                                printf("error\n");
                                    break;
                            }
                            
                            // 数据位移
                            //Received_Data = (Received_Data >> 1) | (bit_val << 23);
                            Received_Data = (Received_Data << 1) | bit_val;
                            Bit_Count++;
                            
                            if (Bit_Count >= 24) {
                                    Frame_Ready = 1;
                                    RF_Decode_State = START;
                                    print_received_data(Received_Data, 24);
                            } else {
                                    RF_Decode_State = LOW_BIT;
                            }
                            break;
    }
}


void EXTI4_15_IRQHandler(void) {
    if (EXTI_GetITStatus(EXTI_Line15) != RESET) {
        EXTI_ClearITPendingBit(EXTI_Line15);  // 清除中断标志            
    uint8_t current = GPIO_ReadInputDataBit(DATA_PORT, DATA_PIN);
    Poll_RF_Receiver(current);        


    }
}


日志如下

Dur4=14067
Dur5=1224
Dur6=1374
Dur5=379
Dur6=1360
Dur5=369
Dur6=1370
Dur5=385
Dur6=1358
Dur5=366
Dur6=1358
Dur5=385
Dur6=1362
Dur5=372
Dur6=1364
Dur5=384
Dur6=1354
Dur5=364
Dur6=1360
Dur5=378
Dur6=1360
Dur5=393
Dur6=1353
Dur5=1236
Dur6=19406
Dur5=122
Dur6=713
Dur5=1297
Dur6=871
Dur5=1277
Dur6=844
Dur5=1646
Dur6=860
Dur5=1937
Dur6=866
Dur5=892
Dur6=707
Dur5=1027
Dur6=850
Dur5=1296
Dur6=856
Dur5=1521
Dur6=854
Dur5=1275
Dur6=858
Dur5=986
Dur6=718
Dur5=1363
Dur6=855
Bit[24]: 000000000000011111111111
Dur4=14038
Dur5=1235
Dur6=1361
Dur5=365
Dur6=1373
Dur5=366
Dur6=1376
Dur5=375
Dur6=1375
Dur5=360
Dur6=1357
Dur5=383
Dur6=1357
Dur5=365
Dur6=1363
Dur5=376
Dur6=1362
Dur5=366
Dur6=1378
Dur5=382
Dur6=1361
Dur5=398
Dur6=1344
Dur5=1229
Dur6=19382
Dur5=1180
Dur6=847
Dur5=1866
Dur6=860
Dur5=1610
Dur6=843
Dur5=1184
Dur6=853
Dur5=1220
Dur6=837
Dur5=1763
Dur6=840
Dur5=1655
Dur6=853
Dur5=1243
Dur6=854
Dur5=1631
Dur6=849
Dur5=1390
Dur6=851
Dur5=1801
Dur6=851
Dur5=1198
Dur6=854
Bit[24]: 000000000000111111111111
Dur4=14037
Dur5=1232
Dur6=1348
Dur5=354
Dur6=1368
Dur5=360
Dur6=1352
Dur5=357
Dur6=1369
Dur5=360
Dur6=1368
Dur5=362
Dur6=1367
Dur5=363
Dur6=1364
Dur5=359
Dur6=1363
Dur5=358
Dur6=1374
Dur5=361
Dur6=1365
Dur5=396
Dur6=1336
Dur5=1236
Dur6=18970
Dur5=94
Dur6=614
Dur5=1338
Dur6=847
Dur5=1458
Dur6=835
Dur5=1641
Dur6=853
Dur5=1353
Dur6=852
Dur5=1535
Dur6=853
Dur5=1925
Dur6=868
Dur5=759
Dur6=710
Dur5=1082
Dur6=848
Dur5=922
Dur6=710
Dur5=1573
Dur6=853
Dur5=1339
Dur6=854
Bit[24]: 000000000000011111111111

发送端,连续发送五次以上
发送数据为101010101010101010100001
的时候,接收的日志如上,请问是什么原因?

  • 写回答

4条回答 默认 最新

  • 紫雾凌寒 新星创作者: 人工智能技术领域 2025-07-09 14:02
    关注

    让 “紫雾凌寒” 来帮你回答,本回答结合 DeepSeek

    如果还有问题,请评论或点击头像私信,如果有帮助到您, 请关注、采纳、点赞

    1. 关键点分析
      - 代码目前看起来不完整,仅给出了部分头文件包含,缺少很多关键部分,比如对无线接收相关硬件引脚的配置、中断处理函数等。
      - 仅从现有代码无法明确具体的接收问题所在,可能存在引脚初始化错误、中断配置错误、数据解析错误等多种情况。
    2. 解决方案
      - 硬件引脚配置
      • 首先要确定433无线接收模块连接到STM32F0xx的哪些引脚。例如,如果接收模块的数据引脚连接到PA0,时钟引脚连接到PA1等。
      • 使用GPIO_InitTypeDef结构体来配置引脚。示例代码如下:
    GPIO_InitTypeDef GPIO_InitStruct;
    // 使能GPIOA时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    // 配置PA0为浮空输入
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    • 中断配置(如果需要)
      • 如果无线接收模块有中断信号,需要配置相应的中断。比如外部中断线0连接到接收模块的中断引脚(假设为PA0)。
      • 配置EXTI_InitTypeDef结构体,示例代码如下:
    EXTI_InitTypeDef EXTI_InitStruct;
    // 使能SYSCFG时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    // 配置PA0为EXTI线0
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
    // 配置EXTI线0
    EXTI_InitStruct.EXTI_Line = EXTI_Line0;
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStruct);
    
    • 接收数据处理
      • 在中断处理函数中读取引脚状态获取接收数据。示例中断处理函数如下:
    void EXTI0_IRQHandler(void)
    {
        if (EXTI_GetITStatus(EXTI_Line0) != RESET)
        {
            // 读取PA0引脚状态获取接收数据
            uint8_t receivedData = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
            // 处理接收到的数据,比如解析数据帧等
            // 清除中断标志位
            EXTI_ClearITPendingBit(EXTI_Line0);
        }
    }
    
    1. 多种解决方案的优缺点
      - 基于硬件直接配置方式
      • 优点:直接针对硬件进行底层配置,能够精确控制硬件资源,对于熟悉硬件原理和寄存器操作的开发者来说,能更好地优化性能。
      • 缺点:代码相对复杂,需要对硬件有深入了解,移植性较差,不同硬件平台可能需要大量修改。
      • 使用库函数方式
      • 优点:代码简洁,易于理解和维护,提高开发效率,具有较好的移植性,不同STM32系列甚至不同芯片厂商的库函数使用方式类似。
      • 缺点:对于一些底层硬件细节的控制不如直接操作寄存器灵活,可能会有一些性能上的损耗。
    2. 总结
      - 要解决433无线接收问题,首先要确保硬件连接正确,然后通过合理配置STM32的GPIO引脚和中断(如果需要)来接收数据。在接收数据后,需要根据协议解析数据,以获取正确的信息。代码的完整性和正确性对无线接收功能的实现至关重要,要仔细检查各个部分的配置和处理逻辑。

    希望以上解答对您有所帮助。如果您有任何疑问,欢迎在评论区提出。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 8月25日
  • 创建了问题 7月9日