将低功耗蓝牙应用到您的设计中,从可穿戴设备到智能家居产品轻松实现无线连接
A
A
硬件概览
它是如何工作的?
BT-EZ 2 Click 基于英飞凌(Infineon)的 CYW20822-P4TAI040 模块,这是一款完全集成的低功耗蓝牙(BLE)无线模块,将 CYW20822 芯片与板载晶振、无源元件、嵌入式闪存以及集成迹线天线结合在一起。该模块预装 EZ-Serial 固件,提供用户友好的命令接口,便于配置与使用,并已通过 Bluetooth SIG 认证,作为一款成本优化的 BLE 5.0 解决方案,适用于广泛的嵌入式应用。模块集成 1MB 嵌入式闪存,支持非易失性存储,实现独立运行和空中固件升级(OTA),保证灵活性和长期适应性。其内置 16MHz Arm Cortex-M0 微控制器可提供高效性能,无线电部分支持多种 BLE 数据速率,包括 2Mbps、1Mbps、500kbps 和 125kbps,为不同应用场景提供可扩展性。模块的最大发射功率为 +4dBm,在理想视距条件下通信距离可达 250 米,而接收端在 125kbps 时的灵敏度为 –101dBm,即便在复杂环境
中也能确保稳健通信。这些特性使 BT-EZ 2 Click 成为可穿戴设备、智能家居系统、物联网节点、健康监测和工业应用等需要可靠蓝牙连接、低功耗和简便集成的理想选择。该 Click 板™ 通过 UART 接口与主控 MCU 通信,使用标准的 UART RX 和 TX 引脚,并支持 CTS 和 RTS 硬件流控。默认通信速率为 115200bps,保证高效的数据交换。板上还提供 UART SEL 跳线,可选择 UART TX 信号的用途,使其既可作为标准 UART TX 信号用于数据交换,也可作为 UART TX 调试信号,用户可通过将跳线置于 DAT 或 DBG 位置来切换模式。除了接口引脚外,板上还包含 RST 引脚,用于在必要时对模块进行硬件复位;CYS 引脚用于命令/数据模式选择(高电平为命令模式,低电平为数据模式);SWD 焊盘则为使用 MIKROE 的 6 针针式连接线提供可选的 SWD(串行线调试)接口,用于模块的调试和固件编程。为了增
强灵活性和适应不同应用场景,板上设计了三个未焊接的 2 针扩展接口。NTC 接口用于连接外部负温度系数热敏电阻,可根据应用需求实现与温度相关的控制或监测;MODE 接口用于低功耗模式控制,可将模块配置为节能模式;BOOT 接口则提供对启动控制的访问,允许用户在开发或现场更新时管理固件加载或恢复过程。板上还配有用户友好的操作与状态指示功能,包括一个按键开关(BUTTON),可用于触发用户自定义操作或模块命令,以及两颗 LED 指示灯:红色 LED(LED1)和黄色 LED(LED2),可用作状态反馈、通信活动指示或通用调试显示。此 Click 板™ 仅支持 3.3V 逻辑电平运行。在与不同逻辑电平的 MCU 搭配使用前,必须进行适当的电平转换。该板还配备了函数库和示例代码,可作为后续开发与集成的参考。
功能概述
开发板
Clicker 4 for STM32F3 是一款紧凑型开发板,作为完整的解决方案而设计,可帮助用户快速构建具备独特功能的定制设备。该板搭载 STMicroelectronics 的 STM32F302VCT6 微控制器,配备四个 mikroBUS™ 插槽用于连接 Click boards™、完善的电源管理功能以及其他实用资源,是快速开发各类应用的理想平台。其核心 MCU STM32F302VCT6 基于高性能
Arm® Cortex®-M4 32 位处理器,运行频率高达 168MHz,处理能力强大,能够满足各种高复杂度任务的需求,使 Clicker 4 能灵活适应多种应用场景。除了两个 1x20 引脚排针外,板载最显著的连接特性是四个增强型 mikroBUS™ 插槽,支持接入数量庞大的 Click boards™ 生态系统,该生态每日持续扩展。Clicker 4 各功能区域标识清晰,界面直观简洁,极大
提升使用便捷性和开发效率。Clicker 4 的价值不仅在于加速原型开发与应用构建阶段,更在于其作为独立完整方案可直接集成至实际项目中,无需额外硬件修改。四角各设有直径 4.2mm(0.165")的安装孔,便于通过螺丝轻松固定。对于多数应用,只需配套一个外壳,即可将 Clicker 4 开发板转化为完整、实用且外观精美的定制系统。
微控制器概述
MCU卡片 / MCU

建筑
ARM Cortex-M4
MCU 内存 (KB)
256
硅供应商
STMicroelectronics
引脚数
100
RAM (字节)
40960
使用的MCU引脚
mikroBUS™映射器
“仔细看看!”
Click board™ 原理图

一步一步来
项目组装
实时跟踪您的结果
应用程序输出
1. 应用程序输出 - 在调试模式下,“应用程序输出”窗口支持实时数据监控,直接提供执行结果的可视化。请按照提供的教程正确配置环境,以确保数据正确显示。

2. UART 终端 - 使用UART Terminal通过USB to UART converter监视数据传输,实现Click board™与开发系统之间的直接通信。请根据项目需求配置波特率和其他串行设置,以确保正常运行。有关分步设置说明,请参考提供的教程。

3. Plot 输出 - Plot功能提供了一种强大的方式来可视化实时传感器数据,使趋势分析、调试和多个数据点的对比变得更加直观。要正确设置,请按照提供的教程,其中包含使用Plot功能显示Click board™读数的分步示例。在代码中使用Plot功能时,请使用以下函数:plot(insert_graph_name, variable_name);。这是一个通用格式,用户需要将“insert_graph_name”替换为实际图表名称,并将“variable_name”替换为要显示的参数。

软件支持
库描述
BT-EZ 2 Click 演示应用程序使用 NECTO Studio开发,确保与 mikroSDK 的开源库和工具兼容。该演示设计为即插即用,可与所有具有 mikroBUS™ 插座的 开发板、入门板和 mikromedia 板完全兼容,用于快速实现和测试。
示例描述
本示例演示了如何使用 BT-EZ 2 Click 板,通过处理来自已连接 BLE 设备的数据来实现蓝牙通信。
关键功能:
btez2_cfg_setup
- 初始化 Click 配置结构体为初始值。btez2_init
- 初始化此 Click 板所需的所有引脚和外设。btez2_cmd_action
- 向 Click 模块发送指定的动作命令。btez2_cmd_set
- 向 Click 模块发送指定的设置命令。btez2_read_packet
- 从 Click 模块读取响应或事件数据包,并存储到 ctx->evt_pkt 结构中。
应用初始化
初始化驱动程序和日志记录器。
应用任务
应用任务分为以下几个阶段:
BTEZ2_POWER_UP:
- 上电并检查通信状态。BTEZ2_CONFIG_EXAMPLE:
- 恢复出厂设置,并读取蓝牙地址和名称。BTEZ2_EXAMPLE:
- 执行蓝牙终端示例,处理来自已连接 BLE 设备的所有数据,并返回相应的响应消息。
开源
代码示例
完整的应用程序代码和一个现成的项目可以通过NECTO Studio包管理器直接安装到NECTO Studio。 应用程序代码也可以在MIKROE的GitHub账户中找到。
/*!
* @file main.c
* @brief BT-EZ 2 Click Example.
*
* # Description
* This example demonstrates the use of BT-EZ 2 Click board by processing data
* from a connected BLE device.
*
* The demo application is composed of two sections :
*
* ## Application Init
* Initializes the driver and logger.
*
* ## Application Task
* Application task is split in few stages:
* - BTEZ2_POWER_UP:
* Powers up the device and checks the communication.
* - BTEZ2_CONFIG_EXAMPLE:
* Restores factory settings and reads the BT address and name.
* - BTEZ2_EXAMPLE:
* Performs a BT terminal example by processing all data from a connected BLE device
* and sending back an adequate response messages.
*
* ## Additional Function
* - static void btez2_clear_app_buf ( void )
* - static void btez2_log_app_buf ( void )
* - static err_t btez2_process ( btez2_t *ctx )
* - static err_t btez2_wait_packet ( btez2_t *ctx, uint8_t timeout_s, uint8_t rsp_flag, uint8_t *cmd_code )
* - static err_t btez2_power_up ( btez2_t *ctx )
* - static err_t btez2_config_example ( btez2_t *ctx )
* - static err_t btez2_example ( btez2_t *ctx )
*
* @note
* We have used the Serial Bluetooth Terminal smartphone application for the test.
*
* @author Stefan Filipovic
*
*/
#include "board.h"
#include "log.h"
#include "btez2.h"
// Message content
#define MESSAGE_CONTENT "BT-EZ 2 Click board - demo example."
static btez2_t btez2;
static log_t logger;
// Application buffer size
#define APP_BUFFER_SIZE 500
#define PROCESS_BUFFER_SIZE 200
static uint8_t app_buf[ APP_BUFFER_SIZE ] = { 0 };
static int32_t app_buf_len = 0;
/**
* @brief Example states.
* @details Predefined enum values for application example state.
*/
typedef enum
{
BTEZ2_POWER_UP = 1,
BTEZ2_CONFIG_EXAMPLE,
BTEZ2_EXAMPLE
} btez2_app_state_t;
static btez2_app_state_t app_state = BTEZ2_POWER_UP;
/**
* @brief BT-EZ 2 clearing application buffer.
* @details This function clears memory of application buffer and reset its length.
* @note None.
*/
static void btez2_clear_app_buf ( void );
/**
* @brief BT-EZ 2 log application buffer.
* @details This function logs data from application buffer to USB UART.
* @note None.
*/
static void btez2_log_app_buf ( void );
/**
* @brief BT-EZ 2 data reading function.
* @details This function reads data from device and concatenates data to application buffer.
* @param[in] ctx : Click context object.
* See #btez2_t object definition for detailed explanation.
* @return @li @c 0 - Read some data.
* @li @c -1 - Nothing is read.
* See #err_t definition for detailed explanation.
* @note None.
*/
static err_t btez2_process ( btez2_t *ctx );
/**
* @brief BT-EZ 2 wait packet function.
* @details This function waits for a packet message, reads and displays it on the USB UART.
* @param[in] ctx : Click context object.
* See #btez2_t object definition for detailed explanation.
* @param[in] timeout_s : Timeout in seconds.
* @param[in] rsp_flag : 1 - response packet, 0 - event packet.
* @param[in] cmd_code : Expected command code string.
* @return @li @c 0 - OK response.
* @li @c -2 - Timeout error.
* @li @c -3 - Command error.
* See #err_t definition for detailed explanation.
* @note None.
*/
static err_t btez2_wait_packet ( btez2_t *ctx, uint8_t timeout_s, uint8_t rsp_flag, uint8_t *cmd_code );
/**
* @brief BT-EZ 2 power up function.
* @details This function powers up the device and checks communication.
* @param[in] ctx : Click context object.
* See #btez2_t object definition for detailed explanation.
* @return @li @c 0 - OK.
* @li @c != 0 - Read response error.
* See #err_t definition for detailed explanation.
* @note None.
*/
static err_t btez2_power_up ( btez2_t *ctx );
/**
* @brief BT-EZ 2 config example function.
* @details This function restores factory settings, and reads the BT address and name.
* @param[in] ctx : Click context object.
* See #btez2_t object definition for detailed explanation.
* @return @li @c 0 - OK.
* @li @c != 0 - Read response error.
* See #err_t definition for detailed explanation.
* @note None.
*/
static err_t btez2_config_example ( btez2_t *ctx );
/**
* @brief BT-EZ 2 example function.
* @details This function performs a BT terminal example by processing all data from
* a connected BLE device and sending back an adequate response messages.
* @param[in] ctx : Click context object.
* See #btez2_t object definition for detailed explanation.
* @return @li @c 0 - OK.
* @li @c != 0 - Read response error.
* See #err_t definition for detailed explanation.
* @note None.
*/
static err_t btez2_example ( btez2_t *ctx );
void application_init ( void )
{
log_cfg_t log_cfg; /**< Logger config object. */
btez2_cfg_t btez2_cfg; /**< Click config object. */
/**
* Logger initialization.
* Default baud rate: 115200
* Default log level: LOG_LEVEL_DEBUG
* @note If USB_UART_RX and USB_UART_TX
* are defined as HAL_PIN_NC, you will
* need to define them manually for log to work.
* See @b LOG_MAP_USB_UART macro definition for detailed explanation.
*/
LOG_MAP_USB_UART( log_cfg );
log_init( &logger, &log_cfg );
log_info( &logger, " Application Init " );
// Click initialization.
btez2_cfg_setup( &btez2_cfg );
BTEZ2_MAP_MIKROBUS( btez2_cfg, MIKROBUS_1 );
if ( UART_ERROR == btez2_init( &btez2, &btez2_cfg ) )
{
log_error( &logger, " Communication init." );
for ( ; ; );
}
log_info( &logger, " Application Task " );
app_state = BTEZ2_POWER_UP;
log_printf( &logger, ">>> APP STATE - POWER UP <<<\r\n\n" );
}
void application_task ( void )
{
switch ( app_state )
{
case BTEZ2_POWER_UP:
{
if ( BTEZ2_OK == btez2_power_up( &btez2 ) )
{
app_state = BTEZ2_CONFIG_EXAMPLE;
log_printf( &logger, ">>> APP STATE - CONFIG EXAMPLE <<<\r\n\n" );
}
break;
}
case BTEZ2_CONFIG_EXAMPLE:
{
if ( BTEZ2_OK == btez2_config_example( &btez2 ) )
{
app_state = BTEZ2_EXAMPLE;
log_printf( &logger, ">>> APP STATE - EXAMPLE <<<\r\n\n" );
}
break;
}
case BTEZ2_EXAMPLE:
{
btez2_example( &btez2 );
break;
}
default:
{
log_error( &logger, " APP STATE." );
break;
}
}
}
int main ( void )
{
/* Do not remove this line or clock might not be set correctly. */
#ifdef PREINIT_SUPPORTED
preinit();
#endif
application_init( );
for ( ; ; )
{
application_task( );
}
return 0;
}
static void btez2_clear_app_buf ( void )
{
memset( app_buf, 0, app_buf_len );
app_buf_len = 0;
}
static void btez2_log_app_buf ( void )
{
for ( int32_t buf_cnt = 0; buf_cnt < app_buf_len; buf_cnt++ )
{
log_printf( &logger, "%c", app_buf[ buf_cnt ] );
}
}
static err_t btez2_process ( btez2_t *ctx )
{
uint8_t rx_buf[ PROCESS_BUFFER_SIZE ] = { 0 };
int32_t overflow_bytes = 0;
int32_t rx_cnt = 0;
int32_t rx_size = btez2_generic_read( ctx, rx_buf, PROCESS_BUFFER_SIZE );
if ( ( rx_size > 0 ) && ( rx_size <= APP_BUFFER_SIZE ) )
{
if ( ( app_buf_len + rx_size ) > APP_BUFFER_SIZE )
{
overflow_bytes = ( app_buf_len + rx_size ) - APP_BUFFER_SIZE;
app_buf_len = APP_BUFFER_SIZE - rx_size;
memmove ( app_buf, &app_buf[ overflow_bytes ], app_buf_len );
memset ( &app_buf[ app_buf_len ], 0, overflow_bytes );
}
for ( rx_cnt = 0; rx_cnt < rx_size; rx_cnt++ )
{
if ( rx_buf[ rx_cnt ] )
{
app_buf[ app_buf_len++ ] = rx_buf[ rx_cnt ];
}
}
return BTEZ2_OK;
}
return BTEZ2_ERROR;
}
static err_t btez2_wait_packet ( btez2_t *ctx, uint8_t timeout_s, uint8_t rsp_flag, uint8_t *cmd_code )
{
err_t error_flag = BTEZ2_OK;
uint32_t timeout_cnt = 0;
while ( ( timeout_cnt < timeout_s ) || ( BTEZ2_WAIT_TIMEOUT_INFINITE == timeout_s ) )
{
error_flag = btez2_read_packet( ctx );
if ( BTEZ2_OK == error_flag )
{
if ( BTEZ2_PACKET_TYPE_EVENT == ctx->evt_pkt.rsp_flag )
{
log_printf ( &logger, " < EVENT >\r\n" );
}
else
{
log_printf ( &logger, " < RESPONSE >\r\n" );
}
if ( ( BTEZ2_PACKET_TYPE_EVENT == ctx->evt_pkt.rsp_flag ) &&
( strstr( ctx->evt_pkt.command, BTEZ2_EVT_SYS_ERROR ) ) )
{
log_printf( &logger, " Wrong CMD!\r\n" );
error_flag = BTEZ2_ERROR_CMD;
break;
}
else
{
log_printf ( &logger, " Command: %s\r\n", ctx->evt_pkt.command );
if ( BTEZ2_PACKET_TYPE_RESPONSE == ctx->evt_pkt.rsp_flag )
{
log_printf ( &logger, " Type: " );
switch ( ctx->evt_pkt.command_type )
{
case '/':
{
log_printf ( &logger, "Action\r\n" );
break;
}
case 'S':
{
log_printf ( &logger, "Set\r\n" );
break;
}
case 'G':
{
log_printf ( &logger, "Get\r\n" );
break;
}
case '.':
{
log_printf ( &logger, "Profile\r\n" );
break;
}
default:
{
log_printf ( &logger, "Unknown\r\n" );
break;
}
}
if ( ctx->evt_pkt.rsp_result )
{
log_printf( &logger, " Result: %.4X\r\n", ctx->evt_pkt.rsp_result );
if ( ( ctx->evt_pkt.rsp_flag == rsp_flag ) &&
( 0 == strcmp( ctx->evt_pkt.command, cmd_code ) ) )
{
error_flag = BTEZ2_ERROR;
break;
}
}
else
{
log_printf( &logger, " Result: OK\r\n" );
}
}
if ( strlen ( ctx->evt_pkt.payload ) )
{
log_printf ( &logger, " Payload: %s\r\n", ctx->evt_pkt.payload );
}
if ( ( ctx->evt_pkt.rsp_flag == rsp_flag ) &&
( 0 == strcmp( ctx->evt_pkt.command, cmd_code ) ) )
{
error_flag = BTEZ2_OK;
break;
}
}
}
else
{
timeout_cnt++;
}
}
if ( ( timeout_cnt >= timeout_s ) && ( 0 != timeout_s ) )
{
log_printf( &logger, " < TIMEOUT >\r\n" );
error_flag = BTEZ2_ERROR_TIMEOUT;
}
log_printf( &logger, "--------------------------------\r\n" );
return error_flag;
}
static err_t btez2_power_up ( btez2_t *ctx )
{
err_t error_flag = BTEZ2_OK;
log_printf( &logger, ">> Reset device.\r\n" );
btez2_set_cmd_mode( ctx );
btez2_reset_device( ctx );
error_flag |= btez2_wait_packet( ctx, BTEZ2_WAIT_TIMEOUT_5S,
BTEZ2_PACKET_TYPE_EVENT,
BTEZ2_EVT_GAP_ADV_STATE_CHANGED );
log_printf( &logger, ">> Check communication.\r\n" );
btez2_cmd_action( ctx, BTEZ2_CMD_SYS_PING, NULL );
error_flag |= btez2_wait_packet( ctx, BTEZ2_WAIT_TIMEOUT_5S,
BTEZ2_PACKET_TYPE_RESPONSE,
BTEZ2_CMD_SYS_PING );
return error_flag;
}
static err_t btez2_config_example ( btez2_t *ctx )
{
err_t error_flag = BTEZ2_OK;
log_printf( &logger, ">> Factory reset.\r\n" );
btez2_cmd_action( ctx, BTEZ2_CMD_SYS_FACTORY_RESET, NULL );
error_flag |= btez2_wait_packet( ctx, BTEZ2_WAIT_TIMEOUT_5S,
BTEZ2_PACKET_TYPE_EVENT,
BTEZ2_EVT_GAP_ADV_STATE_CHANGED );
log_printf( &logger, ">> Save settings.\r\n" );
btez2_cmd_action( ctx, BTEZ2_CMD_SYS_STORE_CONFIG, NULL );
error_flag |= btez2_wait_packet( ctx, BTEZ2_WAIT_TIMEOUT_5S,
BTEZ2_PACKET_TYPE_RESPONSE,
BTEZ2_CMD_SYS_STORE_CONFIG );
log_printf( &logger, ">> Reboot.\r\n" );
btez2_cmd_action( ctx, BTEZ2_CMD_SYS_REBOOT, NULL );
error_flag |= btez2_wait_packet( ctx, BTEZ2_WAIT_TIMEOUT_5S,
BTEZ2_PACKET_TYPE_EVENT,
BTEZ2_EVT_GAP_ADV_STATE_CHANGED );
log_printf( &logger, ">> Get BT address.\r\n" );
btez2_cmd_get( ctx, BTEZ2_CMD_SYS_BT_ADDRESS, NULL );
error_flag |= btez2_wait_packet( ctx, BTEZ2_WAIT_TIMEOUT_5S,
BTEZ2_PACKET_TYPE_RESPONSE,
BTEZ2_CMD_SYS_BT_ADDRESS );
log_printf( &logger, ">> Get device name.\r\n" );
btez2_cmd_get( ctx, BTEZ2_CMD_GAP_DEVICE_NAME, NULL );
error_flag |= btez2_wait_packet( ctx, BTEZ2_WAIT_TIMEOUT_5S,
BTEZ2_PACKET_TYPE_RESPONSE,
BTEZ2_CMD_GAP_DEVICE_NAME );
return error_flag;
}
static err_t btez2_example ( btez2_t *ctx )
{
err_t error_flag = BTEZ2_OK;
uint32_t timeout_cnt = 0;
#define BT_TERMINAL_TIMEOUT_MS 60000
#define BT_TERMINAL_MESSAGE_FREQ_MS 5000
Delay_ms ( 100 );
log_printf( &logger, ">> Waiting for a BT peer to establish connection with the Click board...\r\n" );
error_flag |= btez2_wait_packet( ctx, BTEZ2_WAIT_TIMEOUT_INFINITE,
BTEZ2_PACKET_TYPE_EVENT,
BTEZ2_EVT_CYSPP_STATUS );
log_printf( &logger, ">> BT peer has connected.\r\n" );
btez2_set_data_mode( ctx );
log_printf( &logger, ">> Waiting for data (up to 60 seconds)...\r\n" );
for ( ; ; )
{
btez2_clear_app_buf( );
if ( BTEZ2_OK == btez2_process( ctx ) )
{
Delay_ms ( 100 );
timeout_cnt = 0;
btez2_process( ctx );
btez2_log_app_buf( );
if ( strstr( app_buf, BTEZ2_EVT_GAP_DISCONNECTED ) )
{
log_printf( &logger, ">> BT peer has disconnected.\r\n" );
btez2_set_cmd_mode( ctx );
break;
}
}
timeout_cnt++;
if ( 0 == ( timeout_cnt % BT_TERMINAL_MESSAGE_FREQ_MS ) )
{
log_printf( &logger, ">> Sending \"%s\" message to connected device.\r\n", ( char * ) MESSAGE_CONTENT );
error_flag |= btez2_generic_write ( ctx, MESSAGE_CONTENT, strlen ( MESSAGE_CONTENT ) );
error_flag |= btez2_generic_write ( ctx, BTEZ2_PACKET_END, strlen ( BTEZ2_PACKET_END ) );
Delay_ms ( 100 );
}
if ( BT_TERMINAL_TIMEOUT_MS < timeout_cnt )
{
btez2_set_cmd_mode( ctx );
break;
}
Delay_ms ( 1 );
}
return error_flag;
}
// ------------------------------------------------------------------------ END
额外支持
资源
类别:蓝牙/蓝牙低功耗