NORDIC nRF52840 输入引脚初始化及中断操作

硬件: NORDIC nRF 52840 SoC

软件: NORDIC nRF SDK Ver 15.2

硬件中断触发: 低电平触发


Step 1: 正确配置 GPIOTE Driver 通道数


Step 2: GPIO 引脚初始化

#define	RX8010_IRQ1			16
#define	RX8010_IRQ2			17
#define BUTTON_DETECTION_DELAY          APP_TIMER_TICKS(50)                     /**< Delay from a GPIOTE event until a button is reported as pushed (in number of timer ticks). */

static void GPIO_IRQ_init(void)
{
    ret_code_t err_code;

    //The array must be static because a pointer to it will be saved in the button handler module.
    static app_button_cfg_t RX8010SJ_IRQs[] =
    {
        {RX8010_IRQ1, false, BUTTON_PULL, GPIO_IRQs_event_handler},
        {RX8010_IRQ2, false, BUTTON_PULL, GPIO_IRQs_event_handler}				
    };

    err_code = app_button_init(RX8010SJ_IRQs, ARRAY_SIZE(RX8010SJ_IRQs),BUTTON_DETECTION_DELAY);
    APP_ERROR_CHECK(err_code);
		
    app_button_enable();
}

Step 3: 中断操作函数


/**@brief Function for handling events from the button handler module.
 * @param[in] pin_no        The pin that the event applies to.
 * @param[in] button_action The button action (press/release).
 */

static void GPIO_IRQs_event_handler(uint8_t pin_no, uint8_t button_action)
{
    ret_code_t err_code;
	
    switch (pin_no)
    {
        case RX8010_IRQ1:
            NRF_LOG_INFO("--- RX8010_IRQ1 ---");
            break;
        case RX8010_IRQ2:
            NRF_LOG_INFO("--- RX8010_IRQ2 ---");	
            break;
        default:
            APP_ERROR_HANDLER(pin_no);
            break;
    }
}

备注说明: 按此实施的输入引脚中断,会在上升及下降阶段都触发,即一个脉冲产生两个中断,特别注意!


--- 用以下方法实施,中断只在下降沿产生 --- (参照 example\ble|peripheral\ble_app_uart 样例修改)
 

引脚定义

#define BUTTONS_NUMBER 10

#define BUTTON_1       21
#define BUTTON_2       22
#define BUTTON_3       23
#define BUTTON_4       24
#define BUTTON_5       25
#define BUTTON_6       28
#define BUTTON_7       29
#define BUTTON_8       30
#define	BUTTON_9				16		//	BTN_RX8010SJ_IRQ1			16
#define	BUTTON_10				17		// BTN_RX8010SJ_IRQ2			17

#define BUTTON_PULL    NRF_GPIO_PIN_PULLUP

#define BUTTONS_ACTIVE_STATE 0

#define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4,BUTTON_5, BUTTON_6, BUTTON_7, BUTTON_8, BUTTON_9, BUTTON_10 }

#define BSP_BUTTON_0   BUTTON_1
#define BSP_BUTTON_1   BUTTON_2
#define BSP_BUTTON_2   BUTTON_3
#define BSP_BUTTON_3   BUTTON_4
#define BSP_BUTTON_4   BUTTON_5
#define BSP_BUTTON_5   BUTTON_6
#define BSP_BUTTON_6   BUTTON_7
#define BSP_BUTTON_7   BUTTON_8
#define BSP_BUTTON_8   BUTTON_9
#define BSP_BUTTON_9   BUTTON_10

bsp.h 文件中,枚举 bsp_event_t 添加          

BSP_EVENT_KEY_8,BSP_EVENT_KEY_9, BSP_EVENT_KEY_LAST = BSP_EVENT_KEY_9,


/**@brief BSP events.
 *
 * @note Events from BSP_EVENT_KEY_0 to BSP_EVENT_KEY_LAST are by default assigned to buttons.
 */
typedef enum
{
    BSP_EVENT_NOTHING = 0,                  /**< Assign this event to an action to prevent the action from generating an event (disable the action). */
    BSP_EVENT_DEFAULT,                      /**< Assign this event to an action to assign the default event to the action. */
    BSP_EVENT_CLEAR_BONDING_DATA,           /**< Persistent bonding data should be erased. */
    BSP_EVENT_CLEAR_ALERT,                  /**< An alert should be cleared. */
    BSP_EVENT_DISCONNECT,                   /**< A link should be disconnected. */
    BSP_EVENT_ADVERTISING_START,            /**< The device should start advertising. */
    BSP_EVENT_ADVERTISING_STOP,             /**< The device should stop advertising. */
    BSP_EVENT_WHITELIST_OFF,                /**< The device should remove its advertising whitelist. */
    BSP_EVENT_BOND,                         /**< The device should bond to the currently connected peer. */
    BSP_EVENT_RESET,                        /**< The device should reset. */
    BSP_EVENT_SLEEP,                        /**< The device should enter sleep mode. */
    BSP_EVENT_WAKEUP,                       /**< The device should wake up from sleep mode. */
    BSP_EVENT_SYSOFF,                       /**< The device should enter system off mode (without wakeup). */
    BSP_EVENT_DFU,                          /**< The device should enter DFU mode. */
    BSP_EVENT_KEY_0,                        /**< Default event of the push action of BSP_BUTTON_0 (only if this button is present). */
    BSP_EVENT_KEY_1,                        /**< Default event of the push action of BSP_BUTTON_1 (only if this button is present). */
    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). */
    BSP_EVENT_KEY_4,                        /**< Default event of the push action of BSP_BUTTON_4 (only if this button is present). */
    BSP_EVENT_KEY_5,                        /**< Default event of the push action of BSP_BUTTON_5 (only if this button is present). */
    BSP_EVENT_KEY_6,                        /**< Default event of the push action of BSP_BUTTON_6 (only if this button is present). */
    BSP_EVENT_KEY_7,                        /**< Default event of the push action of BSP_BUTTON_7 (only if this button is present). */
		BSP_EVENT_KEY_8,
    BSP_EVENT_KEY_9,
    BSP_EVENT_KEY_LAST = BSP_EVENT_KEY_9,
		
} bsp_event_t;

bsp.c 文件中变量 static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] 添加

    #ifdef BSP_BUTTON_8
    {BSP_BUTTON_8, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_8
        

    #ifdef BSP_BUTTON_9
    {BSP_BUTTON_9, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_9

static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] =
{
    #ifdef BSP_BUTTON_0
    {BSP_BUTTON_0, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_0

    #ifdef BSP_BUTTON_1
    {BSP_BUTTON_1, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_1

    #ifdef BSP_BUTTON_2
    {BSP_BUTTON_2, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_2

    #ifdef BSP_BUTTON_3
    {BSP_BUTTON_3, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_3

    #ifdef BSP_BUTTON_4
    {BSP_BUTTON_4, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_4

    #ifdef BSP_BUTTON_5
    {BSP_BUTTON_5, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_5

    #ifdef BSP_BUTTON_6
    {BSP_BUTTON_6, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_6

    #ifdef BSP_BUTTON_7
    {BSP_BUTTON_7, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_7
		
    #ifdef BSP_BUTTON_8
    {BSP_BUTTON_8, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_8
		

    #ifdef BSP_BUTTON_9
    {BSP_BUTTON_9, false, BUTTON_PULL, bsp_button_event_handler},
    #endif // BUTTON_9		
};

初始化

/**@brief Function for initializing buttons and leds.
 *
 * @param[out] p_erase_bonds  Will be true if the clear bonding button was pressed to wake the application up.
 */
static void buttons_leds_init(bool * p_erase_bonds)
{
    bsp_event_t startup_event;

    uint32_t err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_btn_ble_init(NULL, &startup_event);
    APP_ERROR_CHECK(err_code);

    *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
}

uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback)
{
    uint32_t err_code = NRF_SUCCESS;

#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
    m_indication_type     = type;
#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)

#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
	
    m_registered_callback = callback;

    // BSP will support buttons and generate events
    if (type & BSP_INIT_BUTTONS)
    {
        uint32_t num;

        for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++)
        {
            err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT);
        }
				
        if (err_code == NRF_SUCCESS)
        {
            err_code = app_button_init((app_button_cfg_t *)app_buttons,BUTTONS_NUMBER,APP_TIMER_TICKS(50));
        }

        if (err_code == NRF_SUCCESS)
        {
            err_code = app_button_enable();
        }

        if (err_code == NRF_SUCCESS)
        {
            err_code = app_timer_create(&m_bsp_button_tmr,
                                        APP_TIMER_MODE_SINGLE_SHOT,
                                        button_timer_handler);
        }
    }
#elif (BUTTONS_NUMBER > 0) && (defined BSP_SIMPLE)
    bsp_board_init(type);
#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)

#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
    if (type & BSP_INIT_LEDS)
    {
      //handle LEDs only. Buttons are already handled.
      bsp_board_init(BSP_INIT_LEDS);

      // timers module must be already initialized!
      if (err_code == NRF_SUCCESS)
      {
          err_code =
              app_timer_create(&m_bsp_leds_tmr, APP_TIMER_MODE_SINGLE_SHOT, leds_timer_handler);
      }

      if (err_code == NRF_SUCCESS)
      {
          err_code =
              app_timer_create(&m_bsp_alert_tmr, APP_TIMER_MODE_REPEATED, alert_timer_handler);
      }
    }
#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)

    return err_code;
}
/**@brief Handle events from button timer.
 *
 * @param[in]   p_context   parameter registered in timer start function.
 */
static void button_timer_handler(void * p_context)
{
    bsp_button_event_handler(*(uint8_t *)p_context, BSP_BUTTON_ACTION_LONG_PUSH);
}
/**@brief Function for handling button events.
 *
 * @param[in]   pin_no          The pin number of the button pressed.
 * @param[in]   button_action   Action button.
 */
static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action)
{
    bsp_event_t        event  = BSP_EVENT_NOTHING;
    uint32_t           button = 0;
    uint32_t           err_code;
    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. */
    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. */

    button = bsp_board_pin_to_button_idx(pin_no);

    if (button < BUTTONS_NUMBER)
    {
        switch (button_action)
        {
            case APP_BUTTON_PUSH:
                event = m_events_list[button].push_event;
                if (m_events_list[button].long_push_event != BSP_EVENT_NOTHING)
                {
                    err_code = app_timer_start(m_bsp_button_tmr, APP_TIMER_TICKS(BSP_LONG_PUSH_TIMEOUT_MS), (void*)&current_long_push_pin_no);
                    if (err_code == NRF_SUCCESS)
                    {
                        current_long_push_pin_no = pin_no;
                    }
                }
                release_event_at_push[button] = m_events_list[button].release_event;
                break;
            case APP_BUTTON_RELEASE:
                (void)app_timer_stop(m_bsp_button_tmr);
                if (release_event_at_push[button] == m_events_list[button].release_event)
                {
                    event = m_events_list[button].release_event;
                }
                break;
            case BSP_BUTTON_ACTION_LONG_PUSH:
                event = m_events_list[button].long_push_event;
        }
    }

    if ((event != BSP_EVENT_NOTHING) && (m_registered_callback != NULL))
    {
        m_registered_callback(event);
    }
}

/**@brief Function for handling events from the BSP module.
 *
 * @param[in]   event   Event generated by button press.
 */
void bsp_event_handler(bsp_event_t event)
{		
    uint32_t err_code;
    switch (event)
    {
			case BSP_EVENT_KEY_0:
				NRF_LOG_INFO("button pressed: KEY_0");
			
				btns_status = btns_status | 0x01;
				_74HC595_update_indicator_of_input_channels(1,1);
			
				if ( current_status_of_output_channels[0] == 0 )
				{
						current_status_of_output_channels[0] = 1;
						_74HC595_update_indicator_of_output_channels(1,1);
						bsp_board_led_off( BSP_BOARD_LED_0 );
				}
				else
				{
						current_status_of_output_channels[0] = 0;
						_74HC595_update_indicator_of_output_channels(0,1);
						bsp_board_led_on( BSP_BOARD_LED_0 );
				}
			
				NUS_send_data_handler();
				nrf_delay_ms(100);
				break;
			case BSP_EVENT_KEY_1:
				btns_status = btns_status | 0x02;
				NRF_LOG_INFO("button pressed: KEY_1");
			
				_74HC595_update_indicator_of_input_channels(1,2);
				if ( current_status_of_output_channels[1] == 0 )
				{
						current_status_of_output_channels[1] = 1;
						_74HC595_update_indicator_of_output_channels(1,2);
						bsp_board_led_off( BSP_BOARD_LED_1 );
				}
				else
				{
						current_status_of_output_channels[1] = 0;
						_74HC595_update_indicator_of_output_channels(0,2);
						bsp_board_led_on( BSP_BOARD_LED_1 );
				}
				
				NUS_send_data_handler();
				nrf_delay_ms(100);
				break;
			case BSP_EVENT_KEY_2:
				btns_status = btns_status | 0x04;
				NRF_LOG_INFO("button pressed: KEY_2");
				_74HC595_update_indicator_of_input_channels(1,3);
				if ( current_status_of_output_channels[2] == 0 )
				{
						current_status_of_output_channels[2] = 1;
						_74HC595_update_indicator_of_output_channels(1,3);
						bsp_board_led_off( BSP_BOARD_LED_2 );
				}
				else
				{
						current_status_of_output_channels[2] = 0;
						_74HC595_update_indicator_of_output_channels(0,3);
						bsp_board_led_on( BSP_BOARD_LED_2 );
				}
				NUS_send_data_handler();
				nrf_delay_ms(100);
				break;
			case BSP_EVENT_KEY_3:
				btns_status = btns_status | 0x08;

				NRF_LOG_INFO("button pressed: KEY_3");
				_74HC595_update_indicator_of_input_channels(1,4);
				if ( current_status_of_output_channels[3] == 0 )
				{
						current_status_of_output_channels[3] = 1;
						_74HC595_update_indicator_of_output_channels(1,4);
						bsp_board_led_off( BSP_BOARD_LED_3 );
				}
				else
				{
						current_status_of_output_channels[3] = 0;
						_74HC595_update_indicator_of_output_channels(0,4);
						bsp_board_led_on( BSP_BOARD_LED_3 );
				}					
				NUS_send_data_handler();
				nrf_delay_ms(100);
				break;		
			case BSP_EVENT_KEY_4:
				btns_status = btns_status | 0x10;
				NRF_LOG_INFO("button pressed: KEY_4");
				_74HC595_update_indicator_of_input_channels(1,5);
				if ( current_status_of_output_channels[4] == 0 )
				{
						current_status_of_output_channels[4] = 1;
						_74HC595_update_indicator_of_output_channels(1,5);
						bsp_board_led_off( BSP_BOARD_LED_4 );
				}
				else
				{
						current_status_of_output_channels[4] = 0;
						_74HC595_update_indicator_of_output_channels(0,5);
						bsp_board_led_on( BSP_BOARD_LED_4 );
				}
				NUS_send_data_handler();
				nrf_delay_ms(100);
				break;		
			
			case BSP_EVENT_KEY_5:
				btns_status = btns_status | 0x20;
				NRF_LOG_INFO("button pressed: KEY_5");
				_74HC595_update_indicator_of_input_channels(1,6);		// Òò PCB ×ßÏßÔ­Òò, 74HC595 LED ¶ÔÓ¦ÊäÈë 6,8 ͨµÀ»¥»»
//				_74HC595_update_indicator_of_input_channels(1,8);
				if ( current_status_of_output_channels[5] == 0 )
				{
						current_status_of_output_channels[5] = 1;
						_74HC595_update_indicator_of_output_channels(1,6);
						bsp_board_led_off( BSP_BOARD_LED_5 );
				}
				else
				{
						current_status_of_output_channels[5] = 0;
						_74HC595_update_indicator_of_output_channels(0,6);
						bsp_board_led_on( BSP_BOARD_LED_5 );
				}		
				NUS_send_data_handler();
				nrf_delay_ms(100);
				break;		
			
			case BSP_EVENT_KEY_6:
				btns_status = btns_status | 0x40;
				NRF_LOG_INFO("button pressed: KEY_6");
				_74HC595_update_indicator_of_input_channels(1,7);
				if ( current_status_of_output_channels[6] == 0 )
				{
						current_status_of_output_channels[6] = 1;
						_74HC595_update_indicator_of_output_channels(1,7);
						bsp_board_led_off( BSP_BOARD_LED_6 );
				}
				else
				{
						current_status_of_output_channels[6] = 0;
						_74HC595_update_indicator_of_output_channels(0,7);
						bsp_board_led_on( BSP_BOARD_LED_6 );
				}	
				NUS_send_data_handler();
				nrf_delay_ms(100);
				break;		
			case BSP_EVENT_KEY_7:
				btns_status = btns_status | 0x80;
				NRF_LOG_INFO("button pressed: KEY_7");
				_74HC595_update_indicator_of_input_channels(1,8);	// Òò PCB ×ßÏßÔ­Òò, 74HC595 LED ¶ÔÓ¦ÊäÈë 6,8 ͨµÀ»¥»»
//				_74HC595_update_indicator_of_input_channels(1,6);
				if ( current_status_of_output_channels[7] == 0 )
				{
						current_status_of_output_channels[7] = 1;
						_74HC595_update_indicator_of_output_channels(1,8);
						bsp_board_led_off( BSP_BOARD_LED_7 );
						NRF_LOG_INFO("button pressed: 111111111");
				}
				else
				{
						current_status_of_output_channels[7] = 0;
						_74HC595_update_indicator_of_output_channels(0,8);
						bsp_board_led_on( BSP_BOARD_LED_7 );
						NRF_LOG_INFO("button pressed: 00000");
				}			
				NUS_send_data_handler();
				nrf_delay_ms(100);
				break;				
	
			case BSP_EVENT_KEY_8:
				NRF_LOG_INFO("--- BTN_RX8010SJ_IRQ1 ---");
				break;
			case BSP_EVENT_KEY_9:
				NRF_LOG_INFO("--- BTN_RX8010SJ_IRQ2 ---");
				break;
			default:
					break;
    }
		btns_status = 0x00;
}

于函数 void bsp_event_handler(bsp_event_t event){} 中,做相应的输入中断判断,即可得到输入引脚下降沿中断,且只有下降沿中断产生。

nrf52840是一款低功耗蓝牙芯片,它具有强大的处理能力和丰富的外设接口,广泛应用于物联网和无线通信领域。协议栈初始化是在使用nrf52840芯片进行蓝牙通信时的一个重要步骤。 在nrf52840上进行协议栈初始化时,需要进行以下几个步骤: 1. 配置引脚:首先需要配置芯片的引脚,包括蓝牙通信所需的引脚和外设接口的引脚。可以使用芯片厂商提供的开发工具或者SDK来进行引脚配置。 2. 初始化时钟:接下来需要初始化芯片的时钟,确保系统时钟正常工作。可以使用芯片厂商提供的时钟初始化函数来完成。 3. 配置协议栈参数:在进行协议栈初始化之前,需要配置一些协议栈参数,例如蓝牙设备名称、设备地址等。这些参数可以通过调用相应的API函数来设置。 4. 初始化协议栈:最后一步是初始化协议栈本身。可以使用芯片厂商提供的协议栈初始化函数来完成。在初始化过程中,协议栈会进行一系列的初始化操作,包括分配内存、注册回调函数等。 如果nrf52840协议栈初始化不过,可能是由于以下几个原因: 1. 引脚配置错误:检查引脚配置是否正确,确保蓝牙通信所需的引脚和外设接口的引脚配置正确。 2. 时钟初始化错误:检查时钟初始化是否正确,确保系统时钟正常工作。 3. 协议栈参数配置错误:检查协议栈参数的配置是否正确,例如蓝牙设备名称、设备地址等。 4. 协议栈初始化函数调用错误:检查协议栈初始化函数的调用是否正确,确保使用了正确的函数和参数。 如果以上步骤都没有问题,还是无法通过协议栈初始化,可以参考芯片厂商提供的文档或者开发社区中的相关讨论,寻求帮助解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值