赞
踩
项目 | 名称 |
---|---|
开发环境 | Windows 10 Enterprise v1809 |
开发工具 | MDK-ARM v5.26 |
SDK版本 | nRF5_SDK_15.2.0_9412b96 |
开发板 | 红旭无线nRF52840/ESP32 mini开发板 |
J-link | 黑色砖头J-link |
nRFgo Studio | 下载最新版本的nRFgo Studio(安装时不要安装nRF5x-Command-Line-Tools,版本太旧) |
nRF5x-Command-Line-Tools | 安装最新版本的nRF5x-Command-Line-Tools(安装时会弹出安装J-link驱动,安装即可,如有老版的J-link驱动,请先卸载在安装) |
Python 2.7.13 | 安装时请选择添加到环境变量(小于2.7.9版本好像安装时没有选项,需要手动添加环境变量) |
nrfutil | windows命令行输入pip install nrfutil后回车(如果Python安装成功并添加环境变量) |
工程位置: G:_03_project_manager\nRF5_SDK_15.2.0_9412b96\examples\ble_peripheral\ble_app_uart_bt5_0\pca10056\s140\arm5_no_packs\ble_app_uart_pca10056_s140.uvprojx
第一次打开工程会弹出安装NordicSemiconductor::nRF_DeviceFamilyPack依赖包的界面,由于网络问题可能会弹出重试的选项卡,选择继续就可以了(可能会多次出现,如果还是不行就等一段时间或者去Keil官网下载对应的包SDK15.2对应8.17.0依赖包)
大部分nRF51840项目开发原理图中只接了外部高速时钟32MHz,没有接外部低速时钟32.768kHz,官方nRF52840开发板上是有外部低速时钟,在sdk_config.h中修改时钟宏定义,如下所示:
#ifndef NRF_SDH_CLOCK_LF_SRC
#define NRF_SDH_CLOCK_LF_SRC 0
#endif
#ifndef NRF_SDH_CLOCK_LF_RC_CTIV
#define NRF_SDH_CLOCK_LF_RC_CTIV 16
#endif
#ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
#define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 2
#endif
#ifndef NRF_SDH_CLOCK_LF_ACCURACY
#define NRF_SDH_CLOCK_LF_ACCURACY 1
#endif
工程配置方式修改
注意:
修改sdk_config.h打印相关的宏定义,工程配置加入DEBUG项,如下所示:
#ifndef NRF_LOG_DEFAULT_LEVEL #define NRF_LOG_DEFAULT_LEVEL 4 #endif #ifndef NRF_LOG_DEFERRED #define NRF_LOG_DEFERRED 0 #endif #ifndef NRF_LOG_USES_COLORS #define NRF_LOG_USES_COLORS 1 #endif #ifndef NRF_LOG_COLOR_DEFAULT #define NRF_LOG_COLOR_DEFAULT 7 #endif #ifndef NRF_SDH_BLE_LOG_LEVEL #define NRF_SDH_BLE_LOG_LEVEL 4 #endif #ifndef NRF_SDH_LOG_LEVEL #define NRF_SDH_LOG_LEVEL 4 #endif #ifndef NRF_SDH_SOC_LOG_LEVEL #define NRF_SDH_SOC_LOG_LEVEL 4 #endif
项目中可能不需要用到UART(UART功耗比较高),需要在“sdk_config.h—>Configuration Wizard—>nRF_Drivers—>对应的宏”中关闭UART控制宏。
int main(void) { //bool erase_bonds; // Initialize. //uart_init(); log_init(); timers_init(); //buttons_leds_init(&erase_bonds); power_management_init(); ble_stack_init(); gap_params_init(); gatt_init(); services_init(); advertising_init(); conn_params_init(); // Start execution. //printf("\r\nUART started.\r\n"); NRF_LOG_INFO("Debug logging for UART over RTT started."); advertising_start(); // Enter main loop. for (;;) { idle_state_handle(); } }
/*******这里开始屏蔽***********/ #if 0 /**@brief Function for handling app_uart events. * * @details This function will receive a single character from the app_uart module and append it to * a string. The string will be be sent over BLE when the last character received was a * 'new line' '\n' (hex 0x0A) or if the string has reached the maximum data length. */ /**@snippet [Handling the data received over UART] */ void uart_event_handle(app_uart_evt_t * p_event) { static uint8_t data_array[BLE_NUS_MAX_DATA_LEN]; static uint8_t index = 0; uint32_t err_code; switch (p_event->evt_type) { case APP_UART_DATA_READY: UNUSED_VARIABLE(app_uart_get(&data_array[index])); index++; if ((data_array[index - 1] == '\n') || (data_array[index - 1] == '\r') || (index >= m_ble_nus_max_data_len)) { if (index > 1) { NRF_LOG_DEBUG("Ready to send data over BLE NUS"); NRF_LOG_HEXDUMP_DEBUG(data_array, index); do { uint16_t length = (uint16_t)index; err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle); if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_RESOURCES) && (err_code != NRF_ERROR_NOT_FOUND)) { APP_ERROR_CHECK(err_code); } } while (err_code == NRF_ERROR_RESOURCES); } index = 0; } break; case APP_UART_COMMUNICATION_ERROR: APP_ERROR_HANDLER(p_event->data.error_communication); break; case APP_UART_FIFO_ERROR: APP_ERROR_HANDLER(p_event->data.error_code); break; default: break; } } /**@snippet [Handling the data received over UART] */ /**@brief Function for initializing the UART module. */ /**@snippet [UART Initialization] */ static void uart_init(void) { uint32_t err_code; app_uart_comm_params_t const comm_params = { .rx_pin_no = RX_PIN_NUMBER, .tx_pin_no = TX_PIN_NUMBER, .rts_pin_no = RTS_PIN_NUMBER, .cts_pin_no = CTS_PIN_NUMBER, .flow_control = APP_UART_FLOW_CONTROL_DISABLED, .use_parity = false, #if defined (UART_PRESENT) .baud_rate = NRF_UART_BAUDRATE_115200 #else .baud_rate = NRF_UARTE_BAUDRATE_115200 #endif }; APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_event_handle, APP_IRQ_PRIORITY_LOWEST, err_code); APP_ERROR_CHECK(err_code); } /**@snippet [UART Initialization] */ #endif /*******这里结束屏蔽***********/
/*******这里开始屏蔽***********/ #if 0 /**@brief Function for handling events from the BSP module. * * @param[in] event Event generated by button press. */ void bsp_event_handler(bsp_event_t event) { uint32_t err_code; switch (event) { case BSP_EVENT_SLEEP: sleep_mode_enter(); break; case BSP_EVENT_DISCONNECT: err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } break; case BSP_EVENT_WHITELIST_OFF: if (m_conn_handle == BLE_CONN_HANDLE_INVALID) { err_code = ble_advertising_restart_without_whitelist(&m_advertising); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } } break; default: break; } } #endif /*******这里结束屏蔽***********/ /*******这里开始屏蔽***********/ #if 0 /**@brief Function for initializing buttons and leds. * * @param[out] p_erase_bonds Will be true if the clear bonding button was pressed to wake the application up. */ static void buttons_leds_init(bool * p_erase_bonds) { bsp_event_t startup_event; uint32_t err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler); APP_ERROR_CHECK(err_code); err_code = bsp_btn_ble_init(NULL, &startup_event); APP_ERROR_CHECK(err_code); *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA); } #endif /*******这里结束屏蔽***********/
static void nus_data_handler(ble_nus_evt_t * p_evt) { if (p_evt->type == BLE_NUS_EVT_RX_DATA) { //uint32_t err_code; NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART."); NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length); #if 0 for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++) { do { err_code = app_uart_put(p_evt->params.rx_data.p_data[i]); if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) { NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code); APP_ERROR_CHECK(err_code); } } while (err_code == NRF_ERROR_BUSY); } if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length - 1] == '\r') { while (app_uart_put('\n') == NRF_ERROR_BUSY); } #endif } }
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) { uint32_t err_code; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: NRF_LOG_INFO("Connected"); /*****屏蔽下面两行*************************/ //err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); //APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_DISCONNECTED: NRF_LOG_INFO("Disconnected"); // LED indication will be changed when advertising starts. m_conn_handle = BLE_CONN_HANDLE_INVALID; break; case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { NRF_LOG_DEBUG("PHY update request."); ble_gap_phys_t const phys = { .rx_phys = BLE_GAP_PHY_AUTO, .tx_phys = BLE_GAP_PHY_AUTO, }; err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: // Pairing not supported err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: // No system attributes have been stored. err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GATTC_EVT_TIMEOUT: // Disconnect on GATT Client timeout event. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server timeout event. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; default: // No implementation needed. break; } }
这里把sleep_mode_enter()也屏蔽掉。
static void on_adv_evt(ble_adv_evt_t ble_adv_evt) { uint32_t err_code; switch (ble_adv_evt) { case BLE_ADV_EVT_FAST: NRF_LOG_INFO("BLE_ADV_EVT_FAST"); /*****屏蔽下面2行,并加打印*************************/ //err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); //APP_ERROR_CHECK(err_code); break; case BLE_ADV_EVT_IDLE: NRF_LOG_INFO("BLE_ADV_EVT_IDLE"); /*****屏蔽下面1行,并加打印*************************/ //sleep_mode_enter(); break; default: break; } }
#define APP_ADV_DURATION 0 /**< The advertising duration (180 seconds) in units of 10 milliseconds. */ static void advertising_init(void) { uint32_t err_code; ble_advertising_init_t init; memset(&init, 0, sizeof(init)); init.advdata.name_type = BLE_ADVDATA_FULL_NAME; init.advdata.include_appearance = false; init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); init.srdata.uuids_complete.p_uuids = m_adv_uuids; init.config.ble_adv_fast_enabled = true; init.config.ble_adv_fast_interval = APP_ADV_INTERVAL; init.config.ble_adv_fast_timeout = APP_ADV_DURATION; init.evt_handler = on_adv_evt; err_code = ble_advertising_init(&m_advertising, &init); APP_ERROR_CHECK(err_code); ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG); }
/********这里开始屏蔽***************/ #if 0 /**@brief Function for putting the chip into sleep mode. * * @note This function will not return. */ static void sleep_mode_enter(void) { uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // Prepare wakeup buttons. err_code = bsp_btn_ble_sleep_mode_prepare(); APP_ERROR_CHECK(err_code); // Go to system-off mode (this function will not return; wakeup will cause a reset). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } /********这里结束屏蔽***************/ #endif
nRF52832开发板的VCC、SWD、SCK、GND的四根线与J-link相连,J-link通过USB接口与电脑相连,如下图所示:
打开nRFgo Studio整片擦除nRF52832程序,并烧录目录\nRF5_SDK_15.2.0_9412b96\components\softdevice\s132\hex\下的132协议栈,如下图所示:
Android手机在Google Play下载nRF UART v2.0(注意有墙)软件,打开:
打开后如果蓝牙时关闭的会弹出一个允许蓝牙权限的对话框,点击允许,然后点Connect开始搜索蓝牙设备,如下图所示:
注意:我的手机开了夜间模式,所以看上去全黑色的背景。
点击Nordic_UART(刚刚烧录程序的设备名就叫这个,main.c里面有定义)
#define DEVICE_NAME "Nordic_UART" /**< Name of device. Will be included in the advertising data. */
点击发送按钮,显示蓝显示已发送数据
设备端打印信息显示已经收到刚刚从手机端发送过来的数据
写博客不容易,需要大家多多支持。想了解更多,本人也可以提供有赏服务
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。