xuboluan 发表于 2019-6-6 16:54:47

NRF52832手机修改蓝牙名称,掉电不丢失

本帖最后由 xuboluan 于 2019-6-6 16:54 编辑

芯片: NRF52832 QF AA
SDK: SDK15.2
Softdevice: s132_nrf52_6.1.1_softdevice
参考资料
1、https://blog.csdn.net/weixin_41572450/article/details/83870623
2、nRF5_SDK_15.2.0_9412b96\examples\peripheral\flash_fstorage\pca10040\s132\arm5_no_packs
3、nrf5/lib_fstorage.html
写在前面:
存放位置:根据官方文档得知FDS区域范围在appication之后。

程序思路:
1、使用官方fstorage 库
2、 开机判断是否存在蓝牙名称然后再判断使用哪个蓝牙名称
3、每次通过蓝牙写完芯片名称后重启芯片

操作步骤:

第一步:项目中添加
nrf_fstorage.c
nrf_fstorage_sd.c
第二步:添加include 路径
第三步:头文件里包含#include "nrf_fstorage.h"#include "nrf_fstorage_sd.h"
第四步:添加代码

//定义操作范围
NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
{
    /* Set a handler for fstorage events. */
    .evt_handler = fstorage_evt_handler,

    /* These below are the boundaries of the flash space assigned to this instance of fstorage.
   * You must set these manually, even at runtime, before nrf_fstorage_init() is called.
   * The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the
   * last page of flash available to write data. */
   .start_addr = youraddressstart,
    .end_addr   = 0x78000,
};

//定义回调函数
static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);

static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
{
    if (p_evt->result != NRF_SUCCESS)
    {
      NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation.");
      return;
    }

    switch (p_evt->id)
    {
      case NRF_FSTORAGE_EVT_WRITE_RESULT:
      {
            NRF_LOG_INFO("--> Event received: wrote %d bytes at address 0x%x.",
                         p_evt->len, p_evt->addr);
      } break;

      case NRF_FSTORAGE_EVT_ERASE_RESULT:
      {
            NRF_LOG_INFO("--> Event received: erased %d page from address 0x%x.",
                         p_evt->len, p_evt->addr);
      } break;

      default:
            break;
    }
}

//定义操作指针
nrf_fstorage_api_t * p_fs_api;

//等待操作完成,由于我在写内容的时候不需要调度其他功能所以直接dump
void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage)
{
    /* While fstorage is busy, sleep and wait for an event. */
    while (nrf_fstorage_is_busy(p_fstorage))
    {
         
    }
}

uint32_t nameadderss=youraddress;
//flash写名字
void writename(char * data)
{
ret_code_t rc;

p_fs_api = &nrf_fstorage_sd;
rc = nrf_fstorage_init(&fstorage, p_fs_api, NULL);
APP_ERROR_CHECK(rc);
// nameadderss = nrf5_flash_end_addr_get();
    //长度必须是4的倍数
rc = nrf_fstorage_write(&fstorage, nameadderss,data, 12, NULL);
APP_ERROR_CHECK(rc);
wait_for_flash_ready(&fstorage);
NRF_LOG_INFO("Done.");
}

//定义名字变量
char DEVICE_NAME = {yourname};
//定义默认名称
char* name="yourname";
//此函数开机调用 用于判断flash里面是否有内容用于确定使用默认名称还是flash名称
void read_name(void)
{
ret_code_t rc;
   
p_fs_api = &nrf_fstorage_sd;
rc = nrf_fstorage_init(&fstorage, p_fs_api, NULL);
APP_ERROR_CHECK(rc);
rc = nrf_fstorage_read(&fstorage, nameadderss, DEVICE_NAME, yournamelength);
if (rc != NRF_SUCCESS)
    {
      
      return;
    }
    wait_for_flash_ready(&fstorage);
//判断名称是否合法
if(yourrule)
{
    memcpy(DEVICE_NAME,name,yournamelength);
}
}

在main.c中找到static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)函数
并添加以下代码:
case BLE_GATTS_EVT_WRITE:
      if(p_ble_evt->evt.gatts_evt.params.write.uuid.uuid == BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME)
      {
            char tempname;
            if((p_ble_evt->evt.gatts_evt.params.write.len ==yournamelength) )
            {
                memcpy(tempname, p_ble_evt->evt.gatts_evt.params.write.data, p_ble_evt->evt.gatts_evt.params.write.len);
                if((yourrule))
                {
                  //断开连接
                  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);
                  memcpy(DEVICE_NAME, tempname, yournamelength);
                  //写flash
                  writename(DEVICE_NAME);
                  //重启
                  NRF_LOG_WARNING("System reset");
                  NVIC_SystemReset();
                }
            }
      }

注意:
开机在gap_params_init()初始化前调用void read_name(void)函数。

手机端操作:


写入蓝牙名称



rf_smart 发表于 2019-6-6 17:12:11

打开LOG看看,有不有写完成事件的打印啊。

chenliangliang_ 发表于 2019-6-6 19:27:22

你这个方法,不会和以后的pm_manager冲突吗
页: [1]
查看完整版本: NRF52832手机修改蓝牙名称,掉电不丢失