zoukankan      html  css  js  c++  java
  • [nRF51822] 7、基础实验代码解析大全(前十)

    实验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(" 
    
    Exit!
    
    ");
    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(" "); 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:beautifulzzzz@qq.com 
    i-blog:blog.beautifulzzzz.com 

  • 相关阅读:
    javascript 利用
    javascript 事件委托(代理)
    【风马一族_日常灵感】 弯曲的几何学 曲角
    【风马一族_Python】 安装pip与Numpy
    【风马一族_Python】 更替pip的版本
    【风马一族_Android】Android学习
    气味分享系统
    【风马一族_构思】寻找二点间的最短距离
    【风马一族_Java】使用java,画出任意大小的菱形
    【风马一族_Java】9*9口诀
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/5750342.html
Copyright © 2011-2022 走看看