实验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驱动,是在串口上继续封装一层的
images/loading.gif' data-original="http://images2015.cnblogs.com/blog/506370/201608/506370-20160808154813246-1755624315.png" />
/**@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_Baud3840015 };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 休眠时看门狗保持运行。
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);//分配一个通道id30 APP_ERROR_CHECK(err_code);31 nrf_drv_wdt_enable();//使能看门狗32 33 while(1)34 {35 __SEV(); //设置事件36 __WFE(); //进入睡眠,等待事件唤醒37 __WFE();38 }39 }
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 occurs5 }
实验10 - 定时器
※ 配置NRF51822 的TIMER0 如下:
- 时钟:16MHz。
- 模式:定时器。
- 位宽:32 位。
- 比较时间:500ms。
※ 计数器开始计数后,当计数器里的值和比较寄存器里的值相等时,产生输出比较匹配事件,触发中断。在中断服务函数中轮流翻转开发板上的4 个LED 指示灯D1~D4。
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~D410 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
原标题:[nRF51822] 7、基础实验代码解析大全(前十)
关键词: