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;
}