无线通信技术在现代社会中扮演着至关重要的角色,它让我们能够实现便捷的远程控制、智能家居、自动化以及各种物联网应用。无线通信技术包括 WiFi、蓝牙、NFC、Zigbee、5G 等等。

本次我要给大家介绍无线通信技术之一的 433M,从基本概念到工作原理再到实际应用。我们将逐步剖析 433M 模块背后的技术细节。无论您是初学者还是有一定经验的开发者,这篇文章都将为您提供全面的指导和启发,帮助您更好地了解和应用 433M 模块。

1. 源码下载及前置阅读

本文首发 良许嵌入式网https://www.lxlinux.net/e/ ,欢迎关注!

本文所涉及的源码及安装包如下(由于平台限制,请点击以下链接阅读原文下载):

https://www.lxlinux.net/e/stm32/433m-tutorial.html

超全的嵌入式入门教程,欢迎小白。

往期精彩教程,有兴趣的小伙伴可以看看。

作者简介
大家好,我是良许,博客里所有的文章皆为我的原创。
下面是我的一些个人介绍,欢迎交个朋友:
· 211工科硕士,国家奖学金获得者;
· 深耕嵌入式11年,前世界500强外企高级嵌入式工程师;
· 书籍《速学Linux作者》,机械工业出版社专家委员会成员;
· 全网60W粉丝,博客分享大量原创成体系文章,全网阅读量累计超4000万;
· 靠自媒体连续年入百万,靠自己买房买车。

我本科及硕士都是学机械,通过自学成功进入世界500强外企。我已经将自己的学习经验写成了一本电子书,超千人通过此书学习并转行成功。现在将这本电子书免费分享给大家,希望对你们有帮助:

电子书链接:https://www.lxlinux.net/1024.html

<img src="https://lxlinux.superbed.verylink.top/item/674d90ffd0e0a243d4dc0bd7.png" style="zoom:67%;" />

2. 433M无线收发模块介绍

无线收发模块 433MHz(或称RF433射频小模块)采用高频射频技术,并结合了全数字技术和 AVR 单片机,成为一种微型收发器。它能够实现高速数据信号传输,并具备打包、检错和纠错处理的功能。

433M 模块采用工业级标准的部件,工作稳定可靠,体积小巧,安装方便。它在各个领域都有广泛的应用,包括安全报警系统、家庭生活、工业自动化、远程遥控以及无线数据传输等。其可靠性和稳定性使得它成为许多无线通信需求下的理想选择。

3. 型号介绍

首先我们知道遥控器上有四个按键,分别对应 433M 模块的四个数据位输出脚 D0、D1、D2、D3。按下按键发射信号,对应的引脚就会输出高电平。

那么,433M 模块一般按照工作模式分类,有三种工作模式:

  1. M 点动:瞬态输出,相当于自复位开关的状态收到信息输出高电平,无信号时为低电平。
  2. T 锁存:上电时为低,收到信号输出高电平并锁定高,再次收到信号输出低并锁定低。
  3. L 自锁:上电时为低,收到信号输出高电平并锁定高,同时将其他输出置低。

比如我的模块是 M4 点动,「4」表示有4个按键,按一下按键 A,D0 将输出一个高电平。

大家购买的时候要看清楚啦,选择合适的工作模式的 433M 模块哦,它们长的都一样,但是工作模式是不能改的。

温馨小贴士:

  • 天线对模块的接收效果影响很大,最好接 1/4 波长的天线,一般采用 50 欧姆单芯导线,433M 的天线的长度约为 17 cm
  • 天线位置对模块接收效果有影响,安装时,天线尽可能伸直,远离屏蔽体、高压及干扰源的地方。

4. 工作参数及引脚介绍

433M 模块工作参数:

  1. 工作电压:DC 5V
  2. 工作电流:4.5mA
  3. 工作温度:-10 ~ +70℃
  4. 工作频率:433MHz

遥控器工作参数:

  1. 工作电压:DC 12V
  2. 工作电流:10mA
  3. 发射频率:433MHz
  4. 调制方式:ASK
  5. 工作频率:433MHz

接线参考如下:

433M 模块STM32说明
GNDG接地
5V5V电源正极
D0任意一个GPIO口对应遥控器的A
D1任意一个GPIO口对应遥控器的B
D2任意一个GPIO口对应遥控器的C
D3任意一个GPIO口对应遥控器的D
VT任意一个GPIO口输出状态提示,收到有效信号输出高电平

5. 编程实战

5.1 通信示意图

我们的实现目标是:遥控器按下A,红灯状态反转;按下B,黄灯状态反转;按下C,绿灯状态反转。

5.2 硬件连接

本教程使用的硬件如下:

  • 单片机:STM32F103C8T6
  • 433M 模块
  • 小灯:三色 LED 灯模块
  • 烧录器:ST-LINK V2
433M模块STM32LED
GNDG
5V5V
D0A1
D1A2
D2A3
A5R
A6Y
A7G
GGND

烧录的时候接线如下表,如果不会烧录的话可以看我之前的文章【STM32下载程序的五种方法:https://www.lxlinux.net/e/stm32/five-ways-to-flash-program-to...】。

ST-Link V2STM32
SWCLKSWCLK
SWDIOSWDIO
GNDGND
3.3V3V3

接好如下图:

开发板使用的是我们自绘的板子。大家也可以用自己的板子,只要是 STM32F103C8T6 主控芯片就行。

5.3 LED初始化

LED 灯的代码简简单单,只要进行一下三个灯的初始化就行。

void led_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    LED1_GPIO_CLK_ENABLE();                                 /* LED1时钟使能 */
    LED2_GPIO_CLK_ENABLE();                                 /* LED2时钟使能 */
    LED3_GPIO_CLK_ENABLE();                                 /* LED3时钟使能 */

    gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引脚 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽输出 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
    HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引脚 */

    gpio_init_struct.Pin = LED2_GPIO_PIN;                   /* LED2引脚 */
    HAL_GPIO_Init(LED2_GPIO_PORT, &gpio_init_struct);       /* 初始化LED2引脚 */
    
    gpio_init_struct.Pin = LED3_GPIO_PIN;                   /* LED3引脚 */
    HAL_GPIO_Init(LED3_GPIO_PORT, &gpio_init_struct);       /* 初始化LED3引脚 */

    LED1(0);                                                /* 关闭 LED1 */
    LED2(0);                                                /* 关闭 LED2 */
    LED3(0);                                                /* 关闭 LED3 */
}

LED 的 .h文件:

#ifndef _LED_H
#define _LED_H
#include "sys.h"


/******************************************************************************************/
/* 引脚 定义 */

#define LED1_GPIO_PORT                  GPIOA
#define LED1_GPIO_PIN                   GPIO_PIN_5
#define LED1_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)             /* PA口时钟使能 */

#define LED2_GPIO_PORT                  GPIOA
#define LED2_GPIO_PIN                   GPIO_PIN_6
#define LED2_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)             /* PA口时钟使能 */

#define LED3_GPIO_PORT                  GPIOA
#define LED3_GPIO_PIN                   GPIO_PIN_7
#define LED3_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)             /* PA口时钟使能 */

/******************************************************************************************/
/* LED端口定义 */
#define LED1(x)   do{ x ? \
                      HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \
                      HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \
                  }while(0)

#define LED2(x)   do{ x ? \
                      HAL_GPIO_WritePin(LED2_GPIO_PORT, LED2_GPIO_PIN, GPIO_PIN_SET) : \
                      HAL_GPIO_WritePin(LED2_GPIO_PORT, LED2_GPIO_PIN, GPIO_PIN_RESET); \
                  }while(0)

#define LED3(x)   do{ x ? \
                      HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_SET) : \
                      HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_RESET); \
                  }while(0)

/* LED取反定义 */
#define LED1_TOGGLE()   do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0)        /* 翻转LED1 */
#define LED2_TOGGLE()   do{ HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_GPIO_PIN); }while(0)        /* 翻转LED2 */
#define LED3_TOGGLE()   do{ HAL_GPIO_TogglePin(LED3_GPIO_PORT, LED3_GPIO_PIN); }while(0)        /* 翻转LED3 */

/******************************************************************************************/
/* 外部接口函数*/
void led_init(void);                                                                            /* LED初始化 */

#endif

5.4 433M模块代码

代码很简单,就是初始化三个引脚,PA1、PA2、PA3 分别对应 D0、D1、D2。

这次我们采用中断的方式,需要初始化和使能一下 EXTI。

void _433M_gpio_init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();


  /*Configure GPIO pins : PA1 PA2 PA3 */
  GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;       //中断上升沿
  GPIO_InitStruct.Pull = GPIO_NOPULL;               //无电阻
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  
  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI1_IRQn, 2, 0);               /* 抢占2,子优先级0 */
  HAL_NVIC_EnableIRQ(EXTI1_IRQn);

  HAL_NVIC_SetPriority(EXTI2_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI2_IRQn);
  
  HAL_NVIC_SetPriority(EXTI3_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI3_IRQn);
}

5.5 中断服务函数

设计中断服务函数,调用中断处理公用函数。EXTI1、EXTI2、EXTI3 分别设计到 GPIO_PIN_1、GPIO_PIN_2、GPIO_PIN_3。

void EXTI1_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);         /* 调用中断处理公用函数 清除中断线 的中断标志位 */
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);         /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}

void EXTI2_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);         /* 调用中断处理公用函数 清除中断线 的中断标志位 */
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_2);         /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}
void EXTI3_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);         /* 调用中断处理公用函数 清除中断线 的中断标志位 */
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_3);         /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}

5.6 LED控制

复写「HAL_GPIO_EXTI_Callback」函数,检测到中断上升沿,则表示按键被按下,翻转对应的 LED。

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    switch(GPIO_Pin)
    {
        case GPIO_PIN_1:
        if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) ==  GPIO_PIN_SET)
        {
            LED1_TOGGLE();
        }
        break;
        
        case GPIO_PIN_2:
        if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) ==  GPIO_PIN_SET)
        {
            LED2_TOGGLE();
        }
        break;
        
        case GPIO_PIN_3:
        if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) ==  GPIO_PIN_SET)
        {
            LED3_TOGGLE();
        }
        break;
    }
}

5.7 效果展示

遥控器按下A,红灯状态反转;按下B,黄灯状态反转;按下C,绿灯状态反转。

下图是按下A、B、C,三灯齐亮的效果。

6. 总结

随着物联网的快速发展和智能化需求的增加,无线通信技术将扮演越来越重要的角色。433M 模块作为一种低功耗、长距离传输的技术,具有广泛的应用前景。从遥控门禁到智能家居自动化,从环境监测到安防系统,433M 模块为各种应用场景带来了便捷和创新。希望本文能够给您带来小小的启发,并激发您在无线通信领域进一步探索和创造的热情。感谢各位看官, peace and love!


良许
1k 声望1.8k 粉丝