无线通信技术在现代社会中扮演着至关重要的角色,它让我们能够实现便捷的远程控制、智能家居、自动化以及各种物联网应用。无线通信技术包括 WiFi、蓝牙、NFC、Zigbee、5G 等等。
本次我要给大家介绍无线通信技术之一的 433M,从基本概念到工作原理再到实际应用。我们将逐步剖析 433M 模块背后的技术细节。无论您是初学者还是有一定经验的开发者,这篇文章都将为您提供全面的指导和启发,帮助您更好地了解和应用 433M 模块。
本文首发 良许嵌入式网 :https://www.lxlinux.net/e/ ,欢迎关注!
本文所涉及的源码及安装包如下(由于平台限制,请点击以下链接阅读原文下载):
https://www.lxlinux.net/e/stm32/433m-tutorial.html
超全的嵌入式入门教程,欢迎小白。
往期精彩教程,有兴趣的小伙伴可以看看。
ESP8266详解,助你成为物联网应用的专家:【手把手教你玩转ESP8266(原理+驱动):https://www.lxlinux.net/e/stm32/esp8266-tutorial.html】
简单好用,为你的智能语音项目提供核心支持:【SU-03T语音控制模块详解:https://www.lxlinux.net/e/stm32/SU-03T-tutorial.html】
如果想知道自己对嵌入式知识掌握程度:【嵌入式自测题:https://www.lxlinux.net/e/stm32/embedded-self-test.html】
作者简介 |
---|
大家好,我是良许,博客里所有的文章皆为我的原创。 下面是我的一些个人介绍,欢迎交个朋友: · 211工科硕士,国家奖学金获得者; · 深耕嵌入式11年,前世界500强外企高级嵌入式工程师; · 书籍《速学Linux作者》,机械工业出版社专家委员会成员; · 全网60W粉丝,博客分享大量原创成体系文章,全网阅读量累计超4000万; · 靠自媒体连续年入百万,靠自己买房买车。 |
我本科及硕士都是学机械,通过自学成功进入世界500强外企。我已经将自己的学习经验写成了一本电子书,超千人通过此书学习并转行成功。现在将这本电子书免费分享给大家,希望对你们有帮助:
电子书链接:https://www.lxlinux.net/1024.html
无线收发模块 433MHz(或称RF433射频小模块)采用高频射频技术,并结合了全数字技术和 AVR 单片机,成为一种微型收发器。它能够实现高速数据信号传输,并具备打包、检错和纠错处理的功能。
433M 模块采用工业级标准的部件,工作稳定可靠,体积小巧,安装方便。它在各个领域都有广泛的应用,包括安全报警系统、家庭生活、工业自动化、远程遥控以及无线数据传输等。其可靠性和稳定性使得它成为许多无线通信需求下的理想选择。
首先我们知道遥控器上有四个按键,分别对应 433M 模块的四个数据位输出脚 D0、D1、D2、D3。按下按键发射信号,对应的引脚就会输出高电平。
那么,433M 模块一般按照工作模式分类,有三种工作模式:
比如我的模块是 M4 点动,「4」表示有4个按键,按一下按键 A,D0 将输出一个高电平。
大家购买的时候要看清楚啦,选择合适的工作模式的 433M 模块哦,它们长的都一样,但是工作模式是不能改的。
温馨小贴士:
433M 模块工作参数:
遥控器工作参数:
接线参考如下:
433M 模块 | STM32 | 说明 |
---|---|---|
GND | G | 接地 |
5V | 5V | 电源正极 |
D0 | 任意一个GPIO口 | 对应遥控器的A |
D1 | 任意一个GPIO口 | 对应遥控器的B |
D2 | 任意一个GPIO口 | 对应遥控器的C |
D3 | 任意一个GPIO口 | 对应遥控器的D |
VT | 任意一个GPIO口 | 输出状态提示,收到有效信号输出高电平 |
我们的实现目标是:遥控器按下A,红灯状态反转;按下B,黄灯状态反转;按下C,绿灯状态反转。
本教程使用的硬件如下:
433M模块 | STM32 | LED |
---|---|---|
GND | G | |
5V | 5V | |
D0 | A1 | |
D1 | A2 | |
D2 | A3 | |
A5 | R | |
A6 | Y | |
A7 | G | |
G | GND |
烧录的时候接线如下表,如果不会烧录的话可以看我之前的文章【STM32下载程序的五种方法:https://www.lxlinux.net/e/stm32/five-ways-to-flash-program-to-stm32.html】。
ST-Link V2 | STM32 |
---|---|
SWCLK | SWCLK |
SWDIO | SWDIO |
GND | GND |
3.3V | 3V3 |
接好如下图:
开发板使用的是我们自绘的板子。大家也可以用自己的板子,只要是 STM32F103C8T6 主控芯片就行。
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
代码很简单,就是初始化三个引脚,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); }
设计中断服务函数,调用中断处理公用函数。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库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */ }
复写「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; } }
遥控器按下A,红灯状态反转;按下B,黄灯状态反转;按下C,绿灯状态反转。
下图是按下A、B、C,三灯齐亮的效果。
另外,想进大厂的同学,一定要好好学算法,这是面试必备的。这里准备了一份 BAT 大佬总结的 LeetCode 刷题宝典,很多人靠它们进了大厂。
刷题 | LeetCode算法刷题神器,看完 BAT 随你挑!
推荐阅读:
欢迎关注我的博客:良许嵌入式教程网,满满都是干货!