在.m文件中
#import"ViewController.h"#import"NSString+SL_Extension.h"#import@interfaceViewController()@property(nonatomic,strong) CBCentralManager *cMgr;/**< 中心管理設備 *//** 連接到的外設 */@property(nonatomic,strong) CBPeripheral *peripheral;@property(strong,nonatomic) CBCharacteristic? ? ? ? *writeCharacteristic;@property(nonatomic,strong)CBCharacteristic * characteristic;@end@implementationViewController// 1.建立中心管理者- (CBCentralManager *)cMgr{if(!_cMgr) {NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);/*
設置主設備的代理,CBCentralManagerDelegate
必須實現的:
- (void)centralManagerDidUpdateState:(CBCentralManager *)central;//主設備狀態改變調用,在初始化CBCentralManager的適合會打開設備,只有當設備正確打開后才能使用
其他選擇實現的委托中比較重要的:
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI; //找到外設
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;//連接外設成功
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//外設連接失敗
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//斷開外設
*/_cMgr = [[CBCentralManager alloc] initWithDelegate:selfqueue:dispatch_get_main_queue()];// 線程不傳默認是主線程}return_cMgr;}- (void)viewDidLoad {? ? [superviewDidLoad];self.title= @"大家好 我是山寨手環";self.view.backgroundColor= [UIColororangeColor];// 初始化[selfcMgr];// 不能在此處掃描,因為狀態還沒變為打開//[self.cMgr scanForPeripheralsWithServices:nil options:nil];}#pragma mark - CBCentralManagerDelegate// 中心管理者狀態改變, 在初始化CBCentralManager的時候會打開設備,只有當設備正確打開后才能使用- (void)centralManagerDidUpdateState:(CBCentralManager *)central{NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);switch(central.state) {caseCBCentralManagerStateUnknown:NSLog(@">>>CBCentralManagerStateUnknown");break;caseCBCentralManagerStateResetting:NSLog(@">>>CBCentralManagerStateResetting");break;caseCBCentralManagerStateUnsupported:NSLog(@">>>CBCentralManagerStateUnsupported");break;caseCBCentralManagerStateUnauthorized:NSLog(@">>>CBCentralManagerStateUnauthorized");break;caseCBCentralManagerStatePoweredOff:NSLog(@">>>CBCentralManagerStatePoweredOff");break;caseCBCentralManagerStatePoweredOn:NSLog(@">>>CBCentralManagerStatePoweredOn");// 2.開始掃描周圍的外設/*
第一個參數nil就是掃描周圍所有的外設,掃描到外設后會進入
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI;
*/[self.cMgrscanForPeripheralsWithServices:niloptions:nil];break;default:break;? ? }}// 掃描到設備會進入到此代理方法- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber*)RSSI{NSLog(@"%s, line = %d, per = %@, data = %@, rssi = %@", __FUNCTION__, __LINE__, peripheral, advertisementData, RSSI);// 接下來連接設備// 判斷設備號是否掃描到if([peripheral.nameisEqualToString:@"iCre Band"]) {/*
一個主設備最多能連7個外設,每個外設最多只能給一個主設備連接,連接成功,失敗,斷開會進入各自的委托
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;//連接外設成功的委托
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//外設連接失敗的委托
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//斷開外設的委托
*/// 保存外設,否則方法結束就銷毀self.peripheral= peripheral;// 發現完之后就是進行連接[self.cMgrconnectPeripheral:self.peripheraloptions:nil];NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);? ? }else{// 此處Alert提示未掃描到設備,重新掃描#warning noCodeNSLog(@"沒掃描到 >>>>>>>>? %s, line = %d", __FUNCTION__, __LINE__);? ? }}// 外設連接成功- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);NSLog(@">>>連接到名稱為(%@)的設備-成功",peripheral.name);//設置的peripheral代理CBPeripheralDelegate//@interface ViewController : UIViewController[peripheral setDelegate:self];//掃描外設Services,成功后會進入方法:-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{[peripheral discoverServices:nil];// 停止掃描[self.cMgrstopScan];}// 外設連接失敗- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError*)error{NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);}// 斷開連接(丟失連接)- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError*)error{NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);}#pragma mark - CBPeripheralDelegate// 發現外設的service- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError*)error{if(error)? ? {NSLog(@">>>Discovered services for %@ with error: %@", peripheral.name, [error localizedDescription]);return;? ? }for(CBService *service in peripheral.services) {NSLog(@"service.UUID = %@", service.UUID);//掃描每個service的Characteristics,掃描到后會進入方法: -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error[peripheral discoverCharacteristics:nilforService:service];? ? }}// 外設發現service的特征- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError*)error{if(error)? ? {NSLog(@"error Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]);return;? ? }#warning noCodeFor 優化,分開寫是為了讓大家看注釋清晰,并不符合編碼規范//獲取Characteristic的值,讀到數據會進入方法:-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error//? ? for (CBCharacteristic *characteristic in service.characteristics){//? ? ? ? [peripheral readValueForCharacteristic:characteristic]; // 外設讀取特征的值//? ? }//? ? //搜索Characteristic的Descriptors,讀到數據會進入方法:-(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error//? ? for (CBCharacteristic *characteristic in service.characteristics){//? ? ? ? [peripheral discoverDescriptorsForCharacteristic:characteristic]; // 外設發現特征的描述//? ? }for(CBCharacteristic * characteristic in service.characteristics) {//? ? ? ? NSLog(@"查找到的服務(屬性)%@",characteristic);//所對應的屬性用于接收和發送數據NSLog(@"service:%@ 的 Characteristic: %@",service.UUID,characteristic.UUID);if([characteristic.UUIDisEqual:[CBUUID UUIDWithString:@"6E400003-B5A3-F393-E0A9-E50E24DCCA9E"]]) {? ? ? ? ? ? [peripheral setNotifyValue:YESforCharacteristic:characteristic];//監聽這個服務發來的數據[peripheral readValueForCharacteristic:characteristic];//主動去讀取這個服務發來的數據}if([characteristic.UUIDisEqual:[CBUUID UUIDWithString:@"6E400002-B5A3-F393-E0A9-E50E24DCCA9E"]]) {? ? ? ? ? ? _writeCharacteristic = characteristic;? ? ? ? }if([characteristic.UUIDisEqual:[CBUUID UUIDWithString:@"6E400001-B5A3-F393-E0A9-E50E24DCCA9E"]]) {//? ? ? ? ? ? [peripheral setNotifyValue:YES forCharacteristic:characteristic];//監聽這個服務發來的數據//? ? ? ? ? ? [peripheral readValueForCharacteristic:characteristic];//主動去讀取這個服務發來的數據}? ? }}// 獲取characteristic的值- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullableNSError*)error{? ? NSData * data = characteristic.value;? ? Byte * resultByte = (Byte *)[data bytes];for(inti=0;i<[data length];i++){? ? ? ? printf("testByteFF02[%d] = %d\n",i,resultByte[i]);}//打印出characteristic的UUID和值//!注意,value的類型是NSData,具體開發時,會根據外設協議制定的方式去解析數據if([characteristic.UUIDisEqual:[CBUUID UUIDWithString:@"6E400003-B5A3-F393-E0A9-E50E24DCCA9E"]]) {? ? ? ? Byte *databyte = (Byte *)[characteristic.valuebytes];for(inti =0; i<[characteristic.valuelength]; i++) {NSLog(@"收到3藍牙發來的數據? %d",databyte[i]);? ? ? ? }//? ? ? ? NSString * string = [NSString hexadecimalString:characteristic.value];NSLog(@"----------%@",characteristic.value);//在這里解析收到的數據,一般是data類型的數據,這里要根據藍牙廠商提供的協議進行解析并且配合LightBlue來查看數據結構,我當時收到的數據是十六進制的數據但是是data類型,所以我先講data解析出來之后轉為十進制來使用。具體方法后面我會貼出//還有一點收到數據后有的硬件是需要應答的,如果應答的話就是在這里再給藍牙發一個指令(寫數據):“我收到發的東西了,你那邊要做什么操作可以做了”。}if([characteristic.UUIDisEqual:[CBUUID UUIDWithString:@"6E400001-B5A3-F393-E0A9-E50E24DCCA9E"]]) {? ? ? ? Byte *databyte = (Byte *)[characteristic.valuebytes];for(inti =0; i<[characteristic.valuelength]; i++) {NSLog(@"收到1藍牙發來的數據? %d",databyte[i]);? ? ? ? }NSString* string = [NSStringhexadecimalString:characteristic.value];NSLog(@"----------%@",[NSStringstringFromHexString:string]);//在這里解析收到的數據,一般是data類型的數據,這里要根據藍牙廠商提供的協議進行解析并且配合LightBlue來查看數據結構,我當時收到的數據是十六進制的數據但是是data類型,所以我先講data解析出來之后轉為十進制來使用。具體方法后面我會貼出//還有一點收到數據后有的硬件是需要應答的,如果應答的話就是在這里再給藍牙發一個指令(寫數據):“我收到發的東西了,你那邊要做什么操作可以做了”。}if([characteristic.UUIDisEqual:[CBUUID UUIDWithString:@"6E400002-B5A3-F393-E0A9-E50E24DCCA9E"]]) {? ? ? ? Byte *databyte = (Byte *)[characteristic.valuebytes];for(inti =0; i<[characteristic.valuelength]; i++) {NSLog(@"收到2藍牙發來的數據? %d",databyte[i]);? ? ? ? }//在這里解析收到的數據,一般是data類型的數據,這里要根據藍牙廠商提供的協議進行解析并且配合LightBlue來查看數據結構,我當時收到的數據是十六進制的數據但是是data類型,所以我先講data解析出來之后轉為十進制來使用。具體方法后面我會貼出//還有一點收到數據后有的硬件是需要應答的,如果應答的話就是在這里再給藍牙發一個指令(寫數據):“我收到發的東西了,你那邊要做什么操作可以做了”。}NSString*dataStr = [[NSStringalloc]initWithData:characteristic.valueencoding:NSUTF8StringEncoding];NSLog(@"%s, line = %d, characteristic.UUID:%@? value:%@", __FUNCTION__, __LINE__, characteristic.UUID, dataStr);}// 獲取Characteristics的 descriptor的值- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(nonnull CBDescriptor *)descriptor error:(nullableNSError*)error{//打印出DescriptorsUUID 和value//這個descriptor都是對于characteristic的描述,一般都是字符串,所以這里我們轉換成字符串去解析NSString*dataStr = [[NSStringalloc]initWithData:descriptor.valueencoding:NSUTF8StringEncoding];NSLog(@"%s, line = %d, characteristic.UUID:%@? value:%@", __FUNCTION__, __LINE__, descriptor.UUID, dataStr);}// 發現特征Characteristics的描述Descriptor- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullableNSError*)error{NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);for(CBDescriptor *descriptor in characteristic.descriptors) {NSLog(@"descriptor.UUID:%@",descriptor.UUID);? ? }}// 5.外設寫數據到特征中// 需要注意的是特征的屬性是否支持寫數據- (void)sl_peripheral:(CBPeripheral *)peripheral didWriteData:(NSData *)data forCharacteristic:(nonnull CBCharacteristic *)characteristic{/*
typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {
CBCharacteristicPropertyBroadcast? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x01,
CBCharacteristicPropertyRead? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x02,
CBCharacteristicPropertyWriteWithoutResponse? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x04,
CBCharacteristicPropertyWrite? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x08,
CBCharacteristicPropertyNotify? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x10,
CBCharacteristicPropertyIndicate? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x20,
CBCharacteristicPropertyAuthenticatedSignedWrites? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x40,
CBCharacteristicPropertyExtendedProperties? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = 0x80,
CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)? ? ? ? = 0x100,
CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)? = 0x200
};
打印出特征的權限(characteristic.properties),可以看到有很多種,這是一個NS_OPTIONS的枚舉,可以是多個值
常見的又read,write,noitfy,indicate.知道這幾個基本夠用了,前倆是讀寫權限,后倆都是通知,倆不同的通知方式
*/NSLog(@"%s, line = %d, char.pro = %d", __FUNCTION__, __LINE__, characteristic.properties);// 此時由于枚舉屬性是NS_OPTIONS,所以一個枚舉可能對應多個類型,所以判斷不能用 = ,而應該用包含&if(characteristic.properties& CBCharacteristicPropertyWrite) {// 核心代碼在這里[peripheral writeValue:data// 寫入的數據forCharacteristic:characteristic// 寫給哪個特征type:CBCharacteristicWriteWithResponse];// 通過此響應記錄是否成功寫入}}// 6.通知的訂閱和取消訂閱// 實際核心代碼是一個方法// 一般這兩個方法要根據產品需求來確定寫在何處- (void)sl_peripheral:(CBPeripheral *)peripheral regNotifyWithCharacteristic:(nonnull CBCharacteristic *)characteristic{// 外設為特征訂閱通知 數據會進入 peripheral:didUpdateValueForCharacteristic:error:方法[peripheral setNotifyValue:YESforCharacteristic:characteristic];}- (void)sl_peripheral:(CBPeripheral *)peripheral CancleRegNotifyWithCharacteristic:(nonnull CBCharacteristic *)characteristic{// 外設取消訂閱通知 數據會進入 peripheral:didUpdateValueForCharacteristic:error:方法[peripheral setNotifyValue:NOforCharacteristic:characteristic];}// 7.斷開連接- (void)sl_dismissConentedWithPeripheral:(CBPeripheral *)peripheral{// 停止掃描[self.cMgrstopScan];// 斷開連接[self.cMgrcancelPeripheralConnection:peripheral];}- (IBAction)sendMessageToBan:(id)sender {//crc //unsignedchardata0 [5]= {0};? ? data0[0] =0x6;? ? *(data0+1) =0x0;? ? *(data0+2) =0x10;? ? *(data0+3) =0x0;? ? *(data0+4) =0x0;? ? uint16_t bb = bd_crc16(0,data0,sizeof(data0));NSLog(@"收到1藍牙發來的數據%d",bb);unsignedchardata [13]= {0};? ? data[0] =0xab;? ? *(data+1) =0x0;? ? *(data+2) =0x0;? ? *(data+3) =0x5;? ? *(data+4) =0xc5;? ? *(data+5) =0x89;? ? *(data+6) =0x0;? ? *(data+7) =0x1e;? ? *(data+8) =0x6;? ? *(data+9) =0x0;? ? *(data+10) =0x10;? ? *(data+11) =0x0;? ? *(data+12) =0x0;//? ? *(data+5) = 0x0;NSData *data1 = [NSData dataWithBytes:data length:sizeof(data)];if(_peripheral.state== CBPeripheralStateConnected) {? ? ? ? [_peripheral writeValue:data1 forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithResponse];? ? }}//用于檢測中心向外設寫數據是否成功-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError*)error{if(error) {NSLog(@"發送數據失敗=======%@",error.userInfo);? ? }else{//馬達接口//ab? 0? 0? 5? 5 d8? 0 50? 6? 0 11? 0? 0unsignedchardata [13]= {0};//Magic byte,有 效值為 0XABdata[0] =0xab;//Reserve 2 bits ERR flag Ack flag Version*(data+1) =0x0;//Payload length*(data+2) =0x0;//*(data+3) =0x5;//CRC16*(data+4) =0x1;//*(data+5) =0x68;//Sequence id*(data+6) =0x0;? ? ? ? *(data+7) =0x3c;//*(data+8) =0x6;//*(data+9) =0x0;//*(data+10) =0x6;//*(data+11) =0x0;//*(data+12) =0x0;//? ? *(data+5) = 0x0;NSData *data1 = [NSData dataWithBytes:data length:sizeof(data)];if(_peripheral.state== CBPeripheralStateConnected) {? ? ? ? ? ? [_peripheral writeValue:data1 forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithResponse];? ? ? ? }NSLog(@"發送數據成功");? ? }? ? [peripheral readValueForCharacteristic:characteristic];}-(NSData *)hexString:(NSString*)hexString {intj=0;? ? Byte bytes[20];///3ds key的Byte 數組, 128位for(inti=0; i<[hexString length]; i++)? ? {intint_ch;/// 兩位16進制數轉化后的10進制數unicharhex_char1 = [hexString characterAtIndex:i];////兩位16進制數中的第一位(高位*16)intint_ch1;if(hex_char1 >='0'&& hex_char1 <='9')? ? ? ? ? ? int_ch1 = (hex_char1-48)*16;//// 0 的Ascll - 48elseif(hex_char1 >='A'&& hex_char1 <='F')? ? ? ? ? ? int_ch1 = (hex_char1-55)*16;//// A 的Ascll - 65elseint_ch1 = (hex_char1-87)*16;//// a 的Ascll - 97i++;unicharhex_char2 = [hexString characterAtIndex:i];///兩位16進制數中的第二位(低位)intint_ch2;if(hex_char2 >='0'&& hex_char2 <='9')? ? ? ? ? ? int_ch2 = (hex_char2-48);//// 0 的Ascll - 48elseif(hex_char1 >='A'&& hex_char1 <='F')? ? ? ? ? ? int_ch2 = hex_char2-55;//// A 的Ascll - 65elseint_ch2 = hex_char2-87;//// a 的Ascll - 97int_ch = int_ch1+int_ch2;NSLog(@"int_ch=%d",int_ch);? ? ? ? bytes[j] = int_ch;///將轉化后的數放入Byte數組里j++;? ? }? ? NSData *newData = [[NSData alloc] initWithBytes:bytes length:20];returnnewData;}//停止手環振動- (IBAction)stopShake:(id)sender {unsignedchardata [13]= {0};? ? data[0] =0xab;? ? *(data+1) =0x0;? ? *(data+2) =0x0;? ? *(data+3) =0x5;? ? *(data+4) =0x5;? ? *(data+5) =0xd8;? ? *(data+6) =0x0;? ? *(data+7) =0x50;? ? *(data+8) =0x6;? ? *(data+9) =0x0;? ? *(data+10) =0x11;? ? *(data+11) =0x0;? ? *(data+12) =0x0;//? ? *(data+5) = 0x0;NSData *data1 = [NSData dataWithBytes:data length:sizeof(data)];if(_peripheral.state== CBPeripheralStateConnected) {? ? ? ? [_peripheral writeValue:data1 forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithResponse];? ? }}staticinlineuint16_t crc16_byte(uint16_t crc,constuint8_t data){return(crc >>8) ^ crc16_table[(crc ^ data) &0xff];}/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */uint16_tconstcrc16_table[256] ={0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040};/**
* crc16 - compute the CRC-16 for the data buffer
* @crc: previous CRC value 之前的crc值
* @buffer: data pointer data指針
* @len: number of bytes in the buffer 字節數
*
* Returns the updated CRC value.
*/uint16_t bd_crc16(uint16_t crc, uint8_tconst*buffer, uint16_t len){while(len--)? ? crc = crc16_byte(crc, *buffer++);returncrc;}@end