NRF52832入门第一步_搭建环境

使用KEIl进行NRF52832的开发,默认已经安装了KEIL5,安装了JLINK驱动,并且有一个jlink下载器和nrf52832的开发板或核心板

  1. 从官方下载SDK,SDK版本太多了,最新版肯定功能丰富,但是新增的功能也用不上,所以我选择了SDK的16.0.0版本,下面的soft device就不下载了。SDK下载链接
    下载NRF5的SDK
    扎心,下载错了,直接下载了最新版。不过问题不大。

  2. 打开一个example的工程,,我打开了10400的s132的blinker程序。然后会出现以下图片,然后就按照操作下载即可。注意有可能下载不下来,可以尝试其他办法下载安装这两个包。
    打开工程
    下载lib

  3. 之后就可以正常烧录了。之后继续更新nrf52832的学习进度,并分享一些学习经验。

一、 gpio控制

gpio控制包括引脚输出、引脚输入、其他的包括上拉、下拉等。因此gpio控制输入实验为led输出和按键输入

  1. led输出
    led输出为控制引脚的高低电平,如果已经在开发板上又led灯,则不需要外接led灯,否则需要在某一个引脚上增加一个led灯并串联一个电阻进行限流。
    如果使用pca10400开发板,在.h文件中已经定义了一些led引脚。
    led引脚
    引脚输出控制主要包括:设置引脚为输出模式、并控制引脚输出高电平和低电平,最好加一个延时控制闪烁。引脚的控制函数主要在nrf_gpio.h文件中看到,主要包括:
    ①引脚输出和输入的枚举类型

/** @brief Pin direction definitions. */
/** @引脚方向定义 */
typedef enum
{
    
    
    NRF_GPIO_PIN_DIR_INPUT  = GPIO_PIN_CNF_DIR_Input, ///< Input.
    NRF_GPIO_PIN_DIR_OUTPUT = GPIO_PIN_CNF_DIR_Output ///< Output.
} nrf_gpio_pin_dir_t;

/** @brief Connection of input buffer. */
/** @引脚是否输入buffer连接,输出时不连接,输入时连接*/
//Sense capability on the pin is configurable and input is connected to buffer so that the GPIO->IN register is readable.
typedef enum
{
    
    
    NRF_GPIO_PIN_INPUT_CONNECT    = GPIO_PIN_CNF_INPUT_Connect,   ///< Connect input buffer.
    NRF_GPIO_PIN_INPUT_DISCONNECT = GPIO_PIN_CNF_INPUT_Disconnect ///< Disconnect input buffer.
} nrf_gpio_pin_input_t;

/**
 * @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin
 * configuration.
 */
 /** @引脚输入时是否上拉下拉,输出模式下不拉,输入模式下可选择 */
typedef enum
{
    
    
    NRF_GPIO_PIN_NOPULL   = GPIO_PIN_CNF_PULL_Disabled, ///<  Pin pull-up resistor disabled.
    NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///<  Pin pull-down resistor enabled.
    NRF_GPIO_PIN_PULLUP   = GPIO_PIN_CNF_PULL_Pullup,   ///<  Pin pull-up resistor enabled.
} nrf_gpio_pin_pull_t;

/** @brief Enumerator used for selecting output drive mode. */
/** @引脚输出时不同的驱动模式,一般都是SOS1 */
typedef enum
{
    
    
    NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1'.
    NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High-drive '0', standard '1'.
    NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high-drive '1'.
    NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high-drive '1'.
    NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1'.
    NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high-drive '1'.
    NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0', disconnect '1'.
    NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High-drive '0', disconnect '1'.
} nrf_gpio_pin_drive_t;

/** @brief Enumerator used for selecting the pin to sense high or low level on the pin input. */
/** @是否感知高电平或低电平,一般都是nosense */
typedef enum
{
    
    
    NRF_GPIO_PIN_NOSENSE    = GPIO_PIN_CNF_SENSE_Disabled, ///<  Pin sense level disabled.
    NRF_GPIO_PIN_SENSE_LOW  = GPIO_PIN_CNF_SENSE_Low,      ///<  Pin sense low level.
    NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High,     ///<  Pin sense high level.
} nrf_gpio_pin_sense_t;

②然后是引脚的控制函数,只提到一些有用的:

/**
 * @brief Pin configuration function.
 *
 * The main pin configuration function.
 * This function allows to set any aspect in PIN_CNF register.
 *
 * @param pin_number Specifies the pin number.
 * @param dir        Pin direction.
 * @param input      Connect or disconnect the input buffer.
 * @param pull       Pull configuration.
 * @param drive      Drive configuration.
 * @param sense      Pin sensing mechanism.
 */
 // 最基础的函数,所有其他的函数都可以调用这个函数实现
 // 包括:引脚位数,注意引脚有些事0-30,有些是1-31;方向、是否连接buffer、是否上下拉、驱动模式、以及感知模式
__STATIC_INLINE void nrf_gpio_cfg(
    uint32_t             pin_number,
    nrf_gpio_pin_dir_t   dir,
    nrf_gpio_pin_input_t input,
    nrf_gpio_pin_pull_t  pull,
    nrf_gpio_pin_drive_t drive,
    nrf_gpio_pin_sense_t sense);

// 输出模式
__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number);
//输入模式
__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config);
//恢复默认状态
__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number);
//引脚输出的四个控制函数:高电平、低电平、反转、通用函数
__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number);
__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number);
__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number);
__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value);
//引脚读取,包括输入模式下读取和输出模式下读取
__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number);
__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin_number);

③很好,现在已经可以控制引脚了,还需要一个延时函数,可以自己写,当然nrf库中也有:

#include "nrf_delay.h"			// 延时需要包含头文件
int main(void)
{
    
    
nrf_gpio_cfg_output(11);
while(1)
	{
    
    
		nrf_gpio_pin_set(11);
		nrf_delay_ms(500);
		nrf_gpio_pin_clear(11);
		nrf_delay_ms(500);	
	}
}

④观察开发板上的led灯,可以看到一直在闪烁了,成功!

  1. 按键输入
    实现按键按一次改变led的亮灭,按键就上拉吧。不多说,直接上代码:
// 按键输入
nrf_gpio_cfg_input(12, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_output(11);
while(1)
{
    
    
	if(nrf_gpio_pin_read(12) == 0)
	{
    
    
		nrf_delay_ms(10);
		if(nrf_gpio_pin_read(12) == 0)
		{
    
    
			nrf_gpio_pin_toggle(11);
		}
		while(nrf_gpio_pin_read(12) == 0);
	}
}
}

nice!,现在已经可以进行简单地引脚输出和输入了。之后将继续进阶,下一步:定时器使用

二、 定时器使用

在nrf中定时器主要有两种,分别为低功耗的RTC定时器和高精度的DRV定时器。RTC定时器使用了32KHz的晶振,因此功耗很低,但无法要求高精度。DRV定时器为硬件定时器,共有5个。具体区别可参考这个链接

  1. RTC定时器
    使用RTC定时器还是挺简单的,但是我的核心板无法成功实现,可能晶振损坏了。
    已经解决了,是因为没有将rtc所需要的时钟进行初始化。在peripheral中的softblink中可以找到的解决方法。代码已经更新,可以正常使用。原文如下:
  • The low-frequency clock can be requested by different modules
  • or contexts. The driver ensures that the clock will be started only when it is requested
    表明还是要提前先启动始终才可以用
    然后介绍下该定时器的使用步骤:定义定时器ID、定时器延时、创建定时器(定义模式和调用函数)、定时器启动和停止。是不是很简单,就用这个定时器实现简单的led闪烁吧:
#include "nrf_drv_timer.h"
#include "nrf_drv_clock.h"		// 用于启用低速定时器的始终
/**
 * @brief Function for starting lfclk needed by APP_TIMER.
 */
static void lfclk_init(void)
{
    
    
    uint32_t err_code;
    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_clock_lfclk_request(NULL);
}
// RTC定时器,成功
APP_TIMER_DEF(s_testTimer);			// 测试用定时器
#define TEST_PERIOD APP_TIMER_TICKS(200)		// 定时器未200ms
static void timer_testCallback(void *arg)
{
    
    
	UNUSED_PARAMETER(arg);
	// 在这里加入自己的应用处理
	nrf_gpio_pin_toggle(11);			// 改变LED引脚
}

int main()
{
    
    
// LED
nrf_gpio_cfg_output(11);
nrf_gpio_pin_set(11);
// 定时器
ret_code_t err_code;
lfclk_init();			// 或直接用以下两个函数替代,启用低速定时器
//nrf_drv_clock_init();
//nrf_drv_clock_lfclk_request(NULL);
err_code = app_timer_init();
APP_ERROR_CHECK(err_code);
err_code = app_timer_create(&s_testTimer, APP_TIMER_MODE_REPEATED, timer_testCallback);
APP_ERROR_CHECK(err_code);
err_code = app_timer_start(s_testTimer, TEST_PERIOD, NULL);
APP_ERROR_CHECK(err_code);
// app_timer_stop(s_testTimer);
while(1);
}
  1. 硬件定时器
    突然发现nrf的官方手册:https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.0.0%2Fgroup__nrfx__timer.html
    另外也突然发现,使用ble_peripheral中的程序、定时器会报错,然后换到peripheral文件夹中的程序,就没有问题。具体的原因找到了,实在sdk_config.h文件中把定时器的该功能给取消了,因此就不能运行。
    定时器被注释了

猜你喜欢

转载自blog.csdn.net/Hot_Ant/article/details/109376757