<think>我们正在创建一个基于APM32F103CB微控制器的MDK工程,实现通过LoRa模块无线传输阵列按键信息。主要涉及以下部分:1.硬件连接:APM32F103CB与阵列按键的连接,以及与LoRa模块的连接。2.软件设计:在MDK(Keil)环境下编写代码,包括初始化、按键扫描、LoRa通信等。步骤:1.硬件连接:-阵列按键:通常使用矩阵键盘(例如4x4),将行和列连接到APM32F103CB的GPIO引脚。- LoRa模块:我们使用串口与LoRa模块通信(例如USART1)。连接时注意:-APM32F103CB的USART_TX引脚连接LoRa模块的RX-APM32F103CB的USART_RX引脚连接LoRa模块的TX-共地(GND连接)-注意电源:LoRa模块的供电电压(通常3.3V,而APM32F103CB也是3.3V,所以可以直接供电)2.软件设计:-初始化:*初始化系统时钟(使用APM32标准库)*初始化GPIO(用于矩阵键盘的行和列,行设置为输出,列设置为输入,并开启上拉)*初始化USART(用于与LoRa模块通信,设置波特率,通常LoRa模块默认波特率可能是9600或115200,具体看模块手册)*初始化LoRa模块(通过AT指令设置工作参数,如信道、发射功率等,确保通信双方在同一信道)-按键扫描:*采用扫描方式检测按键按下,并得到按键值(例如0-15)。*消抖处理。-数据传输:*当有按键按下时,将按键值通过串口发送给LoRa模块(以字符串或字节形式)。*LoRa模块会将数据无线发送出去。-接收端(如果需要接收,但题目只要求发送阵列按键信息,所以这里我们只实现发送端,接收端可以类似处理):*本题只要求发送,所以接收端不在本工程范围内,但需要确保接收端能正确接收。3.代码结构(以发送端为例):-main函数流程:*初始化*循环扫描按键,一旦有按键按下,则通过串口发送按键值(通过LoRa模块发送)4.LoRa模块的配置:-通常使用AT指令配置。例如,我们可能需要设置:*工作模式:一般为透传模式(AT+WMODE=TRANSPARENT)*信道(AT+CHAN=xx,例如设置相同的信道)*发射功率(AT+POWER=xx)-注意:具体指令需要参考你所使用的LoRa模块手册。5.代码示例(简化版):注意:以下代码基于假设,实际需要根据硬件连接调整引脚和串口。```c#include "apm32f10x.h"#include "apm32f10x_gpio.h"
#include"apm32f10x_usart.h"
#include"apm32f10x_rcm.h"#include <stdio.h>
#include<string.h>//假设矩阵键盘为4x4,行:PB0-PB3,列:PB4-PB7#define ROW_PINSGPIO_Pin_0 |GPIO_Pin_1 |GPIO_Pin_2 |GPIO_Pin_3#define COL_PINSGPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 |GPIO_Pin_7//行输出,列输入void Keypad_Init(void){GPIO_Config_TgpioConfig;RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB);//行设置为推挽输出,初始高电平(无按键时行输出高,列上拉也为高)gpioConfig.mode= GPIO_MODE_OUT_PP;gpioConfig.pin =ROW_PINS;gpioConfig.speed =GPIO_SPEED_50MHz;GPIO_Config(GPIOB, &gpioConfig);GPIO_SetBits(GPIOB,ROW_PINS);//列设置为输入,上拉模式(因为按键按下会拉低)gpioConfig.mode= GPIO_MODE_IN_PU;gpioConfig.pin =COL_PINS;GPIO_Config(GPIOB, &gpioConfig);}
//扫描按键,返回按键值(0-15),-1表示无按键intKeypad_Scan(void)
{uint8_trow,col;constuint8_t rows[] ={GPIO_Pin_0,GPIO_Pin_1,GPIO_Pin_2,GPIO_Pin_3};constuint8_t cols[] ={GPIO_Pin_4,GPIO_Pin_5,GPIO_Pin_6,GPIO_Pin_7};for(row=0;row <4; row++){//设置当前行为低,其他行为高GPIO_ResetBits(GPIOB, rows[row]);for(uint8_ti=0;i<4;i++){if(i!= row)GPIO_SetBits(GPIOB,rows[i]);}//检查每一列for(col=0;col <4; col++){if (GPIO_ReadInputBit(GPIOB, cols[col]) ==0)//按键按下,该列被拉低{//消抖(简单延时)for(volatile inti=0;i<1000; i++);if(GPIO_ReadInputBit(GPIOB,cols[col])==0){//等待释放while (GPIO_ReadInputBit(GPIOB, cols[col]) ==0);return row*4+ col;}}}//恢复当前行为高GPIO_SetBits(GPIOB,rows[row]);}return -1;}
//初始化串口1(PA9-TX,PA10-RX)
voidUSART1_Init(void)
{GPIO_Config_T gpioConfig;USART_Config_T usartConfig;RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA |RCM_APB2_PERIPH_USART1);//配置USART1TX (PA9)为复用推挽输出gpioConfig.pin= GPIO_Pin_9;gpioConfig.mode =GPIO_MODE_AF_PP;gpioConfig.speed= GPIO_SPEED_50MHz;GPIO_Config(GPIOA,&gpioConfig);//配置USART1RX (PA10)为浮空输入gpioConfig.pin =GPIO_Pin_10;gpioConfig.mode= GPIO_MODE_IN_FLOATING;GPIO_Config(GPIOA,&gpioConfig);usartConfig.baudRate=9600;usartConfig.hardwareFlow= USART_HARDWARE_FLOW_NONE;usartConfig.mode =USART_MODE_TX;usartConfig.parity =USART_PARITY_NONE;usartConfig.stopBits =USART_STOP_BIT_1;usartConfig.wordLength =USART_WORD_LEN_8B;USART_Config(USART1,&usartConfig);USART_Enable(USART1);
}//发送一个字节void USART1_SendByte(uint8_tbyte){while(USART_ReadStatusFlag(USART1,USART_FLAG_TXBE)== RESET);USART_TxData(USART1, byte);
}//发送字符串voidUSART1_SendString(char*str)
{while(*str){USART1_SendByte(*str++);}}
//配置LoRa模块(使用AT指令)
voidLoRa_Init(void){//发送AT指令设置参数,这里以设置信道1为例USART1_SendString("AT+CHAN=1\r\n");//延时等待响应(实际应用中需要更复杂的处理,这里简化)for(volatile inti=0;i<1000000; i++);}
intmain(void)
{intkey;charstr[10];//初始化Keypad_Init();USART1_Init();LoRa_Init();//配置LoRa模块while (1){key= Keypad_Scan();if(key!= -1){//将按键值转换为字符串并发送sprintf(str, "%d\n", key);USART1_SendString(str);}}}
```6.注意事项:-以上代码为简化示例,实际应用中需要根据具体硬件调整引脚。-矩阵键盘扫描函数中的消抖处理可能需要调整延时时间。-LoRa模块的配置需要根据具体模块的AT指令手册进行,并且需要处理模块的响应。-如果LoRa模块需要复杂的配置流程,可能需要编写更健壮的AT指令发送和接收解析函数。7.在MDK中创建工程:-新建工程,选择APM32F103CB作为目标器件。-添加APM32的标准外设库(需要提前下载)。-将上述代码添加到工程中。-配置编译选项,设置正确的头文件路径。-编译并下载到开发板。8.测试:-连接好硬件,上电。-按下矩阵键盘的按键,观察接收端(另一个LoRa模块)是否收到对应的按键值。如果遇到问题,可以检查:-硬件连接是否正确(特别是串口的交叉连接)。-串口波特率是否一致。-LoRa模块的信道、工作模式等参数是否匹配。以上是一个基本的实现框架,具体实现细节需要根据实际硬件和需求进行调整。</think>### 基于 APM32F103CB 的 LoRa 无线阵列按键系统开发指南
#### 一、硬件连接设计
1. **阵列按键连接**
- 采用 4×4 矩阵按键(16键)
- 行线连接:PB12-PB15(配置为推挽输出)
- 列线连接:PB8-PB11(配置为上拉输入)
- 电路设计:
$$V_{cc} \rightarrow 10k\Omega \text{上拉电阻} \rightarrow \text{列线}$$
$$ \text{按键节点} \rightarrow \text{行线(直接连接)} $$
2. **LoRa 模块连接**
- 使用 USART1 通信:
- PA9 (TX) → LoRa 模块 RX
- PA10 (RX) → LoRa 模块 TX
- GND 共地
- 3.3V 电源供电
- 参考 AT 指令配置(波特率 9600)[^1]:
```c
AT+PARAMETER=10,7,1,7 // 设置扩频因子/带宽/编码率
AT+ADDRESS=1 // 设置本机地址
AT+NETWORKID=0 // 设置网络ID
```
#### 二、MDK 工程搭建步骤
1. **创建基础工程**
- 打开 MDK-ARM → 选择 APM32F103CB 器件
- 添加标准外设库(下载地址:Geehy官网)
- 配置系统时钟(72MHz HSE):
```c
RCM_Config_HXTALPrediv(RCM_HXTAL_DIV_1);
RCM_Enable_HXTAL();
RCM_Config_PLL(PLL_SOURCE_HXTAL_DIV_1, PLL_MUL_9);
```
2. **关键驱动实现**
**矩阵按键扫描函数**:
```c
uint8_t Keypad_Scan(void) {
uint8_t key_val = 0xFF;
// 逐行扫描
for(uint8_t i=0; i<4; i++) {
GPIO_ResetBits(GPIOB, ROW_PINS[i]);
for(uint8_t j=0; j<4; j++) {
if(GPIO_ReadInputBit(GPIOB, COL_PINS[j]) == 0) {
key_val = i*4 + j; // 计算键值
while(GPIO_ReadInputBit(GPIOB, COL_PINS[j]) == 0); // 等待释放
}
}
GPIO_SetBits(GPIOB, ROW_PINS[i]);
}
return key_val;
}
```
**LoRa 数据发送函数**:
```c
void LoRa_Send(uint8_t keycode) {
uint8_t cmd[20];
sprintf((char*)cmd, "AT+SEND=2,%d,%d\r\n", DEST_ADDR, keycode); // 目标地址2
for(int i=0; i<strlen((char*)cmd); i++) {
USART_TxData(USART1, cmd[i]);
while(USART_ReadStatusFlag(USART1, USART_FLAG_TXBE) == RESET);
}
}
```
#### 三、主程序逻辑
```c
int main(void) {
// 初始化
System_Clock_Init();
Keypad_GPIO_Init();
USART1_Init(9600); // LoRa串口
LoRa_AT_Init(); // 配置LoRa参数
while(1) {
uint8_t key = Keypad_Scan();
if(key != 0xFF) {
LoRa_Send(key); // 发送按键值
Delay_ms(50); // 防抖延时
}
}
}
```
#### 四、调试要点
1. **LoRa 模块验证**
- 使用串口助手发送 `AT+VER?` 查询固件版本
- 测试指令:`AT+SEND=2,5` 发送测试数据
2. **功耗优化**
- 空闲时进入 STOP 模式:
```c
PWR_EnterSTOPMode(PWR_REGULATOR_LOW, PWR_STOP_ENTRY_WFI);
```
- 按键中断唤醒:配置 EXTI 中断
3. **数据传输格式**
| 字节 | 0 | 1 | 2 |
|------|------|---------|------|
| 含义 | 头(0xAA) | 按键值 | 校验和 |
#### 五、常见问题解决
1. **LoRa 通信失败**
- 检查波特率是否匹配(默认 9600)
- 验证信道参数:`AT+PARAMETER?`
- 确保收发模块 **网络ID/地址** 一致
2. **按键抖动问题**
- 硬件:并联 104 电容
- 软件:二次扫描验证
$$ t_{delay} > t_{bounce} \quad (t_{bounce} \approx 5-20ms) $$
> 实际测试中,在空旷环境下 ATK-LoRa 模块可实现 1km 以上可靠传输[^1],适用于工业遥控等场景。