nRF52832 — 外部中断BSP(Board Support Package)

2023-11-08

原文链接:http://blog.csdn.net/a369000753/article/details/51312839(转载文章,若有不妥,通知后我会立即删除)

首先来分析下主要的代码

[cpp]  view plain  copy
  1. /**@brief Function for application main entry. 
  2.  */  
  3. int main(void)  
  4. {  
  5.     uint32_t err_code;  
  6.     bool erase_bonds;  
  7.   
  8.     // Initialize.  
  9.     app_trace_init();  
  10.     timers_init();      buttons_leds_init(&erase_bonds); //按键函数初始化  
  11.     ble_stack_init();  
  12.     device_manager_init(erase_bonds);  
  13.     gap_params_init();  
  14.     advertising_init();  
  15.     services_init();  
  16.     sensor_simulator_init();  
  17.     conn_params_init();  
  18.   
  19.     // Start execution.  
  20.     application_timers_start();  
  21.     err_code = ble_advertising_start(BLE_ADV_MODE_FAST);  
  22.     APP_ERROR_CHECK(err_code);  
  23.   
  24.     // Enter main loop.  
  25.     for (;;)  
  26.     {  
  27.         power_manage();  
  28.     }  
  29. }  
[cpp]  view plain  copy
  1. /**@brief Function for initializing buttons and leds. 
  2.  * 
  3.  * @param[out] p_erase_bonds  Will be true if the clear bonding button was pressed to wake the application up. 
  4.  */  
  5. static void buttons_leds_init(bool * p_erase_bonds)  
  6. {  
  7.     bsp_event_t startup_event;  
  8.     //按键和灯初始化函数,APP_TIMER_TICKS(100, APP_TIMER_PRESCALER):消抖时间 bsp_event_handler:回调函数  
  9.     uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS,  
  10.                                  APP_TIMER_TICKS(100, APP_TIMER_PRESCALER),   
  11.                                  bsp_event_handler);  
  12.     APP_ERROR_CHECK(err_code);  
  13.   
  14.     err_code = bsp_btn_ble_init(NULL, &startup_event);  
  15.     APP_ERROR_CHECK(err_code);  
  16.   
  17.     *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);  
  18. }  
[cpp]  view plain  copy
  1. <pre name="code" class="cpp">uint32_t bsp_init(uint32_t type, uint32_t ticks_per_100ms, bsp_event_callback_t callback)  
  2. {  
  3.     uint32_t err_code = NRF_SUCCESS;  
  4. //判断是否定义了LEDS_UNMBER数量和 是否定义BSP_SIMPLE  
[cpp]  view plain  copy
  1. #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)  
  2.     m_app_ticks_per_100ms = ticks_per_100ms; //消抖动时间赋值  
  3.     m_indication_type     = type;//事件类型  
  4. #else  
  5.     UNUSED_VARIABLE(ticks_per_100ms);  
  6. #endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)  
  7. //判断是否定义了按键和是否定义BSP_SIMPLE  
  8. #if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)  
  9.     m_registered_callback = callback;//回调函数赋值 及bsp_event_handler  
  10.   
  11.     // BSP will support buttons and generate events  //判断是否按键事件  
  12.     if (type & BSP_INIT_BUTTONS)   {  
  13.         uint32_t num;  
  14.         //BUTTONS_NUMBER是定义了几个中断, 中断类型 回调函数初始化  
  15.         for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++)  
  16.         {  
  17.             err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT);  
  18.         }  
  19.   
  20.         if (err_code == NRF_SUCCESS)  
  21.         {    //app_buttons 中断表  BUTTONS_NUMBER:中断数目 ticks_per_100ms:消抖动时间  这里是初始化按键设置  
  22.             err_code = app_button_init((app_button_cfg_t *)app_buttons,  
  23.                                        BUTTONS_NUMBER,  
  24.                                        ticks_per_100ms / 2);  
  25.         }  
  26.   
  27.         if (err_code == NRF_SUCCESS)  
  28.         {  //使能中断  
  29.             err_code = app_button_enable();  
  30.         }  
  31.         if (err_code == NRF_SUCCESS)  
  32.         {  //建立m_button_timer_id事件  
  33.             err_code = app_timer_create(&m_button_timer_id,  
  34.                                         APP_TIMER_MODE_SINGLE_SHOT,  
  35.                                         button_timer_handler);  
  36.         }  
  37.     }  
  38. #elif (BUTTONS_NUMBER > 0) && (defined BSP_SIMPLE)  
  39.   
  40.     if (type & BSP_INIT_BUTTONS)  
  41.     {  
  42.         uint32_t cnt;  
  43.         uint32_t buttons[] = BUTTONS_LIST;  
  44.         for (cnt = 0; cnt < BUTTONS_NUMBER; cnt++)  
  45.         {  
  46.             nrf_gpio_cfg_input(buttons[cnt], BUTTON_PULL);  
  47.         }  
  48.     }  
  49. #endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)  
  50.   
  51. #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)  
  52.   
  53.     if (type & BSP_INIT_LED)  
  54.     {  
  55.         LEDS_OFF(LEDS_MASK);  
  56.         NRF_GPIO->DIRSET = LEDS_MASK;  
  57.     }  
  58.   
  59.     // timers module must be already initialized!  
  60.     if (err_code == NRF_SUCCESS)  
  61.     {  
  62.         err_code =  
  63.             app_timer_create(&m_leds_timer_id, APP_TIMER_MODE_SINGLE_SHOT, leds_timer_handler);  
  64.     }  
  65.   
  66.     if (err_code == NRF_SUCCESS)  
  67.     {  
  68.         err_code =  
  69.             app_timer_create(&m_alert_timer_id, APP_TIMER_MODE_REPEATED, alert_timer_handler);  
  70.     }  
  71. #endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)  
  72.   
  73.     return err_code;  
  74. }<span>   </span>  
[cpp]  view plain  copy
  1. <span style="font-family: Arial;">    </span>  
[cpp]  view plain  copy
  1. <span style="font-family: Arial;">                                        </span>  

 这里来分析下bsp_event_to_button_action_assign()函数,其中uint32_t button 是数组m_events_list的下标。可见如果在次初始化的时候可能把 event给改变。

[cpp]  view plain  copy
  1. #ifndef BSP_SIMPLE  
  2. /**@brief Assign specific event to button. 
  3.  */  
  4. uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event)  
  5. {  
  6.     uint32_t err_code = NRF_SUCCESS;  
  7.   
  8. #if BUTTONS_NUMBER > 0  
  9.     if (button < BUTTONS_NUMBER) //判断是否定义了按键  
  10.     {  
  11.         if (event == BSP_EVENT_DEFAULT) //判断事件是否BSP_EVENT_DEFAULT事件  
  12.         {  //找到定义的哪个按键的事件,  
  13.             // Setting default action: BSP_EVENT_KEY_x for PUSH actions, BSP_EVENT_NOTHING for RELEASE and LONG_PUSH actions.  
  14.             event = (action == BSP_BUTTON_ACTION_PUSH) ? (bsp_event_t)(BSP_EVENT_KEY_0 + button) : BSP_EVENT_NOTHING;  
  15.         }   
  16.         switch (action)  
  17.         {            case BSP_BUTTON_ACTION_PUSH:  
  18.                 m_events_list[button].push_event = event; //给m_events_list[button].push_event 赋值  
  19.                 break;  
  20.             case BSP_BUTTON_ACTION_LONG_PUSH:  
  21.                 m_events_list[button].long_push_event = event;  
  22.                 break;  
  23.             case BSP_BUTTON_ACTION_RELEASE:  
  24.                 m_events_list[button].release_event = event;  
  25.                 break;  
  26.             default:  
  27.                 err_code = NRF_ERROR_INVALID_PARAM;  
  28.                 break;  
  29.         }  
  30.     }  
  31.     else  
  32.     {  
  33.         err_code = NRF_ERROR_INVALID_PARAM;  
  34.     }  
  35. #else  
  36.     err_code = NRF_ERROR_INVALID_PARAM;  
  37. #endif // BUTTONS_NUMBER > 0  
  38.   
  39.     return err_code;  
  40. }  
  41.   
  42. #endif // BSP_SIMPLE  

为什么这里 event = (action == BSP_BUTTON_ACTION_PUSH) ? (bsp_event_t)(BSP_EVENT_KEY_0 + button) : BSP_EVENT_NOTHING;是这样 ,请看下面

[cpp]  view plain  copy
  1. typedef enum  
  2. {  
  3.     BSP_EVENT_NOTHING = 0,                  /**< Assign this event to an action to prevent the action from generating an event (disable the action). */  
  4.     BSP_EVENT_DEFAULT,                      /**< Assign this event to an action to assign the default event to the action. */  
  5.     BSP_EVENT_CLEAR_BONDING_DATA,           /**< Persistent bonding data should be erased. */  
  6.     BSP_EVENT_CLEAR_ALERT,                  /**< An alert should be cleared. */  
  7.     BSP_EVENT_DISCONNECT,                   /**< A link should be disconnected. */  
  8.     BSP_EVENT_ADVERTISING_START,            /**< The device should start advertising. */  
  9.     BSP_EVENT_ADVERTISING_STOP,             /**< The device should stop advertising. */  
  10.     BSP_EVENT_WHITELIST_OFF,                /**< The device should remove its advertising whitelist. */                                                       BSP_EVENT_BOND,                         /**< The device should bond to the currently connected peer. */   
  11.     BSP_EVENT_RESET,                        /**< The device should reset. */  
  12.     BSP_EVENT_SLEEP,                        /**< The device should enter sleep mode. */  
  13.     BSP_EVENT_WAKEUP,                       /**< The device should wake up from sleep mode. */  
  14.     BSP_EVENT_DFU,                          /**< The device should enter DFU mode. */  
  15.     BSP_EVENT_KEY_0,                        /**< Default event of the push action of BSP_BUTTON_0 (only if this button is present). */  
  16.     BSP_EVENT_KEY_1,                        /**< Default event of the push action of BSP_BUTTON_1 (only if this button is present). */  
  17.     BSP_EVENT_KEY_2,                        /**< Default event of the push action of BSP_BUTTON_2 (only if this button is present). */                        BSP_EVENT_KEY_3,                        /**< Default event of the push action of BSP_BUTTON_3 (only if this button is present). */  
  18.     BSP_EVENT_KEY_4,                        /**< Default event of the push action of BSP_BUTTON_4 (only if this button is present). */  
  19.     BSP_EVENT_KEY_5,                        /**< Default event of the push action of BSP_BUTTON_5 (only if this button is present). */  
  20.     BSP_EVENT_KEY_6,                        /**< Default event of the push action of BSP_BUTTON_6 (only if this button is present). */  
  21.     BSP_EVENT_KEY_7,                        /**< Default event of the push action of BSP_BUTTON_7 (only if this button is present). */  
  22.     BSP_EVENT_KEY_LAST = BSP_EVENT_KEY_7,  
  23. } bsp_event_t;  

这样就可以找到对应的小标 事件的case事件

上面既是给对应的长按,释放,短按事件赋值对应的事件。。同一个m_events_list只能同时有一个赋值。

  配置端口:

 app_button_init((app_button_cfg_t *)app_buttons,
                                       BUTTONS_NUMBER,
                                       ticks_per_100ms / 2);

BUTTONS_NUMBER:设置按键的个数,

ticks_per_100ms / 2 :消痘痘事件

app_buttons参数,游侠可见,需要配置哪个端口,低电平(false)还是高电平(ture)有效,管脚模式(上下拉等等),对应的回调函数

[cpp]  view plain  copy
  1. #ifndef BSP_SIMPLE  
  2. static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] =  
  3. {  
  4.     #ifdef BSP_BUTTON_0  
  5.     {BSP_BUTTON_0, false, BUTTON_PULL, bsp_button_event_handler},  
  6.     #endif // BUTTON_0  
  7.   
  8.     #ifdef BSP_BUTTON_1  
  9.     {BSP_BUTTON_1, false, BUTTON_PULL, bsp_button_event_handler},  
  10.     #endif // BUTTON_1  
  11.   
  12.     #ifdef BSP_BUTTON_2  
  13.     {BSP_BUTTON_2, false, BUTTON_PULL, bsp_button_event_handler},  
  14.     #endif // BUTTON_2  
  15.   
  16.     #ifdef BSP_BUTTON_3  
  17.     {BSP_BUTTON_3, false, BUTTON_PULL, bsp_button_event_handler},  
  18.     #endif // BUTTON_3  
  19.   
  20.     #ifdef BSP_BUTTON_4  
  21.     {BSP_BUTTON_4, false, BUTTON_PULL, bsp_button_event_handler},  
  22.     #endif // BUTTON_4  
  23.     #ifdef BSP_BUTTON_5  
  24.     {BSP_BUTTON_5, false, BUTTON_PULL, bsp_button_event_handler},  
  25.     #endif // BUTTON_5  
  26.   
  27.     #ifdef BSP_BUTTON_6  
  28.     {BSP_BUTTON_6, false, BUTTON_PULL, bsp_button_event_handler},  
  29.     #endif // BUTTON_6  
  30.   
  31.     #ifdef BSP_BUTTON_7  
  32.     {BSP_BUTTON_7, false, BUTTON_PULL, bsp_button_event_handler},  
  33.     #endif // BUTTON_7  
  34. };  
  35. #endif // BSP_SIMPLE  
  36. #endif // BUTTONS_NUMBER > 0  

 //创建一个按键事件,用于长按的时候计数,请查看下面长按事件,

  err_code = app_timer_create(&m_button_timer_id,
                                        APP_TIMER_MODE_SINGLE_SHOT,
                                        button_timer_handler);

每次中断来了就会跳到:

  void GPIOTE_IRQHandler(void) 中断入口函数,然后跳到

[cpp]  view plain  copy
  1. #if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)  
  2. /**@brief Function for handling button events. 
  3.  * 
  4.  * @param[in]   pin_no          The pin number of the button pressed. 
  5.  * @param[in]   button_action   Action button. 
  6.  */  
  7. static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action)  
  8. {  
  9.     bsp_event_t        event  = BSP_EVENT_NOTHING;  
  10.     uint32_t           button = 0;  
  11.     uint32_t           err_code;  
  12.     static uint8_t     current_long_push_pin_no;              /**< Pin number of a currently pushed button, that could become a long push if held long enough. */  
  13.     static bsp_event_t release_event_at_push[BUTTONS_NUMBER]; /**< Array of what the release event of each button was last time it was pushed, so that no release event is sent if the event was bound after the push of the button. */  
  14.   
  15.     while ((button < BUTTONS_NUMBER) && (m_buttons_list[button] != pin_no))  
  16.     {  
  17.         button++;  
  18.     }  
  19.   
  20.     if (button < BUTTONS_NUMBER)  
  21.     {  
  22.         switch(button_action)  
  23.         {  
  24.             case APP_BUTTON_PUSH:  
  25.                 event = m_events_list[button].push_event;  
  26.                 if (m_events_list[button].long_push_event != BSP_EVENT_NOTHING)  
  27.                 {  
  28.                     err_code = app_timer_start(m_button_timer_id, BSP_MS_TO_TICK(BSP_LONG_PUSH_TIMEOUT_MS), (void*)¤t_long_push_pin_no);  
  29.                     if (err_code == NRF_SUCCESS)  
  30.                     {  
  31.                         current_long_push_pin_no = pin_no;  
  32.                     }  
  33.                 }                                                                                                                                                         release_event_at_push[button] = m_events_list[button].release_event;  
  34.                 break;  
  35.             case APP_BUTTON_RELEASE:  
  36.                 (void)app_timer_stop(m_button_timer_id);  
  37.                 if (release_event_at_push[button] == m_events_list[button].release_event)  
  38.                 {  
  39.                     event = m_events_list[button].release_event;  
  40.                 }  
  41.                 break;  
  42.             case BSP_BUTTON_ACTION_LONG_PUSH:  
  43.                 event = m_events_list[button].long_push_event;  
  44.                           
  45.         }  
  46.     }  
  47.   
  48.     if ((event != BSP_EVENT_NOTHING) && (m_registered_callback != NULL))  
  49.     {    
  50.         m_registered_callback(event);  
  51.     }  
  52. }  


这里来分析下如何实现长按和段按的。

 如果是长按, event = m_events_list[button].push_event; event是0(即BSP_EVENT_NOTHING),-->m_events_list[button].long_push_event不等于BSP_EVENT_NOTHING,然后会产生长按扫描事件m_button_timer_id-->赋值释放事件,如果长按没有到设定的时间则产生释放按键事件,停止app_timer_stop(m_button_timer_id);

注意:BSP_MS_TO_TICK(BSP_LONG_PUSH_TIMEOUT_MS)是长按的时间,设置这个参数可以改变长按的事件。

 如果是短接事件, event = m_events_list[button].push_event; 不为0为定义的事件,-->m_events_list[button].long_push_event 等于 BSP_EVENT_NOTHING-->赋值释放按键事件。

  m_registered_callback(event); 这个函数即:bsp_event_handler函数-,(请查阅上面 bsp_init()函数)

长按事件,时间到了,产生button_timer_handler事件

[cpp]  view plain  copy
  1. /**@brief Handle events from button timer. 
  2.  * 
  3.  * @param[in]   p_context   parameter registered in timer start function. 
  4.  */  
  5. static void button_timer_handler(void * p_context)  
  6. {  
  7.     bsp_button_event_handler(*(uint8_t *)p_context, BSP_BUTTON_ACTION_LONG_PUSH);  
  8. }  

就是产生对应的长按事件。

注意:启动长按扫描的时候err_code = app_timer_start(m_button_timer_id, BSP_MS_TO_TICK(BSP_LONG_PUSH_TIMEOUT_MS), (void*)&current_long_push_pin_no);

current_long_push_pin_no 这个参数也传进去了,这个就是哪个管脚。方便产生长按超时的时候把哪个长按参数传进去,

看代码:bsp_init()函数

[cpp]  view plain  copy
  1. for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++)  
  2. {  
  3.     err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT);  
  4. }  

这里穿进去的参数是BSP_BUTTON_ACTION_PUSH 和 BSP_EVENT_DEFAULT

函数bsp_event_to_button_action_assign()里面

[cpp]  view plain  copy
  1. if (event == BSP_EVENT_DEFAULT)  
  2. {  
  3.     // Setting default action: BSP_EVENT_KEY_x for PUSH actions, BSP_EVENT_NOTHING for RELEASE and LONG_PUSH actions.  
  4.     event = (action == BSP_BUTTON_ACTION_PUSH) ? (bsp_event_t)(BSP_EVENT_KEY_0 + button) : BSP_EVENT_NOTHING;  
  5.    
  6. }  

可以看到只有当设置为BSP_BUTTON_ACTION_PUSH  和BSP_EVENT_DEFAULT的时候,event才有值不然为0.那假如要设置长按怎么办呢?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

nRF52832 — 外部中断BSP(Board Support Package) 的相关文章

随机推荐

  • vue项目Error: Cannot find module ‘xxx’类报错的解决方法

    现发现只要是报错 Error Cannot find module xxx 例如 Error Cannot find module webpack 这类的问题都可以用下面的方法解决 报错内容如下 运行 npm install 没问题 运行
  • 消息队列的两种模式

    Java消息服务 Java Message Service JMS 应用程序接口是一个Java平台中关于面向消息中间件 MOM 的API 用于在两个应用程序之间 或分布式系统中发送消息 进行异步通信 点对点与发布订阅最初是由JMS定义的 这
  • Box2D C++ 教程-物体

    Box2D C 教程 物体 物体 Bodies 物体是物理场景中的基本对象 但是这里的物体并不是你看到的实际互相弹跳碰撞的实物 听起来很费解吗 挺住 马上做解释 http ohcoder com blog 2012 11 29 bodies
  • springboot+log4j2遇到的坑

    情景再现 按照网上一般的教程 这样 并添加 去除 common logging的jar 实际过程中 仍然报错会发出警告 大概意思如下 slfj仍然用着springboot默认的logback 包有冲突 所以第一图并没有起作用 而且logba
  • 【20200326】数据挖掘课程课业打卡三

    20200326 数据挖掘课业打卡三之数据质量 数据挖掘课业打卡三之数据质量 一 单选题 二 填空题 三 判断题 知识点汇总 1 数据中可能存在的问题 2 数据预处理方法 3 关于欧几里得距离 叮嘟 这里是小啊呜的学习课程资料整理 好记性不
  • the host '192.168.2.100'is unreachable,The host may be down,or there may be a problem with......解决办法

    我这里遇到这样的问题 是因为网关和网络IP没有配置对造成的 解决办法如下 第一步 打开VM 点中要操作的虚拟机 鼠标点击左上角 编辑 虚拟网络编辑器 如下图所示 第二步 若是选择自定义网关 即选择如上图的VMnet8模式 选中VMnet8
  • WebSocket整合spring 一文全部搞定

    文章声明 本文简单整合了webSocket 组件 涉及到的源码分解 原理什么的以后再说 本文只适合入门小白体验 不涉及复杂业务逻辑 文章目录 1 引入webSocket依赖包 2 声明式整合WebSocket 这是一道硬菜 2 1 webS
  • C++STL模板库——deque容器

    今天介绍的是双端队列deque 也是STL中非常重要的内容 include
  • QT/QTCreator开发/使用技巧

    调试模式完整的展示过长的字符串 如图 当字符串过长时在调试模式下 无法非常清晰的看到全部的字符串 此时可以通过 右键菜单 change value display format spearate Window 此时字符串将单独显示在一个独立
  • 自己动手实现java 动态代理

    前言 上一篇讲到jdk动态代理的实现 现在来讲一下自己动手实现java 动态代理 上一篇 jdk 动态代理 2 自定义实现 分析 想要自定义实现 有5个步骤 生成增强类源代码 把源代码输出到磁盘 编译成class文件 加载到jvm中 返回被
  • stream的.findAny().orElse (null) 是什么意思?

    List
  • 判断当前浏览器环境是否是移动端

    一 直接上代码 测试移动端环境 function isMobileNavigator let flag navigator userAgent match phone pad pod iPhone iPod ios iPad Android
  • SET的用法

    写给自己看的小tips set set中插入一个元素 insert s1 str1 set中删除一个元素可以这样写 1 2 3 4 5 6 7 8 9 for set
  • Opencv(C++)学习系列---Sobel索贝尔算子边缘检测

    目录 1 算法简介 2 算子参数介绍 3 完整代码 1 算法简介 Sobel算子是一种用于边缘检测的线性滤波器 如果把图像看做是一个二维函数 那么Sobel算子就是图像在垂直和水平方向上变化的速度 即梯度 Sobel算子在水平和垂直方向上做
  • java 替换指定位置的字符_java Sting 如何替换指定位置的 字符?

    展开全部 include include include 此处空一行 using namespace std int main string str 123 421657 abcd 456789 此处空一行 cout lt lt str l
  • spring-mvc 用注解实现spring-mvc的基本开发

    用注解实现spring mvc的基本开发 maven的配置
  • Day20【元宇宙的实践构想06】—— 元宇宙与Web3.0

    本人简介 男 年龄 18 作者 那就叫我亮亮叭 专栏 元宇宙 部分资料参考文献 成生辉教授的 元宇宙 概念 技术及生态 和百度相关资料 0 0 写在前面 元宇宙 在2021年成为时髦的概念 元宇宙到底是什么 元宇宙是否是互联网技术的下一次革
  • Unity 摄像机自适应

    脚本挂在摄像机下 using System Collections using System Collections Generic using UnityEngine 摄像机显示结果一致 拉伸 public class CameraAda
  • MySql 数据库逻辑架构

    与其他数据库相比 MySql 数据库有自己独特的地方 它的架构可以在不同的场景中应用并发挥良好的作用 主要体现在存储引擎的架构上 插件式的存储引擎架构将查询处理和其他的系统任务以及数据的存储提取相分离 这种架构的最大优点是可以根据业务和实际
  • nRF52832 — 外部中断BSP(Board Support Package)

    原文链接 http blog csdn net a369000753 article details 51312839 转载文章 若有不妥 通知后我会立即删除 首先来分析下主要的代码 cpp view plain copy brief Fu