[nRF51822] 7、基礎實驗代碼解析大全(前十)

来源:http://www.cnblogs.com/zjutlitao/archive/2016/08/08/5750342.html
-Advertisement-
Play Games

實驗01 - GPIO輸出控制LED 引腳輸出配置:nrf_gpio_cfg_output(LED_1); 引腳輸出置高:nrf_gpio_pin_set(LED_1); 引腳電平轉換:nrf_gpio_pin_toggle(LED_1); 毫秒延時:nrf_delay_ms(100); 實驗02 ...


 

實驗01 - GPIO輸出控制LED

  • 引腳輸出配置:nrf_gpio_cfg_output(LED_1);
  • 引腳輸出置高:nrf_gpio_pin_set(LED_1);
  • 引腳電平轉換:nrf_gpio_pin_toggle(LED_1);
  • 毫秒延時:nrf_delay_ms(100);
 1 int main(void)
 2 {
 3     nrf_gpio_cfg_output(LED_1);//配置P0.21為輸出
 4     nrf_gpio_pin_set(LED_1);   //指示燈D1初始狀態為熄滅
 5 
 6     while (true)
 7     {
 8         //指示燈D1以200ms的間隔閃爍
 9         nrf_gpio_pin_toggle(LED_1);
10         nrf_delay_ms(100);
11     }
12 }

實驗02 - 跑馬燈(略)

實驗03 - GPIO輸入按鍵檢測

  • 多個引腳同時初始化輸出:nrf_gpio_range_cfg_output(LED_START, LED_STOP);
  • 多個引腳同時初始化輸入:nrf_gpio_range_cfg_input(BUTTON_START,BUTTON_STOP,NRF_GPIO_PIN_PULLUP);
  • 讀取某引腳的電平狀態:nrf_gpio_pin_read(BUTTON_1) == 0
 1 int main(void)
 2 {
 3     nrf_gpio_range_cfg_output(LED_START, LED_STOP);//配置P0.21~P0.24為輸出
 4     nrf_gpio_pin_set(LED_1);  //LED初始狀態為熄滅
 5     nrf_gpio_range_cfg_input(BUTTON_START,BUTTON_STOP,NRF_GPIO_PIN_PULLUP);//配置P0.17~P0.20為輸入
 6 
 7 
 8     while (true)
 9     {
10         //檢測按鍵S1是否按下
11         if(nrf_gpio_pin_read(BUTTON_1) == 0)
12         {
13             nrf_gpio_pin_clear(LED_1);
14             while(nrf_gpio_pin_read(BUTTON_1) == 0);//等待按鍵釋放
15             nrf_gpio_pin_set(LED_1);
16         }
17     }
18 }

實驗04 - GPIO控制蜂鳴器(略)

實驗05 - RGB三色LED(略)

實驗06 - UART數據收發 

調用了串口FIFO驅動,是在串口上繼續封裝一層的

  • /**@brief Function for getting a byte from the UART.
    *
    * @details This function will get the next byte from the RX buffer. If the RX buffer is empty
    * an error code will be returned and the app_uart module will generate an event upon
    * reception of the first byte which is added to the RX buffer.
    *
    * @param[out] p_byte Pointer to an address where next byte received on the UART will be copied.
    *
    * @retval NRF_SUCCESS If a byte has been received and pushed to the pointer provided.
    * @retval NRF_ERROR_NOT_FOUND If no byte is available in the RX buffer of the app_uart module.
    */
    uint32_t app_uart_get(uint8_t * p_byte);

  • /**@brief Function for putting a byte on the UART.
    *
    * @details This call is non-blocking.
    *
    * @param[in] byte Byte to be transmitted on the UART.
    *
    * @retval NRF_SUCCESS If the byte was successfully put on the TX buffer for transmission.
    * @retval NRF_ERROR_NO_MEM If no more space is available in the TX buffer.
    * NRF_ERROR_NO_MEM may occur if flow control is enabled and CTS signal
    * is high for a long period and the buffer fills up.
    */
    uint32_t app_uart_put(uint8_t byte);

 1 int main(void)
 2 {
 3     LEDS_CONFIGURE(LEDS_MASK);
 4     LEDS_OFF(LEDS_MASK);
 5     uint32_t err_code;
 6     const app_uart_comm_params_t comm_params =
 7     {
 8           RX_PIN_NUMBER,
 9           TX_PIN_NUMBER,
10           RTS_PIN_NUMBER,
11           CTS_PIN_NUMBER,
12           APP_UART_FLOW_CONTROL_DISABLED,
13           false,
14           UART_BAUDRATE_BAUDRATE_Baud38400
15     };
16 
17     APP_UART_FIFO_INIT(&comm_params,
18                          UART_RX_BUF_SIZE,
19                          UART_TX_BUF_SIZE,
20                          uart_error_handle,
21                          APP_IRQ_PRIORITY_LOW,
22                          err_code);
23 
24     APP_ERROR_CHECK(err_code);
25 
26     while (true)
27     {
28         uint8_t cr;
29         while(app_uart_get(&cr) != NRF_SUCCESS);  //等待接收串口數據
30         while(app_uart_put(cr) != NRF_SUCCESS);   //返回接收到的串口數據
31 
32         if (cr == 'q' || cr == 'Q')
33         {
34             printf(" \n\rExit!\n\r");
35 
36             while (true)
37             {
38                 // Do nothing.
39             }
40         }
41     }
42 }

實驗07 - UART控制指示燈(略)

實驗08 - 隨機數發生器

Random number generator

利用NRF51822 隨機數發生器生成隨機數,每隔500ms 通過串口輸出一次隨機數數值

/** @brief Function for getting vector of random numbers.
*
* @param[out] p_buff Pointer to unit8_t buffer for storing the bytes.
* @param[in] length Number of bytes to take from pool and place in p_buff.
*
* @retval Number of bytes actually placed in p_buff.
*/
uint8_t random_vector_generate(uint8_t * p_buff, uint8_t size)
{
        uint8_t available;
        uint32_t err_code;
        err_code = nrf_drv_rng_bytes_available(&available);
        APP_ERROR_CHECK(err_code);
        uint8_t length = (size<available) ? size : available;
        err_code = nrf_drv_rng_rand(p_buff,length);
        APP_ERROR_CHECK(err_code);
        return length;
}

 1 int main(void)
 2 {
......
3 while (true) 4 { 5 uint8_t p_buff[RANDOM_BUFF_SIZE]; 6 uint8_t length = random_vector_generate(p_buff,RANDOM_BUFF_SIZE); 7 printf("Random Vector:"); 8 for(uint8_t i = 0; i < length; i++) //串口輸出RNG 9 { 10 printf(" %3d",(int)p_buff[i]); 11 } 12 printf("\r\n"); 13 nrf_delay_ms(500); //延時,方便觀察數據 14 nrf_gpio_pin_toggle(LED_1); //指示燈D1指示程式運行 15 } 16 }

實驗09 - 看門狗

  配置NRF51822 的看門狗超時周期為2 秒,CPU 休眠時看門狗保持運行。

  • NRF51822 的看門狗定時器是倒計數器,當計數值減少到0 時產生TIMEOUT 事件。
  • 通過START task 來啟動看門狗定時器。
  • 看門狗定時器啟動時,如沒有其他32.768KHz 時鐘源提供時鐘,看門狗定時器會強制打開32.768KHz RC 振蕩器。
  • 預設情況下,看門狗定時器會在CPU 睡眠期間,或是debugger 將CPU 暫停的時候保持運行。但是,可以通過配置看門狗定時器,使其在CPU 睡眠期間,或是debugger 將CPU 暫停的時候自動暫停。

  • 看門狗定時器超時周期:超時時間= ( CRV + 1 ) / 32768 秒
 1 int main(void)
 2 {
 3     uint32_t err_code = NRF_SUCCESS;
 4     
 5     //配置開發板上的4個用戶LED指示燈
 6     LEDS_CONFIGURE(LEDS_MASK);
 7     LEDS_OFF(LEDS_MASK);
 8     
 9     //4個指示燈輪流閃爍一次,指示系統啟動
10     for(uint32_t i = 0; i < LEDS_NUMBER; i++)
11     {   nrf_delay_ms(200);
12         LEDS_ON(BSP_LED_0_MASK << i);
13     }
14     
15     //BSP configuration for button support: button pushing will feed the dog.
16     err_code = nrf_drv_clock_init(NULL);
17     APP_ERROR_CHECK(err_code);//檢查返回值
18     nrf_drv_clock_lfclk_request();
19 
20     APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);//定時器設置
21     err_code = bsp_init(BSP_INIT_BUTTONS, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), bsp_event_callback);//按鍵中斷配置
22     APP_ERROR_CHECK(err_code);
23 
24     
25     //配置WDT.
26     nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG;//採用預設設置
27     err_code = nrf_drv_wdt_init(&config, wdt_event_handler);//使用預設參數配置看門狗。即CPU睡眠時,看門狗保持運行;看門狗超時周期2秒
28     APP_ERROR_CHECK(err_code);
29     err_code = nrf_drv_wdt_channel_alloc(&m_channel_id);//分配一個通道id
30     APP_ERROR_CHECK(err_code);
31     nrf_drv_wdt_enable();//使能看門狗
32 
33     while(1)
34     {
35         __SEV();  //設置事件
36         __WFE();  //進入睡眠,等待事件喚醒
37         __WFE();
38     }
39 }
  • 每按下一次S1 按鍵,進行一次喂狗操作:
 1 void bsp_event_callback(bsp_event_t event)
 2 {
 3     switch(event)
 4     {
 5     case BSP_EVENT_KEY_0:
 6         nrf_drv_wdt_channel_feed(m_channel_id);
 7         break;
 8     default : //Do nothing. break;
 9     }
10 } 
  • 如果2 秒內,按下按鍵S1 進行喂狗,系統正常運行,4 個指示燈常亮。如果2 秒內,不進行喂狗操作,系統複位:
1 void wdt_event_handler(void)
2 {
3     LEDS_OFF(LEDS_MASK);
4     //NOTE: The max amount of time we can spend in WDT interrupt is two cycles of 32768[Hz] clock - after that, reset occurs
5 }

實驗10 - 定時器

     配置NRF51822 的TIMER0 如下:

  • 時鐘:16MHz。
  • 模式:定時器。
  • 位寬:32 位。
  • 比較時間:500ms。

    計數器開始計數後,當計數器里的值和比較寄存器里的值相等時,產生輸出比較匹配事件,觸發中斷。在中斷服務函數中輪流翻轉開發板上的4 個LED 指示燈D1~D4。

  • NRF51822 共有3 個定時器TIMER0,TIMER1,TIMER2。
  • NRF51822 的TIMER 有兩種工作模式:定時模式和計數模式。在兩種模式下都是通過START task 啟動TIMER,通過STOP task 停止TIMER。當TIMER 停止時可以通過START task 讓TIMER 恢復運行,恢復運行後,TIMER 從停止時的定時/計數值繼續定時/計數。
  • 定時器時鐘:定時器的時鐘由PCLK16M 分頻而來,公式如下:ftimer=16MHz/(2^PRESCALER)

  •  

    定時器通過一個四位的分頻器進行分頻,PRESCALER 寄存器中數值即為分頻繫數,如果fTIMER <= 1 MHz,定時器將使用PCLK1M 時鐘源取代PCLK16M,以降低功耗。
 1 int main(void)
 2 {
 3     uint32_t time_ms = 500; //Time(in miliseconds) between consecutive compare events.
 4     uint32_t time_ticks;
 5     uint32_t err_code = NRF_SUCCESS;
 6     
 7     
 8     LEDS_CONFIGURE(LEDS_MASK);//配置開發板上驅賭LED的管腳為輸出
 9     LEDS_OFF(LEDS_MASK);      //熄滅LED D1~D4
10     
11     //Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
12     err_code = nrf_drv_timer_init(&TIMER_LED, NULL, timer_led_event_handler);//初始化
13     APP_ERROR_CHECK(err_code);
14     
15     time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_LED, time_ms);
16     
17     nrf_drv_timer_extended_compare(//設置比較寄存器中的值(本實驗設置的值對應於500ms)。計數器開始計數後,當計數器里的值和比較寄存器里的值相等時,產生輸出比較匹配事件,觸發中斷。
18          &TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
19     
20     nrf_drv_timer_enable(&TIMER_LED);//啟動
21 
22     while(1)
23     {
24         __WFI(); //進入睡眠,等待中斷
25     }
26 }

定時器(TIMER0)啟動後,系統通過“__WFI();”指令進入睡眠等待比較匹配事件觸發中斷喚醒,中斷發生後,在中斷服務函數中輪流翻轉開發板上的4 個LED 指示燈的狀態:

 1 /**
 2 * @brief Handler for timer events. 輪流翻轉開發板上的4個指示燈D1~D4的狀態
 3 */
 4 void timer_led_event_handler(nrf_timer_event_t event_type, void *p_context)
 5 {
 6     static uint32_t i;
 7     uint32_t led_to_invert = (1 << leds_list[(i++) % LEDS_NUMBER]);
 8 
 9     switch(event_type)
10     {
11     case NRF_TIMER_EVENT_COMPARE0:
12         LEDS_INVERT(led_to_invert);
13         break;
14 
15     default:
16         //Do nothing.
17         break;
18     }
19 }

 

 

@beautifulzzzz - 物聯網&普適計算實踐者
e-mail:[email protected] 
i-blog:blog.beautifulzzzz.com 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • PIDSTAT NAME pidstat對linux任務的統計 語法 pidstat [ -C comm ] [ -d ] [ -h ] [ -I ] [ -l ] [ -p { pid [,...] | SELF | ALL } ] [ -r ] [ -t ] [ -T { TASK | CHIL ...
  • 說“血案”有寫誇張了,其實是也就熬了一夜的通宵,做運維的傷不起啊,作為一名運維工程師,像這種伺服器突發故障半夜起床的情況屬於家常便飯,見怪不怪了,開始說正事: 前幾天半夜12點左右,收到伺服器宕機的消息,然後用dell idrac 卡遠程,結果無法通過它正常開機,直接發郵件給機房,讓他們重置下idr ...
  • 文件壓縮、解壓 網路、進程 磁碟、文件使用情況 記憶體使用 1、文件壓縮、解壓 1)tar.gz文件解壓: 2)zip 文件解壓: 2、網路、進程 1)netstat 在Linux上通常使用的是: netstat –apn | grep pid 在Windows上,對應的命令是:netstat –an ...
  • 一、本實驗ADC 配置 解析度:10 位。 輸入通道:5,即使用輸入通道AIN5 檢測電位器的電壓。 ADC 基準電壓:1.2V。 二、NRF51822 ADC 管腳分佈 NRF51822 的ADC 共有8 個輸入通道,對應的管腳分佈入下圖: 三、NRF51822 ADC 原理 NRF51822 的 ...
  • (1)當vim打開一個文件的時候,可以使用 (2)對當前文件寫入: 按鍵i ,左下角會顯示insert單詞,代表可以進行文本的插入; (3)滑鼠上下左右的移動: 上:K ↑ 下:j ↓ 左:H ← 右:L → (4)換行及刪除 換行寫入: o 刪除一行 : dd 返回 u (5)保存及退出 ESC ...
  • 附帶東野圭吾小說集(txt文件)http://pan.baidu.com/s/1slMSFxj 類模塊有多種用途,主要用於以下幾個方面: 1.封裝相似功能到單個對象中 2.建立帶有屬性、方法和事件的對象 3.特為自定義集合建立類模塊 封裝相似功能: 以一個名為clsUStationDialog的類開 ...
  • 前一篇分析了前十個基礎實驗的代碼,從這裡開始分析後十個~ 一、PPI原理: PPI(Programmable Peripheral Interconnect),中文翻譯為可編程外設互連。 在nRF51822 內部設置了PPI 方式,可以通過任務和事件讓不同外設之間進行互連,而不需要CPU 進行參與。 ...
  • nginx代理啟動 /usr/local/nginx/sbin/nginx apache2.2 service httpd restart【重啟apache服務】vi /etc/sysconfig/iptables【防火牆配置】service iptables restart【重啟防火牆服務】 vi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...