使用Simplicity Studio5建立一个BLE工程

1.下载和按照Simplicity Studio5就不说了,这边还是以如何生成代码和手动增加功能为主。

这边主要功能是通过串口发送指令,扫描BLE设备,和连接BLE设备

1.1在Project Explorer框框内右击New->Project...

1.2在弹出的框框选择,MCU Project后点击Next

 1.3Boards为开发板的小坂,如若有卖开发板可选择该项,如若没有使用Part根据自己的芯片型号选择后,选择SDK版本,我这边使用的是Bluetooth 3.2.4的版本(备注:之前2.0以下的版本Simplicity Studio5不支持,全新的从3.0起步)点击Next

 1.4会让你选择,要一个空项目还是有例程的项目,我们这边选择带例程的,点击Next

1.5这个有很多类型选择,我这边选择的是Bluetooth - Soc Empty,这个看项目选择,后点击Next

 

 1.6项目名称命名,选择代码存放位置(最好不要有中文路径)点击Next或者Finish

 1.7这边选择的是编译环境的版本,我这边下载的是10.3.1版本,其他版本也是可以,点击Finish,等待代码生成

 1.8左边的Project Explorer为生成后的代码目录

1.9 .slcp后缀的是项目的信息,可以去设置一些信息        

 2.0点击Pin Tool设置信息,我这边设置PF6为TX,PF7为RX,还有几个LED

 2.1可在.slcp后缀的文件选择串口,这边需要先安装,我这边是安装完成的,安装完成后会显示Configure,点击进去配置

2.2这边可配置波特率其他的.....

 

 

2.3 好了,让我们来进入代码mian.c,这边无需任何操作,当然你也可以设置你想要的内容

#include "sl_component_catalog.h"
#include "sl_system_init.h"
#include "app.h"
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#include "sl_power_manager.h"
#endif // SL_CATALOG_POWER_MANAGER_PRESENT
#if defined(SL_CATALOG_KERNEL_PRESENT)
#include "sl_system_kernel.h"
#else // SL_CATALOG_KERNEL_PRESENT
#include "sl_system_process_action.h"
#endif // SL_CATALOG_KERNEL_PRESENT

int main(void)
{
  // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
  // Note that if the kernel is present, processing task(s) will be created by
  // this call.
  sl_system_init();

  // Initialize the application. For example, create periodic timer(s) or
  // task(s) if the kernel is present.
  app_init();

#if defined(SL_CATALOG_KERNEL_PRESENT)
  // Start the kernel. Task(s) created in app_init() will start running.
  sl_system_kernel_start();
#else // SL_CATALOG_KERNEL_PRESENT
  while (1) {
    // Do not remove this call: Silicon Labs components process action routine
    // must be called from the super loop.
    sl_system_process_action();

    // Application process.
    app_process_action();

#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
    // Let the CPU go to sleep if the system allows it.
    sl_power_manager_sleep();
#endif
  }
#endif // SL_CATALOG_KERNEL_PRESENT
}

 2.4这部分是给用户初始化内容的

SL_WEAK void app_init(void)
{
  /
  // Put your additional application init code here!                         //
  // This is called once during start-up.                                    //
  /

}

 2.5这部分是用户自定义程序死循环的while循环的

SL_WEAK void app_process_action(void)
{
  /
  // Put your additional application code here!                              //
  // This is called infinitely.                                              //
  // Do not call blocking functions from here!                               //
  /

}

2.6这部分是蓝牙协议栈处理事件

void sl_bt_on_event(sl_bt_msg_t *evt)
{
  sl_status_t sc;
  bd_addr address;
  uint8_t address_type;
  uint8_t system_id[8];

  switch (SL_BT_MSG_ID(evt->header)) {
    // -------------------------------
    // This event indicates the device has started and the radio is ready.
    // Do not call any stack command before receiving this boot event!
    case sl_bt_evt_system_boot_id:

      // Extract unique ID from BT Address.
      sc = sl_bt_system_get_identity_address(&address, &address_type);
      app_assert_status(sc);
      printf("get MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",address.addr[5],address.addr[4],
                          address.addr[3],address.addr[2],address.addr[1],address.addr[0]);

      // Pad and reverse unique ID to get System ID.
      system_id[0] = address.addr[5];
      system_id[1] = address.addr[4];
      system_id[2] = address.addr[3];
      system_id[3] = 0xFF;
      system_id[4] = 0xFE;
      system_id[5] = address.addr[2];
      system_id[6] = address.addr[1];
      system_id[7] = address.addr[0];

      sc = sl_bt_gatt_server_write_attribute_value(gattdb_system_id,
                                                   0,
                                                   sizeof(system_id),
                                                   system_id);
      app_assert_status(sc);

      // Create an advertising set.
      sc = sl_bt_advertiser_create_set(&advertising_set_handle);
      app_assert_status(sc);

    
      // Set advertising interval to 100ms.
      sc = sl_bt_advertiser_set_timing(
        advertising_set_handle,
        160, // min. adv. interval (milliseconds * 1.6)
        160, // max. adv. interval (milliseconds * 1.6)
        0,   // adv. duration
        0);  // max. num. adv. events
      app_assert_status(sc);
      // Start general advertising and enable connections.
      sc = sl_bt_advertiser_start(
        advertising_set_handle,
        sl_bt_advertiser_general_discoverable,
        sl_bt_advertiser_connectable_scannable);
      app_assert_status(sc);
      break;

    // -------------------------------
    // This event indicates that a new connection was opened.
    case sl_bt_evt_connection_opened_id:
          _ble_Connect_handle(&evt->data.evt_connection_opened);
      break;

    // -------------------------------
    // This event indicates that a connection was closed.
    case sl_bt_evt_connection_closed_id:
      // Restart advertising after client has disconnected.
      sc = sl_bt_advertiser_start(
        advertising_set_handle,
        sl_bt_advertiser_general_discoverable,
        sl_bt_advertiser_connectable_scannable);
      app_assert_status(sc);

      _ble_Connect_CloseHandle(&evt->data.evt_connection_closed);

      break;

    ///
    // Add additional event handlers here as your application requires!      //
    ///


    // -------------------------------
    // Default event handler.
    default:
      break;
  }

 2.7创建一个.c文件,用来编写我们的功能

//定时器初始话信息
static uint32_t soft_timer_LED = 32768; // 1S
static uint8_t soft_time_LED_handle = 0xff;

static uint32_t soft_time_UART_RX = 1640;//约等于50ms
static uint8_t soft_time_UART_handle = 0x03;

#define UARTRXBUFLEN 256
#define _FALSE 0
#define _TRUE  1

typedef struct
{
    uint8_t  *Rxbuf;
    uint32_t RxbufLen;
    uint32_t RXBUF_w;
    uint32_t RXBUF_r;
    uint8_t rx_flag;

}_usart_buffer;

static uint8_t  RXBUF[UARTRXBUFLEN];
_usart_buffer _uast_1;


//初始化LED灯状态
void _LEDInit(void)
{
    GPIO_PinModeSet(gpioPortF, 2, gpioModePushPull, 0);
    GPIO_PinModeSet(gpioPortF, 3, gpioModePushPull, 1);
    GPIO_PinModeSet(gpioPortF, 4, gpioModePushPull, 0);
    GPIO_PinModeSet(gpioPortF, 5, gpioModePushPull, 1);
    
    sl_bt_system_set_soft_timer(soft_timer_LED, soft_time_LED_handle, 0);//初始化定时器
}
//定时器时间到后LED灯翻转
void _LEDFlicker(sl_bt_evt_system_soft_timer_t *time)
{

    if (time->handle == soft_time_LED_handle)
    {
        GPIO_PinOutToggle(gpioPortF, 2);
        GPIO_PinOutToggle(gpioPortF, 3);
        GPIO_PinOutToggle(gpioPortF, 4);
        GPIO_PinOutToggle(gpioPortF, 5);
    }
}
//串口缓冲初始化
void _usart_buffer_init(void)
{
    _uast_1.Rxbuf = RXBUF;
    _uast_1.RxbufLen = UARTRXBUFLEN;
    _uast_1.RXBUF_w = 0;
    _uast_1.RXBUF_r = 0;
    _uast_1.rx_flag = _FALSE;
}


//串口接收
void _UART_RX_receive(void)
{
    uint32_t bytes_read = 0;
    uint8_t cmdbuf[UARTRXBUFLEN];

    sl_status_t checkisOK = sl_iostream_read(SL_IOSTREAM_STDOUT, cmdbuf, UARTRXBUFLEN, &bytes_read);//为流接收
    if (checkisOK == SL_STATUS_OK)
    {
        for (uint32_t i = 0; i < bytes_read; i++)
        {
            _uast_1.Rxbuf[_uast_1.RXBUF_w] = cmdbuf[i];
            if (++_uast_1.RXBUF_w >= _uast_1.RxbufLen)
            {
                _uast_1.RXBUF_w = 0;
            }
        }
        if (_uast_1.rx_flag != _TRUE)
        {
            _uast_1.rx_flag = _TRUE;
            sl_bt_system_set_soft_timer(soft_time_UART_RX, soft_time_UART_handle, 1);
        }
        
    }
}
//串口接收处理函数
void _Test_handle(sl_bt_evt_system_soft_timer_t *time)
{
    static uint8_t buf[UARTRXBUFLEN];
    static uint32_t buflen = 0;
    uint8_t *Checktail="\r\n";
    uint8_t  *isOK=NULL;

    if (time->handle==soft_time_UART_handle)
    {

        if (_uast_1.rx_flag == LDS_TRUE)
        {
            _uast_1.rx_flag = LDS_FALSE;
            _UART_RX_get(&_uast_1, buf, &buflen);

            isOK = (uint8_t*)strstr(buf,Checktail);
            if (isOK==NULL || (uint8_t*)strstr(buf,"AT")==NULL)
            {
                return;
            }
            isOK=NULL;
            
            if (_cli_SearchParse(buf, buflen) == _TRUE)
            {
            }
            else
            {
                printf("Error\n");
            }
        }
        memset(buf, 0, UARTRXBUFLEN);
        buflen = 0;
    }
    
}

2.8在app.c上添加我们的代码

SL_WEAK void app_init(void)
{
  /
  // Put your additional application init code here!                         //
  // This is called once during start-up.                                    //
  /
  _LEDInit();
  _usart_buffer_init();
}
SL_WEAK void app_process_action(void)
{
  /
  // Put your additional application code here!                              //
  // This is called infinitely.                                              //
  // Do not call blocking functions from here!                               //
  /
  _UART_RX_receive();
}
void sl_bt_on_event(sl_bt_msg_t *evt)
{
  sl_status_t sc;
  bd_addr address;
  uint8_t address_type;
  uint8_t system_id[8];

  switch (SL_BT_MSG_ID(evt->header)) {
    // -------------------------------
    // This event indicates the device has started and the radio is ready.
    // Do not call any stack command before receiving this boot event!
    case sl_bt_evt_system_boot_id:

      // Extract unique ID from BT Address.
      sc = sl_bt_system_get_identity_address(&address, &address_type);
      app_assert_status(sc);
      printf("get MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",address.addr[5],address.addr[4],
                          address.addr[3],address.addr[2],address.addr[1],address.addr[0]);

      // Pad and reverse unique ID to get System ID.
      system_id[0] = address.addr[5];
      system_id[1] = address.addr[4];
      system_id[2] = address.addr[3];
      system_id[3] = 0xFF;
      system_id[4] = 0xFE;
      system_id[5] = address.addr[2];
      system_id[6] = address.addr[1];
      system_id[7] = address.addr[0];

      sc = sl_bt_gatt_server_write_attribute_value(gattdb_system_id,
                                                   0,
                                                   sizeof(system_id),
                                                   system_id);
      app_assert_status(sc);

      // Create an advertising set.
      sc = sl_bt_advertiser_create_set(&advertising_set_handle);
      app_assert_status(sc);

    

      // Set advertising interval to 100ms.
      sc = sl_bt_advertiser_set_timing(
        advertising_set_handle,
        160, // min. adv. interval (milliseconds * 1.6)
        160, // max. adv. interval (milliseconds * 1.6)
        0,   // adv. duration
        0);  // max. num. adv. events
      app_assert_status(sc);
      // Start general advertising and enable connections.
      sc = sl_bt_advertiser_start(
        advertising_set_handle,
        sl_bt_advertiser_general_discoverable,
        sl_bt_advertiser_connectable_scannable);
      app_assert_status(sc);
      break;

    // -------------------------------
    // This event indicates that a new connection was opened.
    case sl_bt_evt_connection_opened_id:
          _ble_Connect_handle(&evt->data.evt_connection_opened);
      break;

    // -------------------------------
    // This event indicates that a connection was closed.
    case sl_bt_evt_connection_closed_id:
      // Restart advertising after client has disconnected.
      sc = sl_bt_advertiser_start(
        advertising_set_handle,
        sl_bt_advertiser_general_discoverable,
        sl_bt_advertiser_connectable_scannable);
      app_assert_status(sc);

      _ble_Connect_CloseHandle(&evt->data.evt_connection_closed);

      break;

    ///
    // Add additional event handlers here as your application requires!      //
    ///
    //以下为自己添加的代码:
    case sl_bt_evt_system_soft_timer_id:
        _LEDFlicker(&evt->data.evt_system_soft_timer);
        _Test_handle(&evt->data.evt_system_soft_timer);
    break;

    case sl_bt_evt_scanner_scan_report_id:
        _ble_Scan_handle(&evt->data.evt_scanner_scan_report);
    break;

    // -------------------------------
    // Default event handler.
    default:
      break;
  }

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值