<cite id="9vvnb"></cite>
<cite id="9vvnb"></cite>
<var id="9vvnb"><strike id="9vvnb"></strike></var>
<menuitem id="9vvnb"><strike id="9vvnb"><listing id="9vvnb"></listing></strike></menuitem>
<cite id="9vvnb"><video id="9vvnb"></video></cite>
<cite id="9vvnb"></cite>
<cite id="9vvnb"><video id="9vvnb"></video></cite>
<var id="9vvnb"></var>
<cite id="9vvnb"></cite><cite id="9vvnb"><span id="9vvnb"></span></cite>
<cite id="9vvnb"><span id="9vvnb"><menuitem id="9vvnb"></menuitem></span></cite>

nrf52832藍牙開發踩過的坑

接觸nrf52832芯片已經有一段時間了,記錄我踩過的坑。這些坑大多都補回來了,愿后來的開發者沒有坑~

先來點開胃小菜

一、環境問題

  • 安裝離線包遇到的錯誤——svdconv exited with an error

原因可能是軟件包含中文路徑或者keil版本過低,修改安裝路徑或者升級一下keil。

  • Jlink下載提示No Cortex-M SW Device Found錯誤

最簡單的就是在keil的調試設置里面選擇Jlink,然后scan一下

不行就重插jlink再試一下。如果還是不行,不著急,還可以試試一下這個方法

打開jlink的RTT Viewer(或者在keil里面debug的Jlink選擇cmd進入),然后選著默認使用的藍牙芯片按下回車,之后去keil下載就沒有這些錯誤。

  • Keil5調試警告——This target device does not support all the defined breakpos!Please reduce the number of breakpoints and start again.

原因設備斷點太多,超過5個就會產生這個警告。清除所有斷點,再選擇自己想要設置斷點的位置。

  • keil5閃退問題

可能的兩個原因,Jlink的接觸不良,拔了再接起來可能就沒有了,最好的解決辦法是買正版的Jlink,還可以把工程移動到其他文件夾也可能可以解決。

還有就是版本兼容性問題,可以試著把Keil注冊表中的Recent Projects的全部內容清楚。

如果還不行,便把keil5程序改成兼容性win7。

再不行,打擾了

這些用到keil5的都有可能會遇到,不要慌都可以解決 來點主菜吧,大家也等久了~

二、程序問題

  • 【編譯錯誤】 ".\_build\nrf52832_xxaa.axf: Error: L6218E: Undefined symbol app_uart_init (referred from main.o)."

版本驅動不兼容,添加就得版本驅動即可解決。舊版驅動:\modules\nrfx\drivers,新版驅動:\integration\nrfx\legacy.

  • 【編譯錯誤】 "._build\rtc_tick.axf: Error: L6200E: Symbol SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler multiply defined (by nrf_drv_spi.o and nrf_drv_twi.o)."

TWI0和SPI0使用使用相同地址,把其中一個換到1(SPI1/TWI1)或者使用模擬IIC。

  • 【編譯錯誤】 ”,. build\nrf5232 xxaa,.axf: Eror:16915E:Library zeports error: _use no sewihosting was requested, bnt asemihosting frutc was linked inNot enough information to list load addresses in the image map.“

我的解決辦法是把printf改成NRF_LOG_INFO打印輸出。網上的解決辦法是Keil的設置里面勾選use MicroLIB。

  • RTT打印浮點數,NRF_LOG_INFO無法打印浮點數

1) 添加串口打??;

2) 添加浮點數打印函數——NRF_LOG_FLOAT.

/**
 * @brief Macro to be used in a formatted string to a pass float number to the log.
 *
 * Use this macro in a formatted string instead of the %f specifier together with
 * @ref NRF_LOG_FLOAT macro.
 * Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f)))
 */
#define NRF_LOG_FLOAT_MARKER "%s%d.%02d"

/**
 * @brief Macro for dissecting a float number into two numbers (integer and residuum).
 */
#define NRF_LOG_FLOAT(val) (uint32_t)(((val) < 0 && (val) > -1.0) ? "-" : ""),   \
                           (int32_t)(val),                                       \
                           (int32_t)((((val) > 0) ? (val) - (int32_t)(val)       \
                                                : (int32_t)(val) - (val))*100)

 

  • IIC讀寫卡住問題

卡在iic讀寫的時候,很大可能是它的設備地址沒有寫對,有些庫會偏移器件地址,有些不會。試一下把iic器件的地址偏移。

  • 自定義藍牙名字過長,廣播顯示不全

原因:nrf52832默認使用藍牙4.x的廣播,它的廣播包數據只有32byte數據,當廣播已經包含足夠多的數據的時候,廣播每次過長就會顯示部分名稱,即便你選擇"BLE_ADVDATA_FULL_NAME"也一樣。解決辦法是使用藍牙5.0,它的容量就會增加到254byte,具體添加代碼如下:

/**
 * @brief Function for initializing the Advertising functionality.
 */
void advertising_init(void)
{
    uint32_t               		err_code;
    ble_advertising_init_t 		adv_data;
    ble_advdata_service_data_t 	        service_data;									//定義藍牙服務數據到廣播包中
    int8_t tx_power_level 		= TX_POWER_LEVEL;							//設置發射功率

    memset(&adv_data, 0, sizeof(adv_data));

    adv_data.advdata.name_type          	 = BLE_ADVDATA_FULL_NAME;
    adv_data.advdata.include_appearance 	 = true;
    adv_data.advdata.flags              	 = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    adv_data.advdata.p_tx_power_level 		 = &tx_power_level;

    adv_data.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    adv_data.advdata.uuids_complete.p_uuids  = m_adv_uuids;

    uint8_t my_adv_manuf_data[6] = {0};
    memcpy(my_adv_manuf_data, passwords, 6);
    ble_advdata_manuf_data_t manuf_specific_data;							 	//定義制造商數據結構體變量
    manuf_specific_data.company_identifier 	 = 0x0059;							//0x0059是Nordic的制造商ID
    manuf_specific_data.data.p_data 		 = my_adv_manuf_data;			 	 		//指向自定義數據
    manuf_specific_data.data.size   		 = sizeof(my_adv_manuf_data);	 	 			//自定義數據的大小
    adv_data.advdata.p_manuf_specific_data 	 = &manuf_specific_data;			 		//定義自定義數據到廣播包中	

    adv_data.config.ble_adv_fast_enabled  	 = true;
    adv_data.config.ble_adv_fast_interval 	 = APP_ADV_INTERVAL;
    adv_data.config.ble_adv_fast_timeout  	 = APP_ADV_DURATION;
    adv_data.evt_handler = on_adv_evt;

    //**********************添加藍牙5.0**************************//
    adv_data.config.ble_adv_primary_phy      = BLE_GAP_PHY_1MBPS;
    adv_data.config.ble_adv_secondary_phy    = BLE_GAP_PHY_2MBPS;
    adv_data.config.ble_adv_extended_enabled = true;
    //***********************************************************//

    err_code = ble_advertising_init(&m_advertising, &adv_data);
    APP_ERROR_CHECK(err_code);

    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
}

 注意:只能添加advdata的數據,srdata的數據在開啟5.0之后添加會出錯。

  • 按鍵長短按設置的時候每次都進入短按事件

注釋掉bsp_init()里面的循環

//      uint32_t num;

//      for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++)
//      {
//            err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT);
//      }

 

  •  【程序錯誤】 <error> nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.

錯誤截圖:

將0x20002AE8和0xD518放入Keil5的RAM設置

產生NRF_ERROR_NO_MEM的原因,除了RAM沒有配置對,還與NRF_SDH_BLE_VS_UUID_COUNTNRF_SDH_BLE_GATTS_ATTR_TAB_SIZE,試著SIZE的值,然后改RAM可能就可以解決。

  • 【自定義服務】—— 初始化值不顯示、顯示不全問題

看看有沒有設置變量把值存進去,再進行復制;設置長度可變,如下

add_char_params.is_var_len          = true;			//長度可變

 

  • 【自定義服務】添加128bitUUID到特性

在添加特性前面,添加一個sd_ble_uuid_vs_add()函數,把自定義特性的128UUID放進去,然后再添加特性。

示例代碼:

/**
 @brief  Register the application callback function. Call this function only once 
 @param  pLwsProfile  -[out] LWS Initialize the service structure
 @param  pAppCallback -[in] Callback to the application 
 @return NRF_SUCCESS - Success; other values-failure
*/
uint32_t ble_lws_init(LwsProfile_t *pLwsProfile, const LwsProfileCallback_t *pAppCallback)
{
    uint32_t errCode;
    ble_uuid_t bleUuid;
    ble_add_char_params_t addCharParams;

    // Initialize the service structure
    pLwsProfile->lWsProfileCharWriteHandler = pAppCallback->lWsProfileCharWriteHandler;

    /*--------------------- service ---------------------*/
    ble_uuid128_t baseUuid = {LWSPROFILE_UUID_BASE};
    // Add base UUID
    errCode = sd_ble_uuid_vs_add(&baseUuid, &pLwsProfile->uuidType);
    VERIFY_SUCCESS(errCode);

    //Add main service UUID
    bleUuid.type = pLwsProfile->uuidType;
    bleUuid.uuid = LWSPROFILE_UUID_SERVICE;

    errCode = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, 
					&bleUuid, 
					&pLwsProfile->serviceHandle);
    VERIFY_SUCCESS(errCode);

    /*--------------------- characteristic 1--Update request---------------------*/
    ble_uuid128_t         nus_base_uuid_char1 = LWSPROFILE_UUID_NEW_CHAR1;
    errCode = sd_ble_uuid_vs_add(&nus_base_uuid_char1, &pLwsProfile->uuidType); // add uuid base to SD, get uuid type back to app
    VERIFY_SUCCESS(errCode);
	
    memset(&addCharParams, 0, sizeof(addCharParams));
    addCharParams.uuid              	= LWSPROFILE_UUID_CHAR1;
    addCharParams.uuid_type         	= pLwsProfile->uuidType;
    addCharParams.init_len          	= 0;
    addCharParams.max_len           	= LWSPROFILE_CHAR1_LEN;								// Characteristic length
    addCharParams.is_var_len            = true;										//可變數據長度
    addCharParams.char_props.indicate   = 1;										// Declarable					

    addCharParams.cccd_write_access     = SEC_MITM;

    errCode = characteristic_add(pLwsProfile->serviceHandle, &addCharParams, &pLwsProfile->char1Handle);
    return errCode;
}

 

  • 在DFU后,FDS內容丟失

FDS供用戶使用的有一個范圍的ID,FILE ID(0x0000 - 0xBFFF),RECORD KEY(0x0001 - 0xBFFF),在這個范圍內使用一般沒什么問題,而我直接使用0xfff1的ID,就有這個問題。FILE ID 從0xC000 到 0xFFFF 的值保留供Peer Manager模塊使用,并且只能在不包含 Peer Manager 的應用程序中使用;RECORD KEY 從0xFFFF 是被系統使用的,從 0xC000 到 0xFFFE 的值保留供Peer Manager模塊使用,并且只能在不包含 Peer Manager 的應用程序中使用。

  •  sd_ble_gatts_value_set()產生的錯誤NRF_ERROR_DATA_SIZE

原因:使用數據長度超過特征最大長度

解決辦法:將所使用到的特征的最大長度加長

  • nrf_crypto_init初始化失敗

RTT打印信息:

 sm_init()初始化產生的錯誤,可能是RNG重復初始化,可以在sm_init()里面加一個重復判斷,或者把原先的RNG初始化關閉。

三、硬件問題

  • DFU升級程序一直卡在bootloader

本來以為是配置問題,然后看了一天的配置,發現一點問題都沒有  再去看升級命令、步驟,也沒有發現什么問題。也試過改settings的版本號,也不行。最后在官方文檔發現,程序在啟動時先進入協議棧,再由協議棧進入bootloader,然后bootloader去檢測是否進入app。如果bootloader的按鍵進入DFU引腳一直被拉高,就會導致程序一直無法啟動。解決辦法,把bootloader的按鍵檢測引腳更換到其他引腳位置。

原本是25號引腳,被我改到了27號,程序可以正常進入,DFU也是正常的。

四、解決思路

        以前遇到nrf52832問題的時候,直接就百度,如果關鍵詞不對會花費很多時間?,F在的話,先去開啟DEBUG打印,看看錯誤的位置,再去看函數定義的錯誤返回值是什么原因引起的,要么直接改,要么根據這個函數和返回錯誤百度或者去官方社區搜索。都找不到就去看NORDIC在線文檔的指導步驟。之后想到的再更新,nrf52832該有的坑我都踩了

五、參考鏈接

nrf52832 SPI和IIC外設不可同時使用

nrf52832底層驅動兼容性問題

關于stm32報錯Library reports error: __use_no_semihosting was requested的三種解決方案

NRF52832學習筆記(13)——RTT打印調試日志

Flash Data Storage (FDS)存儲

 

posted @ 2021-11-20 18:01  wfagly  閱讀(97)  評論(0編輯  收藏  舉報
黄色网站在现免费看_黄色网站在线18P_黄色网站在线播放