蓝牙BLE实用教程

时间:2023-03-08 19:35:43

蓝牙BLE实用教程

Bluetooth
BLE

欢迎使用 小书匠(xiaoshujiang)编辑器,您可以通过 设置 里的修改模板来改变新建文章的内容。

1.蓝牙BLE常见问答

Q: Smart Ready 和 Smart 以及传统蓝牙之间是什么关系?

A:

1.Smart Ready 可以和 Smart Ready、传统蓝牙,以及 Smart 之间相互连接和通信。

2.传统蓝牙可以和 Smart Ready、传统蓝牙之间连接和通信

3.Smart 可以和 Smart、 Smart Ready 之间连接和通信

蓝牙BLE实用教程

2016-06-13_174221.jpg

Q: 双模(dual-mode)和单模(single-mode)有什么区别?

A: 都是蓝牙芯片,双模指的是同时支持1:BasicRate ( BR), 2:Bluetooth Low Energy ( BLE),如手机, PC 等采用的均是双模的蓝牙芯片。很多 android手机都表明支持蓝牙 4.0,其实很大部分只支持 Smart Ready 里的 BR。不是硬件的问题而是软件里还不支持LE。目前 Android4.3 系统才开始全面支持 BLE。iOS 设备对蓝牙 4.0 支持的最好,只要是 iPhone4S 和以后的设备均完美完全支持蓝牙 4.0。单模指的是只支持Bluetooth Low Energy ( 缩写:BLE或者LE),目前我们在使用的如Cypress的PSoC和PRoC系列,TI的CC2640等都是单模芯片,只支持Smart。BLE最主要特点是低功耗和低速率,网上关于蓝牙 4.0 一节纽扣电池能够使用一年均是针对 BLE 而言。

蓝牙BLE实用教程

1465828530504.jpg

Q: There is a confusion between Server-Client vs Master-Slave vs Central-Peripheral. I need a simplified explanation.

A: These are the different roles defined at different layers of the BLE protocol stack.

Link Layer roles:

  • Master - Initiates a connection
  • Slave - Advertises and waits for a connection initiation

GATT roles:

  • Server - Has data
  • Client - Wants data

GAP roles:

  • Central - The primary device in a connection
  • Peripheral - The secondary device in a connection

The GAP Central is always a Link Layer Master, while the GAP Peripheral is always a Link Layer Slave.

Q: I am new to Bluetooth Low Energy and looking for a quick bringup. Where do I start?

A: For a quick bringup with Bluetooth Low Energy, please refer to the following:

If you want to know about the technology, please refer to the videos available at BLE Developer Portal.

2.BLE协议栈介绍

2.1 Architecture / Configurations

蓝牙BLE实用教程

1465808274415.jpg
  • Protocol stack consists of two main sections:

    绿色 Controller

    蓝色 Host
  • Controller Block Diagram
蓝牙BLE实用教程

2016-06-24_120236.jpg
  • Profiles and Application sit on top of the GAP and GATT layers of the host
  • In a “single-device solution” (or “single-chip solution”), the host, controller, profiles, and application are all implemented together on the same chip
  • In a “dual-device solution”, the BLE controller is implemented on one device, while the host,application, and profiles are implemented separately
  • In a “network processor”, the host and controller are implemented together, but the application and profiles sit on another device (such as a PC or external microcontroller)

2.2 Physical Layer

  • RF Specifications
    • Operates in 2.4 GHz ISM band
    • GFSK modulation
    • 40 channels with 2 MHz spacing
      • 3 fixed advertisting channels for broadcasting, which avoid 802.11 interferance
      • 37 adaptively frequency hoppeddynamic data channels
  • Physical layer can be combined with standard Bluetooth RF in a dual-mode device
  • 2 MHz spacing allows for better adjacent channel rejection

2.3 BLE Link Layer

  • **Channl :**3 Advertising Channels and 37 Data Channels
蓝牙BLE实用教程

1465811675073.jpg
  • States and Network Topology

    • There are six possible Link Layer states of a BLE device:
      • Standby - device is not transmitting or receiving any data, and is not connected to any other device
      • Advertiser - periodically broadcasting advertisements
      • Scanner - actively looking for advertisers
      • Initiator - actively trying to initiate a connection with another device
      • Master - connected to another device as a master
      • Slave - connected to another device as a slave
    • BLE is a star topology network:
      • Master device “manages” the connection,and can be connected to multiple slaves
      • Slave device can only be connected to one master
  • Advertisement Events

    • During one “advertising event”, an advertisement packet is transmitted on each of the three advertising channels (37, 38, and 39)
  • Advertisement Intervals

    • The advertising device has an “advertising interval”, which is the minimum amount of time between two advertising events
    • Advertising Interval can be any amount of time between 20ms and 10.24s
  • Advertisement Types

    • Four types of advertisements:

      • Connectable undirected- any scanner device can initiate a connection with this advertiser
      • Connectable directed- only one specific device can initiate a connection with this advertiser
      • Non-connectable undirected- no devices can initiate a connection with this advertiser; primarily used for general broadcast of data
      • Discoverable undirected- any scanner device can request more information from the advertising device, but no devices can initiate a connection with it
      蓝牙BLE实用教程

      2016-06-13_190115.jpg
  • Scanning

    Active Scanning Packet Flow

蓝牙BLE实用教程

1465815899962.jpg
  • Connection Initiation

    Connection Request Packet Flow
蓝牙BLE实用教程

1465816179961.jpg
  • Connection Parameters

    • Channel Map- indicates which data channels are used during the connection
    • Connection Interval- multiple of 1.25ms in range of 7.5ms and 4.0s
    • Supervision Timeout- multiple of 10ms in the range of 100ms and 32.0s. Must be larger than: (1 + slaveLatency) * (ConnInterval)
    • Slave Latency- any value between 0 and 499, though it cannot exceed:((supervisionTimeout / connInterval) – 1)
  • Connection Events

    • All communications between two connected devices occur in “connection events”
    • Each event occurs on one data channel (channels 0-36), with the hop increment parameter determining the next channel for the next event
    • During each connection event, the master transmits first, and the slave responds 150us later
    • Master and slave can continue transmitting back and forth as many times as they want during a single connection event
    • Connection events occur even when one (or both) sides have no data to send (the exception to this is when slave latency is enabled; more information on next slide). This allows both devices to acknowledge that the other is still there and keeps the connection active.
    蓝牙BLE实用教程

    2016-06-13_192301.jpg
  • Slave Latency

蓝牙BLE实用教程

1465817247343.jpg
  • Connection Parameters Tradeoffs

    • Short connection interval:
      • Higher power consumption for both devices
      • Higher throughput in both directions
      • Shorter wait for data to be sent in either direction
    • Long connection interval:
      • Lower power consumption for both devices
      • Lower throughput in both directions
      • Longer wait for data to be sent in either direction
    • Low / Zero slave latency:
      • Higher power consumption for peripheral
      • Peripheral receives data sent from central device sooner
    • High slave latency:
      • Lower power consumption for peripheral during periods when it has no data to send

        to central device
      • Peripheral may not immediately receive data being sent from central device
  • Connection Update Request

    If the slave does not like the connection parameters (interval, slave latency, or supervision timeout), it can send a connection update request to the master

  • Connection Termination

    • A connection can be voluntarily terminated by either the master or the slave for any reason
    • Connection can also be terminated as a result of a supervision timeout
  • Direct Test Mode

    Allows a tester to directly control the device under test (DUT) in either Rx or Tx mode on any channel with any amount of data

蓝牙BLE实用教程

1465827463935.jpg

2.4 Host/Controller Interface (HCI)

  • Reused from standard Bluetooth specification,with new additional commands for low energy specific functions
  • Thin layer; doesn‟t perform any processing
  • In a dual-chip solution (with separate host and controller) allows for host to communicate with controller over a standard interface (UART,USB, SDIO, etc.)
  • Used internally by the CC2540 BLE protocol stack for communication between higher and lower layers
  • Also allows for custom “vendor-specific commands”. In the CC2540, vendor-specific commands can be used by an external source to directly interface with the entire stack or application. This is called a “Network Processor”

2.5 Host -- Logical Link Control and Adaptation Protocol (L2CAP)

  • Permits upper level protocols and applications to transmit and receive upper layer data packets up to 23 bytes in length
  • Provides channel management, allowing for logical channels between two endpoints,supported by the link layer
  • Connection Parameter Updates

2.6 Security Manager Protocol (SMP)

  • Performs authentication and key management
  • Uses AES-128 as the encryption algorithm for security procedures
  • Defines protocol to setup secure link
  • Works with GAP to manage relationships between devices:
    • Pairing – encryption between two devices once a connection has been established between them
    • Authentication – verification that a peer device can be trusted, providing protection against “Man-in-the-Middle” attacks
    • Bonding – long-term relationship between devices; security and identity information is saved for re-use next time the devices are connected

2.7 Generic Access Profile (GAP)

  • Overview
    • Defines generic procedures for connection-related services:
      • Device Discovery
      • Link Establishment
      • Link Management
      • Link Termination
      • Initiation of security features
    • Many GAP functions correspond directly to the functions of the Link Layer in the controller
  • Profile Roles
    • The GAP layer works in one of four profile roles:
      • Broadcaster – an advertiser that is non-connectable
      • Observer – scans for advertisements, but cannot initiate connections.
      • Peripheral – an advertiser that is connectable and can operate as a slave in a single link layer connection.
      • Central – scans for advertisements and initiates connections; operates as a master in a single or multiple link layer connections.
蓝牙BLE实用教程

1465875931887.jpg
  • Profile Multi-Roles
    • The BLE specification allows for a few different possible multiple-role configurations:
      • Peripheral and Broadcaster
      • Peripheral and Observer
      • Central and Broadcaster
  • Discoverable Modes
    • GAP supports three different discoverable modes:
      • Non-discoverable Mode – No advertisements
      • Limited Discoverable Mode – Device advertises for a limited amount of time before returning to the standby state
      • General Discoverable Mode – Devices advertises continuously
  • Advertisement and Scan Response Data
    • GAP manages the data that is sent out in advertisement and scan response packets
  • Pairing
    • Pairing can be initiated by either the central or peripheral device
    • Based on the combination of the capabilities of the two devices, one of two methods of pairing will be used:
      • Passkey entry – one device will display a randomly generator passkey, while the other will require the user to input the passkey. This allows for an authenticated link (MITM protection)
      • “Just Works” – the pairing process completes without requiring a passkey to be entered. The link will not be authenticated, but is encrypted
    • During the pairing process, each device states whether it wants authentication to the other device
      • Each device also states it‟s input/output capabilities from among these options:
        • DisplayOnly – no way user can input anything into device, but it can output data
        • DisplayYesNo – user can input “yes” or “no” but nothing else; can also display data
        • KeyboardOnly – user can input a password or PIN, but no display
        • NoInputNoOutput – device has no means for user input, and has no display
        • KeyboardDisplay – device has a means for display as well as for input

2.8 Attribute Protocol (ATT)

  • Overview

    • ATT defines the over-the-air protocol for reading, writing, and discovering attributes
    • An attribute is a discrete value that has associated with it the following three properties:
      1. A handle (address)
      2. A type
      3. A set of permissions
  • Client / Server Architecture

    • Servers have data, Clients want to use this data
  • Attribute Table Example

    • Handle – The address of the attribute in the table
    • Type – Tells what the data represents; can be a UUID (universal unique identifier) assigned by the Bluetooth SIG, or a custom type
    • Permissions – Enforces if and how the attribute client can access the attribute‟s value

2.9 Generic Attribute Profile (GATT)

  • Overview

    • Designed for use by the application or a profile, so that an attribute client can communicate with attribute server
    • GATT defines:
      • Procedures for using the attribute protocol (ATT) to discover, read, write, and obtain indications of these attributes
      • The grouping and relationship of characteristics within a service or profile
      • Procedures for configuring the broadcast of attributes
    • 通用属性配置文件 (gatt)
  • Client / Server Architecture

    • GATT specifies the structure in which profile data is exchanged
    • Same client server architecture as Attribute Protocol, except that data is encapsulated in “Services” and data is exposed in “Characteristic”
  • Profile Hierarchy

    • A profile is composed of one or more “services” necessary to fulfill a use-case
    • A service may contain certain attributes called “characteristic values”, which are values used by a service (example: in a temperature sensor, the attribute containing the temperature itself is the characteristic value)
    • A characteristic value must have a mandatory “characteristic declaration” attribute immediately before the value,containing the properties of the characteristic
    • Characteristics may also contain optional “descriptor” attributes, with fields such as a configuration or a description
蓝牙BLE实用教程

1465882745971.jpg

GATT database:

  1. const CYBLE_GATTS_DB_T cyBle_gattDB[0x10u] = { 

  2. { 0x0001u, 0x2800u /* Primary service */, 0x00000001u /* */, 0x0007u, {{0x1800u, NULL}} }, 

  3. { 0x0002u, 0x2803u /* Characteristic */, 0x00000201u /* rd */, 0x0003u, {{0x2A00u, NULL}} }, 

  4. { 0x0003u, 0x2A00u /* Device Name */, 0x00000201u /* rd */, 0x0003u, {{0x0009u, (void *)&cyBle_attValuesLen[0]}} }, 

  5. { 0x0004u, 0x2803u /* Characteristic */, 0x00000201u /* rd */, 0x0005u, {{0x2A01u, NULL}} }, 

  6. { 0x0005u, 0x2A01u /* Appearance */, 0x00000201u /* rd */, 0x0005u, {{0x0002u, (void *)&cyBle_attValuesLen[1]}} }, 

  7. { 0x0006u, 0x2803u /* Characteristic */, 0x00000201u /* rd */, 0x0007u, {{0x2A04u, NULL}} }, 

  8. { 0x0007u, 0x2A04u /* Peripheral Preferred Connection Par */, 0x00000201u /* rd */, 0x0007u, {{0x0008u, (void *)&cyBle_attValuesLen[2]}} }, 

  9. { 0x0008u, 0x2800u /* Primary service */, 0x00000001u /* */, 0x000Bu, {{0x1801u, NULL}} }, 

  10. { 0x0009u, 0x2803u /* Characteristic */, 0x00002201u /* rd,ind */, 0x000Bu, {{0x2A05u, NULL}} }, 

  11. { 0x000Au, 0x2A05u /* Service Changed */, 0x00002201u /* rd,ind */, 0x000Bu, {{0x0004u, (void *)&cyBle_attValuesLen[3]}} }, 

  12. { 0x000Bu, 0x2902u /* Client Characteristic Configuration */, 0x00000A04u /* rd,wr */, 0x000Bu, {{0x0002u, (void *)&cyBle_attValuesLen[4]}} }, 

  13. { 0x000Cu, 0x2800u /* Primary service */, 0x00000001u /* */, 0x0010u, {{0xCBBBu, NULL}} }, 

  14. { 0x000Du, 0x2803u /* Characteristic */, 0x00001A01u /* rd,wr,ntf */, 0x0010u, {{0xCBB1u, NULL}} }, 

  15. { 0x000Eu, 0xCBB1u /* Custom Buffer */, 0x00011A04u /* rd,wr,ntf */, 0x0010u, {{0x00C8u, (void *)&cyBle_attValuesLen[5]}} }, 

  16. { 0x000Fu, 0x2901u /* Custom Descriptor */, 0x00010001u /* */, 0x000Fu, {{0x001Cu, (void *)&cyBle_attValuesLen[6]}} }, 

  17. { 0x0010u, 0x2902u /* Client Characteristic Configuration */, 0x00010A04u /* rd,wr */, 0x0010u, {{0x0002u, (void *)&cyBle_attValuesLen[7]}} }, 

  18. }; 

Custom Uart Tx Service

Handle att Type Permission value
0x000Cu 0x2800(GATT Service UUID) read 0xCBBBu(2bytes)
0x000Du 0x2803u (GATT Characteristic UUID) read,write,notify 0xCBB1u(2bytes)
0x000Eu 0xCBB1u (Custom Buffer UUID) read,write,notify (200bytes)
0x000Fu 0x2901u (Custom Descriptor UUID) read (28bytes)
0x0010u 0x2902u (Client Characteristic Configuration UUID) read,write (2bytes)
  • Client Commands

    • When two BLE devices are in the connected state, the GATT client device can perform several different sub-procedures to communicate with the GATT server device:

      • Discover Characteristic by UUID – search the GATT server for all attributes with type that matches the specified UUID
      • Read Characteristic Value – read the value of the characteristic at the specified handle
      • Write Characteristic Value – write a new value to the characteristic at the specified handle
    • A GATT server device, when configured to do so, can send out messages to the GATT client device without being prompted:

      • Notification – The value a characteristic is sent from the server to the client without receiving a read request, and does not need to be acknowledged
      • Indication – The value a characteristic is sent from the server to the client without receiving a read request, but must be acknowledged before any further data can be sent

3. BLE应用实例

3.1 BLE转串口透传例程

BLE_Uart_Transmission_Collector01BLE_UART_Transmission_Server组成一对主从机程序,实现串口透传功能。

硬件组成:基于 CY8CKIT-042 BLE Pioneer Kit

3.2 程序介绍

3.2.1 程序流程

蓝牙BLE实用教程
  • Psoc Creator 工程图示
蓝牙BLE实用教程

1465890989305.jpg

3.2.2 主机和从机的联系

主机 从机
profile customer profile customer profile
profile role Client(GATT Client) server(GATT Server)
GAP role Central Peripheral
  • 在主流程上主机和从机是类似的
  • 主机在BLE使能后,执行的 scan
  1. case CYBLE_EVT_STACK_ON: 

  2. printf("EVT_STACK_ON \r\n"); 

  3. goto start_scan; 


  4. case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: 

  5. BleConnected = 0; 

  6. printf("EVT_GAP_DEVICE_DISCONNECTED \r\n"); 

  7. goto start_scan; 


  8. case CYBLE_EVT_TIMEOUT: 

  9. printf("EVT_TIMEOUT \r\n"); 

  10. start_scan: 

  11. if(BleConnected == 0) 



  12. StartScan(CYBLE_UUID_CUSTOMER_SERVICE);//CYBLE_UUID_CUSTOM_UART_TX_SERVICE 

  13. //Scanning_LED_Write(LED_ON);  

  14. ble_state = BLE_SCAN_STATE; 




  15. break; 

  • 从机在BLE使能后,执行的是Advertisement
  1. case CYBLE_EVT_STACK_ON: 

  2. printf("EVT_STACK_ON \r\n"); 

  3. goto start_advert; 

  4. case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: 

  5. //ble_state = BLE_DISCONNECTED_STATE; 

  6. case CYBLE_EVT_TIMEOUT: 

  7. start_advert: 

  8. /* Put the device into discoverable mode so that remote can search it. */ 

  9. StartAdvertisement(); 

  10. //Advertising_LED_Write(LED_ON); 

  11. ble_state = BLE_ADV_STATE; 

  12. test_ptr=0; 

  13. break; 

  • 下面是主机找到从机的关键函数,最终以 flag |= CONNECT; 为出口,并在scan结束后CYBLE_EVT_GAPC_SCAN_START_STOP,发起连接CyBle_GapcConnectDevice(&peerAddr[deviceN]), peerAddr[deviceN]就是找到的从机的mac地址。
  1. void ScanProgressEventHandler(CYBLE_GAPC_ADV_REPORT_T* eventParam) 



  2. uint8 newDevice = 0u, device = 0u; 

  3. uint8 i; 

  4. uint8 adStructPtr = 0u; 

  5. uint8 adTypePtr = 0u; 

  6. uint8 nextPtr = 0u; 


  7. printf("SCAN_PROGRESS_RESULT: peerAddrType - %d, ", eventParam->peerAddrType); 

  8. printf("peerBdAddr - "); 

  9. for(newDevice = 1u, i = 0u; i < advDevices; i++) 



  10. if((memcmp(peerAddr[i].bdAddr, eventParam->peerBdAddr, CYBLE_GAP_BD_ADDR_SIZE) == 0)) /* same address */ 



  11. device = i; 

  12. printf("%x: ", device); 

  13. newDevice = 0u; 

  14. break; 





  15. if(newDevice != 0u) 



  16. if(advDevices < CYBLE_MAX_ADV_DEVICES) 



  17. memcpy(peerAddr[advDevices].bdAddr, eventParam->peerBdAddr, CYBLE_GAP_BD_ADDR_SIZE); 

  18. peerAddr[advDevices].type = eventParam->peerAddrType; 

  19. device = advDevices; 

  20. advDevices++; 

  21. printf("%x: ", device); 






  22. for(i = CYBLE_GAP_BD_ADDR_SIZE; i > 0u; i--) 



  23. printf("%2.2x", eventParam->peerBdAddr[i-1]); 



  24. printf(", rssi - %d dBm, data - ", eventParam->rssi); 


  25. /* Print and parse advertisement data and connect to device which has HRM */ 

  26. adStructPtr = 0u; 

  27. for(i = 0; i < eventParam->dataLen; i++) 



  28. printf("%2.2x ", eventParam->data[i]); 


  29. if(i == adStructPtr) 



  30. adTypePtr = i + 1; 

  31. adStructPtr += eventParam->data[i] + 1; 

  32. nextPtr = 1; 



  33. else if(i == (adTypePtr + nextPtr)) 



  34. switch(eventParam->data[adTypePtr]) 



  35. case CYBLE_GAP_ADV_FLAGS: 

  36. break; 


  37. case CYBLE_GAP_ADV_INCOMPL_16UUID: 

  38. case CYBLE_GAP_ADV_COMPL_16UUID: 

  39. if(serviceUuid == CyBle_Get16ByPtr(&(eventParam->data[i]))) 



  40. newDevice = 2; /* temporary use newDevice as a flag */ 



  41. else 



  42. nextPtr += 2; 



  43. break; 


  44. default: 

  45. break; 







  46. printf("newDevice = %d \r\n",newDevice); 


  47. if(2 == newDevice) 



  48. deviceN = device; 

  49. printf(" This device contains "); 

  50. switch(serviceUuid) 



  51. case CYBLE_UUID_HEART_RATE_SERVICE: 

  52. printf("Heart Rate Service \r\n"); 

  53. break; 


  54. case CYBLE_UUID_GLUCOSE_SERVICE: 

  55. printf("Glucose Service \r\n"); 

  56. break; 


  57. case CYBLE_UUID_BLOOD_PRESSURE_SERVICE: 

  58. printf("Blood Pressure Service \r\n"); 

  59. break; 

  60. case CYBLE_UUID_HIDS_SERVICE: 

  61. printf("HID Service \r\n"); 

  62. printf("Stop Scanning, waiting for Scanning event \r\n"); 

  63. flag |= CONNECT; 

  64. CyBle_GapcStopScan(); 


  65. break; 

  66. /* other services */ 

  67. case 0x290A: 

  68. printf("Stop Scanning, waiting for Scanning event \r\n"); 

  69. flag |= CONNECT; 

  70. CyBle_GapcStopScan(); 

  71. break; 


  72. case CYBLE_UUID_CUSTOMER_SERVICE: 

  73. printf("Customer Service \r\n"); 

  74. printf("Stop Scanning, waiting for Scanning event \r\n"); 

  75. flag |= CONNECT; 

  76. CyBle_GapcStopScan(); 


  77. break; 


  78. default: 

  79. printf("%x \r\n", serviceUuid); 

  80. break; 





  81. else 



  82. printf("\r\n"); 





3.2.3 初始化程序

以主机为例

  1. int main() 



  2. CYBLE_API_RESULT_T apiResult; 


  3. CYBLE_LP_MODE_T lpMode; 


  4. CyGlobalIntEnable; 


  5. CommInit(); /* Start communication component */ 

  6. printf("BLE Uart Transmission Collector Example Project \r\n"); 


  7. Scanning_LED_Write(LED_OFF); 


  8. apiResult = CyBle_Start(AppCallBack); 

  9. if(apiResult != CYBLE_ERROR_OK) 



  10. printf("CyBle_Start API Error: %xd \r\n", apiResult); 



  11. else 



  12. printf("CyBle_Start API ok \r\n"); 




  13. /* Enable the Interrupt component connected to interrupt */ 

  14. TC_CC_ISR_StartEx(InterruptHandler); 


  15. /* Start the components */ 

  16. Timer_Start(); 

3.2.4 主程序

以主机为例

  1. while(1) 



  2. if(CyBle_GetState() != CYBLE_STATE_INITIALIZING) 



  3. /* Enter DeepSleep mode between connection intervals */ 

  4. lpMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP); 

  5. if(lpMode == CYBLE_BLESS_DEEPSLEEP)  



  6. /* Put the device into the Deep Sleep mode only when all debug information has been sent  

  7. if(UART_DEB_SpiUartGetTxBufferSize() == 0u) 



  8. CySysPmDeepSleep(); 



  9. else 



  10. CySysPmSleep(); 

  11. }*/ 

  12. CySysPmSleep(); 

  13. /* Handle scanning led blinking */ 

  14. HandleLEDs(ble_state); 



  15. HandleLEDs(ble_state); 



  16. /*********************************************************************** 

  17. * Wait for connection established with Central device 

  18. ***********************************************************************/ 

  19. if(CyBle_GetState() == CYBLE_STATE_CONNECTED) 



  20. /******************************************************************* 

  21. * Periodically measure a battery level and temperature and send  

  22. * results to the Client 

  23. *******************************************************************/  

  24. CommMonitorUart(); 

  25. CommMonitorBLE(); 



  26. #if 0 

  27. if(mainTimer != 0u) 



  28. mainTimer = 0u; 


  29. if(storeBondingData == ENABLED) 



  30. cystatus retValue; 

  31. retValue = CyBle_StoreBondingData(0u); 

  32. printf("Store bonding data, status: %lx \r\n", retValue); 

  33. storeBondingData = DISABLED; 






  34. #endif 







  35. /******************************************************************* 

  36. * Processes all pending BLE events in the stack 

  37. *******************************************************************/  

  38. CyBle_ProcessEvents(); 



  1. /////////////////////////////////////////////////////////////////////////////// 

  2. /// \brief MonitorBLE 

  3. /// \param none 

  4. /// \return none 

  5. /// \deprecated monitor ble send usd uart tx 

  6. /////////////////////////////////////////////////////////////////////////////// 

  7. void CommMonitorBLE(void) 



  8. if(uCommState.Bit.BLERxFinshed == ENABLED) 

  9. {  

  10. uCommState.Bit.BLERxFinshed = DISABLED; 


  11. CommUartTxByte(); 

  12. // Then switch to Uart RX state 

  13. CommUartRxReady();  

  14. BLE_LED_OFF; 


  15. // Then switch to RF RX state 

  16. CommBLERxReady(); 






  1. /////////////////////////////////////////////////////////////////////////////// 

  2. /// \brief CommMonitorUart 

  3. /// \param none 

  4. /// \return none 

  5. /// \deprecated monitor uart send use ble 

  6. /////////////////////////////////////////////////////////////////////////////// 

  7. void CommMonitorUart(void) 



  8. CYBLE_API_RESULT_T apiResult; 

  9. CYBLE_GATT_HANDLE_VALUE_PAIR_T CustomNotificationhandle; 


  10. if(uCommState.Bit.UartRxFinished == ENABLED) 



  11. uCommState.Bit.UartRxFinished = DISABLED; 


  12. uCommState.Bit.BLERxRDY = DISABLED; 


  13. CustomNotificationhandle.attrHandle = UART_TX_HANDLE; 

  14. CustomNotificationhandle.value.val = &Buffer[1]; 

  15. CustomNotificationhandle.value.len = Buffer[0]; 

  16. CustomNotificationhandle.value.actualLen = Buffer[0]; 

  17. #if 0 


  18. /* Send notification to client using previously filled structure */ 

  19. apiResult = CyBle_GattsNotification(cyBle_connHandle, &CustomNotificationhandle); 

  20. #else 


  21. apiResult = CyBle_GattcWriteWithoutResponse(cyBle_connHandle,&CustomNotificationhandle); 

  22. #endif 

  23. /* Send uart receive handle as attribute for read by central device */ 

  24. CyBle_GattsWriteAttributeValue(&CustomNotificationhandle,FALSE,&cyBle_connHandle,FALSE); 

  25. #ifdef test 

  26. if(apiResult != CYBLE_ERROR_OK) 



  27. printf("ble send Error: %x \r\n", apiResult); 



  28. else 




  29. printf("ble send ok len: %x \r\n", CustomNotificationhandle.value.len); 



  30. #endif 


  31. CommUartRxReady(); 

  32. Uart_LED_OFF; 

  33. // Then switch to RF RX state 

  34. CommBLERxReady(); 






蓝牙的事件回调函数 接收蓝牙数据,产生uCommState.Bit.BLERxFinshed

  1. void AppCallBack(uint32 event, void* eventParam) 



  2. ... 


  3. case CYBLE_EVT_GATTC_HANDLE_VALUE_NTF:  

  4. wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam; 

  5. if(wrReqParam->handleValPair.attrHandle == UART_TX_HANDLE) 



  6. len = wrReqParam->handleValPair.value.len; 

  7. Buffer[0] = len; 

  8. memcpy(&Buffer[1],wrReqParam->handleValPair.value.val,len); 

  9. uCommState.Bit.BLERxFinshed = ENABLED; 

  10. //printf("len %d buf[0] %d \r\n", len,Buffer[0]); 




  11. .... 



串口中断函数及定时器中断函数 接收串口数据,产生uCommState.Bit.UartRxFinished

  1. /******************************************************************************* 

  2. * Function Name: Transport_RX_ISR 

  3. ******************************************************************************** 



  4. * Summary: 

  5. * Handles the Interrupt Service Routine for the UART RX. 

  6. * Contains cmdRxState m/c to check for valid command reciept and triggers flag 



  7. * Parameters: 

  8. * NONE 



  9. * Return: 

  10. * NONE 



  11. * Theory: 

  12. * NONE 



  13. * Side Effects: 

  14. * Command bufffers and newCmdRxDoneFlag will be modified 



  15. * Note: 



  16. *******************************************************************************/ 

  17. CY_ISR(Transport_RX_ISR) 


  18. /******************************************************************************* 

  19. * Function Name: Transport_Timer_ISR 

  20. ******************************************************************************** 



  21. * Summary: 

  22. * Handles the Interrupt Service Routine for the UART Timer. 

  23. * Resets RX command state m/c for every 10ms delay on RX byte 

  24. * If RX packet has started, there should not be more than 10ms delay between each RX byte with-in the packet 



  25. * Parameters: 

  26. * NONE 



  27. * Return: 

  28. * NONE 



  29. * Theory: 

  30. * NONE 



  31. * Side Effects: 

  32. * State m/c and other parameters will be reset 



  33. * Note: 



  34. *******************************************************************************/ 

  35. CY_ISR(Transport_Timer_ISR) 


3.2.5 程序的调试

  • 从机的debug信息
蓝牙BLE实用教程

11.png
  1. * 1 AppCallBack :CYBLE_EVT_STACK_ON:StartAdvertisement() 


  2. * 2 AppCallBack :CYBLE_EVT_GAPC_SCAN_START_STOP (SCAN_START) 


  3. * 3&4 AppCallBack :CYBLE_EVT_GAP_DEVICE_CONNECTED 连接间隔 为 7.5ms 


  4. * 5 AppCallBack :CYBLE_EVT_GATTC_XCHNG_MTU_RSP 变更成功 

  • 这个透传的程序目前我们用于无线打印数据,配合下图的虚拟示波器使用
蓝牙BLE实用教程

QQ图片20160615181218.jpg
蓝牙BLE实用教程

2次倒水的区别.jpg

3.3 其他精彩例程

PSoC 4 BLE is an easy-to-use, ARM® Cortex™-M0 based, single-chip solution which integrates programmable analog front ends, programmable digital peripherals, CapSense® technology for touch-sensing, and a Bluetooth® LE (Low Energy) or Bluetooth Smart radio. http://www.cypress.com/psoc4ble/ — Edit

4. BLE语音遥控器

4.1 概述

  • 利尔达BLE遥控器方案是基于蓝牙4.1的多功能智能遥控器解决方案,可以根据需求加入蓝牙语音,多指触控,体感控制等功能。本方案采样了Cypress的PRco系列,该系列是Cypress公司专门针对低功耗蓝牙设备推出的超低功耗,超高集成度的单芯片解决方案。
功能 性能 备注
BLE stack Bluetooth 4.2 single-mode device
TX output power –18 dBm to +3 dBm
RX sensitivity –89 dBm
TX current 15.6 mA at 0 dBm
RX current 16.4 mA
CPU Cortex-M0 operating at up to 48 MHz
flash memory 128~256 KB
SRAM memory 16~32 KB
Other feature 1.3-µA Deep-Sleep mode
CapSense® Touch Sensing
Two-finger gestures
12-bit, 1-Msps SAR ADC with internal reference
OTA

4.2 功能介绍

  • 语音部分 实现 256kbps的语音采样
    • I2S 数字语音接口
蓝牙BLE实用教程

1465891997716.jpg
  • ADC 模拟语音
蓝牙BLE实用教程

1465892054582.jpg
  • 触摸板
蓝牙BLE实用教程

1465892273795.jpg
  • 体感空鼠 6轴姿态补偿
蓝牙BLE实用教程

1465892334083.jpg
  • LED & IR 硬件实现呼吸灯 和 红外NEC编码
蓝牙BLE实用教程

1465892395048.jpg
  • 硬件实现行列键盘
蓝牙BLE实用教程

1465892431610.jpg

4.3 BLE HID Profile

  • Human Interface Device Service
蓝牙BLE实用教程

1465892594285.jpg
  • report map

    HID设备描述符 其中我们定义了两个私有的描述符,这个是我们用来传输语音的。因为BLE并不支持 A2DP(Advenced Audio Distribution Profile)蓝牙立体声协议,要传语音数据我们只能利用私有的通道。
蓝牙BLE实用教程

1465892713794.jpg
  • 在 android端提供相应的驱动来解析我们的语音数据,最终提供标准的PCM数据给到android的中间层。
蓝牙BLE实用教程

1465893098472.jpg