You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

nRF51/nRF51822 UART引脚映射修改及运行时切换技术咨询

Alright, let's break down your two questions about modifying UART pin mappings on the nRF51822—both statically in code and dynamically at runtime using the g_ADigitalPinMap structure. Here's how to tackle each one clearly:

1. Static UART Pin Mapping Modification in nRF51 Code

If you just need a fixed pin mapping for your custom board, modify the UART initialization code directly:

  • First, locate your project's UART setup function (usually named something like uart_init() or app_uart_init()—check files like uart.c or board_support.c).
  • Look for the UART configuration structure (typically nrf_uart_config_t). Update the psel_tx and psel_rx fields with your desired physical pin numbers (nRF51 uses P0.x pins, so the value is just the x portion). For example, switching from P0.0/P0.1 to P0.10/P0.11:
    nrf_uart_config_t uart_config = {
        .psel_tx = 10,  // Physical pin P0.10 for TX
        .psel_rx = 11,  // Physical pin P0.11 for RX
        .psel_rts = NRF_UART_PSEL_DISCONNECTED,  // Disable RTS if unused
        .psel_cts = NRF_UART_PSEL_DISCONNECTED,  // Disable CTS if unused
        .hwfc = NRF_UART_HWFC_DISABLED,
        .parity = NRF_UART_PARITY_EXCLUDED,
        .baudrate = NRF_UART_BAUDRATE_115200,
    };
    
  • If you're using the SoftDevice, ensure you update any SoftDevice-specific UART enable calls (like sd_uart_enable()) to match the new pins—this avoids resource conflicts.
  • Rebuild and flash your code, and the new pin mapping will be active on boot.
2. Runtime UART Pin Mapping Modification (Using g_ADigitalPinMap)

To switch pins dynamically after communicating with one device and send data to another, follow these steps:

Step 1: Prepare Your Pin Configurations

First, define two sets of pin mappings (one for each serial device) and track the current state:

// Define pin sets for Device A and Device B
#define DEV_A_TX_PIN 10
#define DEV_A_RX_PIN 11
#define DEV_B_TX_PIN 15
#define DEV_B_RX_PIN 16

// Track current active device
typedef enum { DEVICE_A, DEVICE_B } active_device_t;
active_device_t current_device = DEVICE_A;

Step 2: Safely Switch Pins at Runtime

You need to disable the UART first to release the current pins, then update the mapping and reinitialize:

  • Disable the UART peripheral to free up the current pins:
    nrf_uart_disable(NRF_UART0);  // Use your UART instance (UART0/UART1)
    
  • Update g_ADigitalPinMap: This global structure maps logical pin IDs to physical nRF51 pins. If your code uses logical pins for UART TX/RX, update those entries:
    // Assume LOGICAL_UART_TX and LOGICAL_UART_RX are your logical pin IDs
    if (current_device == DEVICE_A) {
        // Switch to Device B
        g_ADigitalPinMap[LOGICAL_UART_TX] = DEV_B_TX_PIN;
        g_ADigitalPinMap[LOGICAL_UART_RX] = DEV_B_RX_PIN;
        current_device = DEVICE_B;
    } else {
        // Switch back to Device A if needed
        g_ADigitalPinMap[LOGICAL_UART_TX] = DEV_A_TX_PIN;
        g_ADigitalPinMap[LOGICAL_UART_RX] = DEV_A_RX_PIN;
        current_device = DEVICE_A;
    }
    
  • Reconfigure the physical pins for UART functionality:
    uint32_t new_tx_pin = g_ADigitalPinMap[LOGICAL_UART_TX];
    uint32_t new_rx_pin = g_ADigitalPinMap[LOGICAL_UART_RX];
    
    nrf_gpio_cfg_output(new_tx_pin);  // Set TX as output
    nrf_gpio_cfg_input(new_rx_pin, NRF_GPIO_PIN_NOPULL);  // Set RX as input (no pull-up/down)
    
  • Update the UART peripheral's pin registers or reinitialize the UART:
    // Option 1: Direct register update (faster)
    NRF_UART0->PSELTXD = new_tx_pin;
    NRF_UART0->PSELRXD = new_rx_pin;
    
    // Option 2: Re-initialize with new config (safer if you need to reset other settings)
    nrf_uart_config_t new_uart_config = {
        .psel_tx = new_tx_pin,
        .psel_rx = new_rx_pin,
        .psel_rts = NRF_UART_PSEL_DISCONNECTED,
        .psel_cts = NRF_UART_PSEL_DISCONNECTED,
        .hwfc = NRF_UART_HWFC_DISABLED,
        .parity = NRF_UART_PARITY_EXCLUDED,
        .baudrate = NRF_UART_BAUDRATE_115200,
    };
    nrf_uart_uninit(NRF_UART0);
    nrf_uart_init(NRF_UART0, &new_uart_config);
    
  • Re-enable the UART to start using the new pins:
    nrf_uart_enable(NRF_UART0);
    

Step 3: Trigger the Switch After Communication Completion

To switch pins right after finishing with the first device:

  • Implement a completion flag or callback. For example, if using interrupt-driven UART, set a flag in the TX/RX complete interrupt handler when communication with Device A is done.
  • Once the flag is set, run the pin switching steps above, then initiate data transmission to Device B.

Critical Notes

  • Avoid Pin Conflicts: Double-check that the new pins aren't used by other peripherals (SPI, I2C, GPIO) before switching.
  • SoftDevice Compatibility: If using the SoftDevice, replace direct nrf_uart_* functions with sd_uart_uninit() and sd_uart_enable(), and ensure pins are allocated via the SoftDevice's resource manager.
  • Timing: Add a short delay (1-2ms) after disabling the UART to ensure hardware releases the pins fully before reconfiguration.

内容的提问来源于stack exchange,提问作者MrEspin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:28:01