首页 新闻 会员 周边 捐助

433无线收发,收不到准确数据,怎么回事?

1
悬赏园豆:200 [已解决问题] 解决于 2025-08-26 16:43

正在开发一个433无线通信的东西,发射端输入数字,使用曼彻斯特编码,通过无线发送模块,发送到接收端的显示板上,现在就是无法接收数据,弄了好久了,是什么原因,各位大佬帮忙看看

发送端代码如下
// 添加配对模式标志
uint8_t pairing_mode = 0;

//S14正常模式发送数字
void S14_SendNumber(void)
{
uint8_t data[3] = {0};

// 配对模式下发送配对码
if(pairing_mode) {
    // 将显示的三位数转换为配对码
    uint16_t pairing_code = display_num[0] * 100 + 
                           display_num[1] * 10 + 
                           display_num[2];
			printf("pairing_code=%d",pairing_code);
    current_id =  (0x123 & 0x3FF) << 10  | (pairing_code & 0x3FF);
			printf("current_id=0x%04X\n",current_id);

	  	uint32_t frame_24bit = ((uint32_t)current_id << 4) | 0xB;
    printf("发送的24位: 0x%06lX\n", (unsigned long)frame_24bit);
		  // 打印二进制(24位,左补零)
			printf("二进制: ");
			for (int i = 23; i >= 0; i--) {
					printf("%d", (frame_24bit >> i) & 1);
			}
			printf("\n");

    EV1527_send_frame(0xB);
    pairing_mode = 0;  // 退出配对模式
    S11_clean();       

    // 显示配对成功提示
    TM1650_DisplayOne(1, 0x73); // P
    TM1650_DisplayOne(2, 0x5E); // d
    TM1650_DisplayOne(3, 0x00);
    TM1650_DisplayOne(4, 0x00);
    delay_us(100);    // 显示1秒
    S11_clean();       // 再次清空显示
} 
// 正常模式发送数字
else {
    // 确保有3位数字,不足则补0
    uint8_t send_data[3] = {0};
    int start_index = 3 - current_digits;
    for (int i = 0; i < current_digits; i++) {
        send_data[start_index + i] = display_num[i];
    }
			printf("Send Data: [%d, %d, %d]\n", send_data[0], send_data[1], send_data[2]);
    // 发送三位数(分三帧发送)
    for (int i = 0; i < 3; i++) {
					// 打印要发送的24位数据
					uint32_t frame = ((uint32_t)current_id << 4) | (send_data[i] & 0x0F);

					printf("发送24位数据[%d]: 0x%06lX, 二进制: ", i, (unsigned long)frame);
					for(int j = 23; j >= 0; j--) {
							printf("%d", (frame >> j) & 1);
					}
					printf("\n");

        Radio_Send(&send_data[i], 1);  // 每次发送一位
    }

}

}

// S15_configure进入配对模式
void S15_configure(void)
{
pairing_mode = 1; // 进入配对模式
current_digits = 0; // 重置输入计数器

// 显示配对提示
TM1650_DisplayOne(1, 0x73); // P
TM1650_DisplayOne(2, 0x39); // C
TM1650_DisplayOne(3, 0x00);
TM1650_DisplayOne(4, 0x00);

}

include <stm32f0xx.h>

include "tm1650.h"

include "delay.h"

include "uart.h"

include "key.h"

include "stdio.h"

include "string.h"

include "radio.h"

// 硬件配置

define EV1527_TX_PIN GPIO_Pin_2

define EV1527_TX_PORT GPIOA

define CLK_PERIOD_US 100

// 预设ID编码

define EV1527_ID_CODE 0xAAAAA

uint32_t current_id = EV1527_ID_CODE; // 初始为预设ID

void Radio_init(void)
{
GPIO_InitTypeDef GPIO_InitStructeru;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

GPIO_InitStructeru.GPIO_Pin = EV1527_TX_PIN;
GPIO_InitStructeru.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructeru.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructeru.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructeru.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(EV1527_TX_PORT, &GPIO_InitStructeru);

GPIO_ResetBits(EV1527_TX_PORT, EV1527_TX_PIN);
printf("Software Radio Initialized\n");

}

// 发送同步码
void send_sync(void) {

GPIO_SetBits(EV1527_TX_PORT, EV1527_TX_PIN); 
delay_us(450);

GPIO_ResetBits(EV1527_TX_PORT, EV1527_TX_PIN);   
delay_us(14000);

}

// 发送单个数据
void send_bit(uint8_t bit_value) {
if(bit_value) { // 发送'1'
GPIO_SetBits(EV1527_TX_PORT, EV1527_TX_PIN);
delay_us(1300);

    GPIO_ResetBits(EV1527_TX_PORT, EV1527_TX_PIN);
    delay_us(450);
} else { // 发送'0'
    GPIO_SetBits(EV1527_TX_PORT, EV1527_TX_PIN);
    delay_us(450);			

    GPIO_ResetBits(EV1527_TX_PORT, EV1527_TX_PIN);
    delay_us(1300);

}

}

// 发送完整数据

void EV1527_send_frame(uint8_t key_data) {

    send_sync();
// 发送20位ID(高位在前)bit19~bit0
for(int8_t i = 19; i >= 0; i--) {
    send_bit((current_id >> i) & 0x01);
}
// 发送4位按键数据(高位在前)bit3~bit0
for(int8_t i = 3; i >= 0; i--) {
    send_bit((key_data >> i) & 0x01);
}

//GPIO_SetBits(EV1527_TX_PORT, EV1527_TX_PIN);

GPIO_ResetBits(EV1527_TX_PORT, EV1527_TX_PIN);

}

void Radio_Send(uint8_t *data, uint8_t len) {

for(uint8_t i = 0; i < len; i++) {
    // 确保数据在0-9范围内
    uint8_t key_value = data[i] & 0x0F;
    EV1527_send_frame(key_value);
   	delay_ms(13); // 帧间隔
}

}

接收端代码如下

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.95f

define TOLERANCE_MAX 1.05f

// 定义数据解码状态枚举
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 =0;
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; // 1MHz频率
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 =2;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
  
TIM_Cmd(TIM3, ENABLE);

}
// 定时器溢出计数(扩展为 64 位时间戳)
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 = TIM_GetCounter(TIM3);
return ((uint64_t)overflow_count << 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 == 1) {
            RF_Decode_State = LEAD_CODE_H;
        }
        break;

    case LEAD_CODE_H:
        if (current_state == 0) {				
            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_L;
            } else {
                RF_Decode_State = START;
            }
        }
        break;

    case LEAD_CODE_L:
        if (current_state == 1) {
					
            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 = HIGH_BIT;
            } else {
                RF_Decode_State = START;
            }
        }
        break;

    case HIGH_BIT:
					
        if (current_state == 0) { 	

printf("Dur5=%d\n",duration);
H_duration = duration;
RF_Decode_State = LOW_BIT;
}
break;

    case LOW_BIT:
        if (current_state == 1) { 

printf("Dur6=%d\n",duration);
L_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 = HIGH_BIT;
						}
						break;
}

}

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

}

}

void Process_Received_Frame(void) {
if (!Frame_Ready) return;

// 直接提取20位ID和4位按键
uint32_t received_id = (Received_Data >> 4) & 0xFFFFF;
uint8_t received_key = Received_Data & 0x0B;

// 防止重复帧干扰
if (received_id == last_received_id && received_key == last_received_key) {
    Frame_Ready = 0;
    return;
}
last_received_id = received_id;
last_received_key = received_key;
// 配对模式处理

if (received_key == 0xB) {
// 预期的配对ID
uint32_t expected_id = ((0x123UL & 0x3FF) << 10) |
(((uint32_t)pairing_code[0] * 100 +
(uint32_t)pairing_code[1] * 10 +
(uint32_t)pairing_code[2]) & 0x3FF);
//uint32_t expected_id = (0x123UL & 0x3FF) << 10 | (pairing_code & 0x3FF);

// 判断 received_id 是否等于期望值
if (received_id == expected_id) {
    stored_pairing_id = received_id;
    sys_state = STATE_CONNECTED;

    printf("Pairing_OK ID:0x%05lX, Code:%d%d%d\n",
           (unsigned long)(received_id & 0xFFFFF),
           pairing_code[0], pairing_code[1], pairing_code[2]);
}else {
    printf("ID不匹配,期望ID: 0x%05lX : 实际ID: 0x%05lX\n",
           (unsigned long)expected_id,
           (unsigned long)(received_id & 0xFFFFF));
}

}
// 正常模式
else if (sys_state == STATE_CONNECTED && received_id == stored_pairing_id) {
if (received_key <= 9) {
if (digit_count < 3) {
collected_digits[digit_count] = received_key;
digit_count++;

            // 构造要显示的三个数字
            uint8_t display_digits[3];
            for (int i = 0; i < 3; i++) {
                display_digits[i] = (i < digit_count) ? collected_digits[i] : 10; // 10 表示空白或横杠
            }
            UpdateDisplay(display_digits[0], display_digits[1], display_digits[2]);

            if (digit_count == 3) {
                printf("received_OK: %d%d%d\n",
                       collected_digits[0], collected_digits[1], collected_digits[2]);
                digit_count = 0;
            }
        }
    }
} 

Frame_Ready = 0;

}
// 检查无线数据
uint8_t CheckRadio(void) {
if (Frame_Ready) {
Process_Received_Frame();

    return 1; // 有新数据
}
return 0; // 无新数据

}

接收端部分日志如下
Bit[24]: 000000010000000000010000
Dur4=14538
Dur5=1429
Dur6=1362
Dur5=89
Dur6=590
Dur5=50
Dur6=4036
Dur5=102
Dur6=748
Dur5=184
Dur6=122
Dur5=30
Dur6=66
Dur5=39
Dur6=5665
Dur5=111
Dur6=888
Dur5=57
Dur6=4119
Dur5=201
Dur6=-59762
Dur5=133
Dur6=74
Dur5=54
Dur6=228
Dur5=227
Dur6=199
Dur5=116
Dur6=6745
Dur5=60
Dur6=9796
Dur5=36
Dur6=1248
Dur5=68
Dur6=199
Dur5=39
Dur6=570
Dur5=112
Dur6=90
Dur5=56
Dur6=2193
Dur5=64
Dur6=536
Dur5=169
Dur6=3389
Dur5=214
Dur6=399
Dur5=55
Dur6=57
Bit[24]: 100010000010100000100000
Dur4=14427
Dur5=1099
Dur6=1054
Dur5=74
Dur6=19220
Dur5=7874
Dur6=902
Dur5=68
Dur6=53
Dur5=353
Dur6=38
Dur5=1963
Dur6=324
Dur5=92
Dur6=1575
Dur5=212
Dur6=783
Dur5=1201
Dur6=365
Dur5=422
Dur6=3541
Dur5=276
Dur6=1681
Dur5=92
Dur6=36
Dur5=165
Dur6=5070
Dur5=61
Dur6=62
Dur5=361
Dur6=2132
Dur5=187
Dur6=54
Dur5=93
Dur6=86
Dur5=59
Dur6=1543
Dur5=1384
Dur6=39
Dur5=273
Dur6=46
Dur5=130
Dur6=169
Dur5=196
Dur6=1479
Dur5=126
Dur6=-58834
Dur5=1412
Dur6=884
Bit[24]: 101111001001000110110001
Dur4=13825
Dur5=1244
Dur6=1128
Dur5=39
Dur6=-57005
Dur5=222
Dur6=9101
Dur5=93
Dur6=1279
Dur5=55
Dur6=181
Dur5=60
Dur6=43
Dur5=121
Dur6=70
Dur5=202
Dur6=691
Dur5=103
Dur6=799
Dur5=49
Dur6=61
Dur5=42
Dur6=60
Dur5=935
Dur6=1170
Dur5=152
Dur6=931
Dur5=91
Dur6=956
Dur5=184
Dur6=1069
Dur5=47
Dur6=3539
Dur5=173
Dur6=99
Dur5=151
Dur6=70
Dur5=140
Dur6=40
Dur5=98
Dur6=521
Dur5=34
Dur6=119
Dur5=44
Dur6=148
Dur5=63
Dur6=64
Dur5=206
Dur6=688
Bit[24]: 100001100000000011100000

发送端日志如下
KEY_MAP=14
key_scan=14
Send Data: [2, 3, 6]
发送24位数据[0]: 0xAAAAA2, 二进制: 101010101010101010100010
发送24位数据[1]: 0xAAAAA3, 二进制: 101010101010101010100011
发送24位数据[2]: 0xAAAAA6, 二进制: 101010101010101010100110

为何发送的数据和接收的数据不一致?
并且发送端,每次是发送3位数据的,而接收端只能接收到一位数据
逻辑分析仪中,发射端的波形和接收端的波形是一致的

新手村中打大boss的主页 新手村中打大boss | 初学一级 | 园豆:-3
提问于:2025-07-07 19:33

麻烦您调整一下排版,支持 markdown 语法

博客园团队 3个月前
< >
分享
最佳答案
1

我曾经遇到过类似的问题,433无线收发无法收到准确数据,主要可能是由以下几方面原因导致的:

从你的情况来看,发送端能正常发送数据,逻辑分析仪也显示发射端和接收端的波形一致,但接收数据不准确且只能收到一位,可能是同步和时序匹配出现了问题。发送端发送‘1’时高电平1300微秒、低电平450微秒,发送‘0’时高电平450微秒、低电平1300微秒,而接收端判断‘1’和‘0’是通过比较高低电平持续时间,这种判断方式对时序精度要求很高。另外,接收端日志中出现了负数的持续时间,这可能是定时器溢出或时间计算错误导致的,会干扰对高低电平的判断,进而影响数据接收的准确性。同时,发送端分三帧发送三位数字,接收端需要正确识别这三帧并按顺序收集,但目前可能存在帧识别或顺序错乱的问题,导致只能收到一位数据。

以下是两种解决方案:

  1. 优化时序判断机制:重新调整接收端对高低电平持续时间的判断逻辑,不再单纯比较两者大小,而是根据发送端的时序参数设置合理的阈值范围。比如,当高电平持续时间在1200-1400微秒、低电平在400-500微秒时判断为‘1’;当高电平在400-500微秒、低电平在1200-1400微秒时判断为‘0’。这样能减少因微小时间波动导致的判断错误,同时解决负数持续时间带来的干扰,可在接收端的COMPARE状态处理部分修改判断条件。
  2. 增加帧同步标识:在发送端发送的每帧数据中加入特定的帧同步标识,比如在每帧数据的开头和结尾加入固定的二进制序列。接收端在接收数据时,先识别到这些同步标识,再提取中间的有效数据。这样接收端能准确区分不同的帧,确保三位数字按正确顺序被收集,避免因帧识别错误导致只能收到一位数据的情况,需要在发送端的Radio_Send函数中添加同步标识的发送,同时在接收端的Process_Received_Frame函数中添加对同步标识的识别和处理。

最优方案是优化时序判断机制。因为从问题表现来看,接收端对高低电平的判断不准确是导致数据接收异常的主要原因,而时序判断机制的优化能直接针对这一核心问题。通过设置合理的阈值范围,能有效减少时间波动和异常值对判断的影响,提高数据接收的准确性。相比增加帧同步标识,这种方案不需要对发送的数据结构进行大的改动,实现起来更简单直接,能更快地解决当前接收不到准确数据的问题。而且解决了时序判断的根本问题后,再处理帧的识别和数字收集会更加顺利。

请楼主采纳,如果按照上述方案操作后还有问题,请继续留言。

收获园豆:200
一杯年华-编程空间 | 菜鸟二级 |园豆:404 | 2025-07-10 23:53

谢谢您的解答,我现在换了一个方式,使用定时器中断
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);

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

// 配置中断优先级
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority =0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
  
TIM_Cmd(TIM3, ENABLE);

}

自动重载值设置为100.就是100us中断一次,然后判断在每个电平脉宽之间中断了多少次就可以了。现在已经成功接收到完整的数据

新手村中打大boss | 园豆:-3 (初学一级) | 2025-07-11 09:05
其他回答(1)
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);

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

// 配置中断优先级
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority =0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);

TIM_Cmd(TIM3, ENABLE);
}

自动重载值设置为100.就是100us中断一次,然后判断在每个电平脉宽之间中断了多少次就可以了。现在已经成功接收到完整的数据

新手村中打大boss | 园豆:-3 (初学一级) | 2025-07-11 17:47
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册