基于 移远 BC26 移柯BL620的NB模块调试流程
NB模块连接网络顺序
移柯NBL260模块
NB卡: 联通 默认波特率 115200
//UDP 链接方式:
AT //判断模组是否上电开机成功
AT+CIMI //读取 IMSI, 判断 SIM 卡初始化是否成功
AT+CESQ 检查信号质量
AT+CEREG? //判断 PS 域附着(是否注册网络)状态,标识位返回 1 或 5 表示附着正常
AT+CIPMUX=0 //切换到单个链接
AT+CIPSTART="UDP","101.95.153.110",60110 // 配置服务器及上产方式
AT+QLWOPEN=0 // 连接网络
AT+CIPSEND =5 //固定发送数据长度位5(长度大小可自由设定)
12345 //直接上传数据
AT+CIPRXGET=1,100 // get data
移远NB BC26模块
链接移远平台(COAP协议)
NB卡: 联通 默认波特率 115200
手动检查:
AT //同步波特率直到回复OK
AT+CIMI //读取 IMSI, 判断 SIM 卡初始化是否成功
AT+CESQ //检查信号质量 推荐15 -31
AT+CFUN? //是否返回1 检查 UE的功能等级 1代表全部功能
AT+CEREG? 返回0,1表示入网成功,0,0 0,2正在找网 300S
AT+CGPADDR=1 检查IP
AT+CGSN=1 // 获取IMEI号码 在绑定平台的时候需要发送IMEI号
自动检查部分:
URC:
+CPIN: READY
+IP:XXXXXXX
//网络,格式配置
AT+NCDP=southbound.quectel.com,5683 //设置服务器端口和 地址
AT+QLWCONF="IMEI" 例如: AT+QLWCONF="866971033147948"
AT+QLWADDOBJ=19,1,1,"0" //配置:LWM2M
AT+QLWADDOBJ=19,0,1, "0" //配置1:LWM2M
AT+QLWOPEN=0 //Register to the IoT platform in direct push mode
AT+QLWCFG="dataformat",1,1 //Configure hex string mode for sending and received data.
AT+QLWDATASEND=19,0,0,2,3132,0x0100 . //send data 1和2 datalength 2 CON数据
AT+SM=LOCK指令来阻止模块进入PSM //调试的时候可以使用到
说明: 模块上电启动会自动连接网络,若模块返回+CPIN: READY 说明模块本身的基本配置已经完成,返回+IP:XXXXXXX,表示模块已经自动联网。若自动联网即可直接进入网络配置一块,后即可发送数据。具体案例最下图所示。
移远NB 广州联通平台
https://device1-portal.10646.cn
user = "dyson.zhang@whoareyou.live";
password = "way123!@#";
coAP接入方式LwM2M链接
AT
AT+CESQ
AT+CFUN?
AT+CEREG?
AT+CGPADDR=1
AT+QLWSERV="device1-api.10646.cn",5683 等价 AT+NCDP=device1-api.10646.cn,5683
AT+QLWCONF="866971033147948"
AT+QLWADDOBJ=19,1,1,"0"
AT+QLWADDOBJ=19,0,1,"0"
AT+QLWOPEN=0
AT+QLWCFG="dataformat",1,1
AT+QLWDATASEND=19,0,0,2,3132,0x0100 // con数据
注意事项:模块开机后会自动调整工作模式,不需额外干预,若一段时间不操作,模块会自进入PSM模式。如想再次操作,需从PSM唤醒。
AT指令发送时需要回车键
include "App_Main.h"
#include "NBIot_BC26.h"
#include "Drv_Usart.h"
#include "fifo.h"static void StartingUp(void);extern char gaucUsart1Buff[RXBUFSIZE];char *gcBC26CmdBuff=0 ; // 存放BN26模块返回的状态指令void NB_BC26_init(void){// NB Vcc GPIO_SetMode(NB_VCCPort, NB_VCCPin, GPIO_MODE_OUTPUT);GPIO_SetMode(PWRKEY_Port, PWRKEY_Pin, GPIO_MODE_OUTPUT);GPIO_SetMode(PSM_EINT_port, PSM_EINT_pin, GPIO_MODE_OUTPUT);GPIO_SetMode(Reset_Port, Reset_Pin, GPIO_MODE_OUTPUT);NB_VCCEN;Reset_Disable;
// Reset_BC26();Drv_SysDelayMs(50);StartingUp();// PSM_wake();}// 从psm 唤醒static void PSM_wake(void){PSM_EINT_Disable;Drv_SysDelayMs(10);PSM_EINT_EN;Drv_SysDelayMs(5);PSM_EINT_Disable;}//上电启动static void StartingUp(void){PWRKEY_Disable;Drv_SysDelayMs(10);PWRKEY_EN; Drv_SysDelayMs(800);PWRKEY_Disable;}//断电关机void Shutdown(void){NB_VCCDisable;}
// reset void Reset_BC26(void){Reset_Disable;Drv_SysDelayMs(10);Reset_EN;Drv_SysDelayMs(100);Reset_Disable;}/*发送 AT 指令给NBiot返回: 1 代表成功 0 代表失败 */uint8_t Send_AT_CMD(UART_T* uart,uint8_t *cmdBuffer){uint8_t utReturn = 0;while(*cmdBuffer != '\0'){utReturn = UART_Write(uart,cmdBuffer++,1);}return utReturn;}/* function : 判断返回数据@param :*String: 接受到的与之对比的命令*InBuffer: 输入的数据缓存(IN)* OutBuffer : 在InBuffer 中截取的String及以后的数据ucLen 对比之后首次出现是首地址*/
extern volatile uint32_t gudComRFlag;
extern uint8_t guRX_num;char *RX_BC26_CMD(char *InBuffer,char *String)
{char *INdex=0;INdex = strstr(InBuffer,String);return INdex;
}/* function : 发送指令@param :uart 串口号cmd 发送命令*String: 接受到的与之对比的预知命令waittime : 超时时间Index_location 对比之后首次出现是首地址
return : sucess or fail*/
uint8_t BC26_send_cmd(UART_T* uart,uint8_t *cmd,char *String,char **Index_location,uint16_t waittime)
{uint8_t res = TA_FAIL; guRX_num =0;memset(gaucUsart1Buff,0,sizeof(gaucUsart1Buff));Send_AT_CMD(uart,cmd); //发送出去命令Drv_SysDelayMs(300);while(waittime--){ Drv_SysDelayMs(20);//串口在一个字节一个字节的接收,这块每接收一个字节就检测接收到的整个数据是否符合要求if(gudComRFlag) //收到数据,检查数据是否是想要的{ *Index_location = RX_BC26_CMD(gaucUsart1Buff,String);if( RX_BC26_CMD(gaucUsart1Buff,String)){res = TA_SUCCESS;break; //是想要的,发送结束,跳出}gudComRFlag=0; } }return res;}/*function: BC26模块上电自检 return : sucess or fail*/
//uint8_t Power_ONCheckself(void)
//{
// uint32_t Time_out = 0;
// //NB_BC26_init();
// while(RX_BC26_CMD(gaucUsart1Buff,"Leaving"))
// {
// memset(gaucUsart1Buff,0,sizeof(gaucUsart1Buff));
// return TA_SUCCESS;
// }
// else
// {
// Shutdown();
// Drv_SysDelayMs(10);
// NB_BC26_init();
// if(TA_SUCCESS == RX_BC26_CMD(gaucUsart1Buff,"Leaving"))
// {
// memset(gaucUsart1Buff,0,sizeof(gaucUsart1Buff));
// return TA_SUCCESS;
// }
// else
// {
// return TA_FAIL;
// }
// }
//
//}
//将普通字符串转化成Hex字符串
uint8_t str2hex(char* str, char* hex)
{const char* cHex = "0123456789ABCDEF";int i=0,j=0;for( j =0; j < strlen(str); j++){unsigned int a = (unsigned int) str[j];hex[i++] = cHex[(a & 0xf0) >> 4];hex[i++] = cHex[(a & 0x0f)];}hex[i] ='\0';return i;
}
//NBiot模块上网流程
uint8_t BC26_DataProcess(uint8_t *NB_buffer,uint8_t NB_Length)
{ uint32_t time_out = 5; uint8_t Signal_Strength = 0;uint8_t Statue = NB_Start;uint16_t Hex_Data_Length = 0;uint8_t New_Satrt_count = 3 ; //启动的次数uint8_t Hex_buffer[100]={0}; // 存储转化为hex的数据char *Data_Location =0;char *AT_cmd1= 0; // 存储 AD—cmdchar *AT_cmd2= 0;// if(TA_SUCCESS != Power_ONCheckself())// 自检失败,直接退出
// {
// return TA_FAIL;
// }while(1){ if(0 == New_Satrt_count)return TA_FAIL;switch(Statue){case NB_Start:time_out = 40;// NB_VCCDisable;Drv_SysDelayMs(1000);NB_BC26_init();while(time_out--){if( RX_BC26_CMD(gaucUsart1Buff,"Leaving"))break;Drv_SysDelayMs(10);}Statue = AT;break;case AT: //同步波特率time_out=4;while(time_out--) {if(TA_SUCCESS == BC26_send_cmd(UART1,"AT\r\n","OK",&Data_Location,100)) // 超时时间2S{break;}if( RX_BC26_CMD(gaucUsart1Buff,"+CPIN: READY"))break;if(time_out<2) // 若失败两次,则重启模块{Statue = NB_Start;New_Satrt_count--;break;}}if(RX_BC26_CMD(gaucUsart1Buff,"+IP:")){Statue = AT_NCDP;break;}else{Statue = AT_CESQ;break;}case AT_CESQ: // 检查信号强度time_out =50;while(time_out--){ if( RX_BC26_CMD(gaucUsart1Buff,"+CPIN: READY")){break;}Drv_SysDelayMs(100);} time_out = 3;while(time_out--) { if(RX_BC26_CMD(gaucUsart1Buff,"+IP:")){Statue = AT_NCDP;break;} if(TA_SUCCESS == BC26_send_cmd(UART1,"AT+CESQ\r\n","+CESQ: ",&Data_Location,100)) // 超时时间2S{Signal_Strength = 10*(*(Data_Location+7) - 48) + (*(Data_Location+8) - 48);if(((*(Data_Location+7) - 48) == 0) || ((*(Data_Location+7) - 48) == 9)){New_Satrt_count--;Statue = NB_Start;break;}else{Statue = AT_CFUN;break;}}if(time_out<2){Statue = NB_Start;New_Satrt_count--;break;}}break;case AT_CFUN: // 检查UE功能等级 最长15S time_out = 2; while(time_out--) {if(RX_BC26_CMD(gaucUsart1Buff,"+IP:")){Statue = AT_NCDP;break;}if(TA_SUCCESS == BC26_send_cmd(UART1,"AT+CFUN?\r\n","+CFUN: ",&Data_Location,750)) // 超时时间15S{Signal_Strength = (*(Data_Location+7) - 48);if((Signal_Strength != 1)){continue;}else{Statue = AT_CEREG;break;}}else{PSM_wake();}if(time_out<1){Statue = NB_Start;New_Satrt_count--;break;;}}break;case AT_CEREG: // 检查是否入网成功time_out = 3;while(time_out--) {if(RX_BC26_CMD(gaucUsart1Buff,"+IP: ")){Statue = AT_NCDP;break;}if(TA_SUCCESS == BC26_send_cmd(UART1,"AT+CEREG?\r\n","+CEREG: ",&Data_Location,400)) // 超时时间2S{ if(*(Data_Location+10) == '1')// join in internet sucess{Statue = AT_CGPADDR;break;}else if((*(Data_Location+10) == '2') || (*(Data_Location+10) == '0') ) //looking for internet{Drv_SysDelayMs(500);}}if(time_out<2){Statue = NB_Start;New_Satrt_count--;break;}}break;case AT_CGPADDR: // Get IP adresstime_out = 3;while(time_out--) {if(TA_SUCCESS == BC26_send_cmd(UART1,"AT+CGPADDR=1\r\n","+CGPADDR: 1",&Data_Location,100)) // 超时时间2S{Statue = AT_NCDP; break;}if(time_out<2){Statue = NB_Start;New_Satrt_count--;break;}}break;// case AT_CGSN: // get IMEI case AT_NCDP: // configure network adress// Drv_SysDelayMs(7000); time_out = 2;while(time_out--){ if (TA_SUCCESS == BC26_send_cmd(UART1,"AT+NCDP=southbound.quectel.com,5683\r\n","OK",&Data_Location,100)) // 超时时间2S{Statue = AT_QLWCONF; break;}else{if(time_out<1){Statue = NB_Start;New_Satrt_count--;break;}}}break;case AT_QLWCONF: // 配置设备的IMEItime_out = 2;AT_cmd1 = "AT+QLWCONF=";AT_cmd2 = "866971033234043";memset(Hex_buffer,0,sizeof(Hex_buffer));Hex_Data_Length = Cmd_connect(AT_cmd1,AT_cmd2,Hex_buffer,11,15);Hex_buffer[Hex_Data_Length] = 0x0D;Hex_buffer[Hex_Data_Length+1] = 0x0A;// UART_Write(UART1,QLWCONF_buffer,sizeof(QLWCONF_buffer)); //发送出去命令while(time_out--){ if (TA_SUCCESS == BC26_send_cmd(UART1,Hex_buffer,"OK",&Data_Location,100)) // 超时时间2S{Statue = AT_QLWADDOBJ;break;}else{if(time_out<1){Statue = NB_Start;New_Satrt_count--;break;}}} break;case AT_QLWADDOBJ: // 配置1time_out = 2;AT_cmd1 = "AT+QLWADDOBJ=19,1,1,";AT_cmd2 = "0";memset(Hex_buffer,0,sizeof(Hex_buffer));Hex_Data_Length = Cmd_connect(AT_cmd1,AT_cmd2,Hex_buffer,20,1);Hex_buffer[Hex_Data_Length]= 0x0D; //回车 Hex_buffer[Hex_Data_Length+1] = 0x0A;while(time_out--){ if (TA_SUCCESS == BC26_send_cmd(UART1,Hex_buffer,"OK",&Data_Location,100)) // 超时时间2S{Statue = AT_QLWADDOBJ1;break;}else{if(time_out<1){Statue = NB_Start;New_Satrt_count--;break;}}}break;case AT_QLWADDOBJ1: // 配置2time_out = 2;AT_cmd1 = "AT+QLWADDOBJ=19,0,1,";AT_cmd2 = "0";memset(Hex_buffer,0,sizeof(Hex_buffer));Hex_Data_Length = Cmd_connect(AT_cmd1,AT_cmd2,Hex_buffer,20,1);Hex_buffer[Hex_Data_Length]= 0x0D; //回车while(time_out--){ if (TA_SUCCESS == BC26_send_cmd(UART1,Hex_buffer,"OK",&Data_Location,100)) // 超时时间2S{Statue = AT_QLWOPEN;break;}else{if(time_out<1){Statue = NB_Start;New_Satrt_count--;break;}}}break;case AT_QLWOPEN: // Register to the IoT platform in direct push modetime_out = 2;while(time_out--){ if (TA_SUCCESS == BC26_send_cmd(UART1,"AT+QLWOPEN=0\r\n","+QLWOBSERVE:",&Data_Location,300)) // 超时时间6S{break;}else{if(time_out<1){return TA_FAIL;}}}Statue = AT_QLWCFG; // 16进制break;case AT_QLWCFG:time_out = 2;AT_cmd1 = "AT+QLWCFG=";AT_cmd2 = "dataformat";memset(Hex_buffer,0,sizeof(Hex_buffer));Hex_Data_Length = Cmd_connect(AT_cmd1,AT_cmd2,Hex_buffer,10,10);Hex_buffer[Hex_Data_Length] = 0x2c; //,Hex_buffer[Hex_Data_Length+1] = 0x31; //1Hex_buffer[Hex_Data_Length+2] = 0x2c;//,Hex_buffer[Hex_Data_Length+3] = 0x31; //1Hex_buffer[Hex_Data_Length+4]= 0x0D; //回车while(time_out--){ if (TA_SUCCESS == BC26_send_cmd(UART1,Hex_buffer,"OK",&Data_Location,100)) // 超时时间2S{Statue = AT_QLWDATASEND;break;}else{if(time_out<1){return TA_FAIL;}}}break;case AT_QLWDATASEND: // updatatime_out = 3;memset(Hex_buffer,0,sizeof(Hex_buffer)); Hex_Data_Length = NB_Settle_Data(Hex_buffer,NB_buffer,NB_Length);//数据整合Hex_buffer[Hex_Data_Length++] = 0x2c;//,Hex_buffer[Hex_Data_Length++] = 0x30;//0Hex_buffer[Hex_Data_Length++] = 0x78;//xHex_buffer[Hex_Data_Length++] = 0x30;//0Hex_buffer[Hex_Data_Length++] = 0x31;//1Hex_buffer[Hex_Data_Length++] = 0x30;//0Hex_buffer[Hex_Data_Length++] = 0x30;//0Hex_buffer[Hex_Data_Length++]= 0x0D; //回车Hex_buffer[Hex_Data_Length++] = 0x0A;while(time_out--){ //Drv_SysDelayMs(2000); if (TA_SUCCESS == BC26_send_cmd(UART1,Hex_buffer,"SEND OK",&Data_Location,200)) // 超时时间4S{return TA_SUCCESS;}else{if(time_out<1){return TA_FAIL;}}}}}
}
/*功能,整理数据成NB 可以识别的正常数据Outbuffer [OUT] 输出数据INbuf : 输入的 开门信息Len : 开门信息数据长度
*/
uint8_t NB_Settle_Data(uint8_t *Outbuffer,uint8_t *INbuf,uint8_t Len)
{uint16_t length0=0,i=0;char *AT_P = "AT+QLWDATASEND=19,0,0,";length0 = AT_Conversion_HEX(AT_P,Outbuffer,22);if(2*Len >9){Outbuffer[length0++] = (2*Len)/10 + 0x30;Outbuffer[length0++] = (2*Len)%10 + 0x30;}else{Outbuffer[length0++] = Len + 0x30;}Outbuffer[length0++] = 0x2c; //,// datafor(i=0;i<Len;i++){Outbuffer[length0++] = 0x33;
// if(INbuf[i]>9)
// {Outbuffer[length0++] = INbuf[i]/10+0x30;Outbuffer[length0++] = 0x33;Outbuffer[length0++] = INbuf[i]%10+0x30;
// }
// else
// Outbuffer[length0++] = INbuf[i]%10+0x30;}return length0;
}/* function: AT TO Hex@param IN_buffer AT_cmd (IN)length the length of IN_bufferOutbuffer Hex (out)*/
uint16_t AT_Conversion_HEX(char *IN_buffer,uint8_t *Outbuffer,uint16_t length)
{char temp=0;uint16_t i=0;uint16_t Cmd_length = 0;Cmd_length = length ;while(Cmd_length--){Outbuffer[i]= IN_buffer[i];i++;}return i;
}
/*链接两个CMD
@param:*IN_buffer1 【IN】 cmd 1*IN_buffer2 【IN】 cmd 2*Outbuffer 【out】 输出 hex length1 [IN] IN_buffer1 lengthlength2 [IN] IN_buffer2 length*/
uint16_t Cmd_connect(char *IN_buffer1,char *IN_buffer2,uint8_t *Outbuffer,uint16_t length1,uint16_t lengt2)
{uint16_t len1 = 0;uint16_t len2 = 0;len1 = AT_Conversion_HEX(IN_buffer1,Outbuffer,length1);len2 = AT_Conversion_HEX(IN_buffer2, Outbuffer + len1+1 ,lengt2);Outbuffer[len1] =0x22;Outbuffer[len1+len2+1] = 0x22;return (len1+len2+2);
}
基于 移远 BC26 移柯BL620的NB模块调试流程相关推荐
- 大白NBIOT 移远BC26模块模组OpenCpu开发视频教程(有连接移动、电信平台的opencpu源码)
NBIOT(BC26.BC28,BC35)模块 移远BC26全网通模组OpenCpu实现TCPCLient网络数据传输 [复制链接] http://www.openedv.com/forum.ph ...
- NB-IoT模块 移远BC26接入OneNET
NB-IoT模块 移远BC26接入OneNET 1.OneNET接入流程图 OneNET平台接入分为平台端接入和设备端接入. 2.OneNET平台创建NB-IoT设备 这里IMEI及IMSI是BC26 ...
- NB-IoT低功耗芯片:国产新秀移芯EC616,能挑战联发科MT2625吗?来看看使用低功耗分析仪做的对比功耗评测,评测对象:采用移远BC26和BC260Y模块开发板。
国产NB-IoT芯片EC616,官宣NB超低功耗,能挑战联发科老牌MT2625这款NB芯片吗?本文使用功耗分析仪作为测试仪器,来看看在DRX模式下的功耗评测对比情况. 测试条件: 1.使用中国电信NB ...
- QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之02【EC20模组硬件供电和开关机复位操作】
QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之02[EC20模组硬件供电和开关机复位操作] 一.模组硬件知识 1.背景知识:网络制式 2.模组的供电 3.模组的开机 4 ...
- QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之04【EC20模组SIM卡和驻网模组指令说明】
QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之04[EC20模组SIM卡和驻网模组指令说明] 一.准备工作 二.硬件环境的搭建 三.基础AT指令的说明和测试 关于SIM ...
- QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之05【EC20模组TCP/IP模块AT指令说明】
QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之05[EC20模组TCP/IP模块AT指令说明] Socket长连接 一.准备工作 二.针对TCP/IP协议 关于TCP/ ...
- QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之03【EC20模组基础串口指令说明】
QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之03[EC20模组基础串口指令说明] 一.准备工作 二.硬件环境的搭建 三.基础AT指令的说明和测试 STM32F103学 ...
- 移远BC26/BC28(略)/MC20开发之环境搭建 一
1.对于常见的移远OPENCPU开发来说,第一步安装GCC编译器 2.第二步,安装一个集成编译环境,常见的是keil编译环境 3.环境的配置(仅 BC28) 4.最后检查环境是否搭建好 BC28,命令 ...
- QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之02EC20模组硬件供电和开关机复位操作
本系列博文将系统性讲解物联网模组系列的实际使用和调试指南,以移远4G模组EC20为例(其他厂家模组的调试方法大同小异),加快嵌入式软.硬件工程师对物联网模组调试和使用的上手速度. 一.模组硬件知识 1 ...
最新文章
- tf.keras.layers.MaxPool2D 示例 池化层
- tomcat 配置 使用 HTTPS
- c语言打开文件出现分段故障,我不明白为什么我使用ifstream时出现分段错误
- audio 上一首 下一首 自定义样式_我们的歌:盛典即将来临,勤深深还有一首歌,这场表演值得期待...
- Elasticsearch,Kibana,Logstash,NLog实现ASP.NET Core 分布式日志系统
- 蓝桥杯 每周一练 第一周(3n+1问题)
- 马云卸任CEO演讲全文:明天起生活将是我的工作
- CentOS6.5安装与配置Mysql数据库
- 入职地府后我成了人生赢家_拿年终奖前跳槽,你才是赢家
- php memcache 有效期,PHP可以拿到memcache中的key的过期时间吗?
- html博客网页代码_Python自动化运维系列:Django搭建个人博客之前端篇
- Winxp 中文版 使用 IDM,补丁
- 日期操作工具2:DateUtil
- 解除谷歌浏览器默认禁止音频自动播放
- 【电脑控制手机屏幕】windows11、10自带投屏功能,三步解决
- 坑多路难走,学数据分析转行前要知道培训机构不会说的事情
- c语言实验报告总结周信东,周信东主编c语言程序设计基础实验一实验报告精选版.docx...
- PKUWC2019 总结
- mysql ndb存储引擎_Cluster的NDB存储引擎
- 如何实现1080P延迟低于500ms的实时超清直播传输技术
热门文章
- .NET Core 2.2 IIS网站出现HTTP503无法访问解决方法
- ToG产品_产品白皮书框架_2019_003
- STM32 USB VCOM和HID的区别,配置及Echo功能实现(HAL)
- 微信小程序《沈航二手书》
- Apple ID 登录
- 计算机女学霸,邹楚杭:计算机学院走出来的才女学霸
- 华科计算机专硕英语几,2020华中科技大学计算机专硕考研成功经验谈
- 如何在项目中利用 git 提高工作效率
- 《期权、期货及其他衍生产品》读书笔记(第九章:价值调节量)
- CMDN Club #19: Windows 8 Dev BootCamp - Win8开发知识与产品实践