nu-lb-nuc140 freertos 外部按键 中断实验
参考实验代码为:
en.stm32cubef4\STM32Cube_FW_F4_V1.21.0\Projects\STM32F412G-Discovery\Applications\FreeRTOS\FreeRTOS_SemaphoreFromISR
1 复制FreeRTOS模板,修改名字为FreeRTOS_KEY_Interrupt
参考程序:
Nu_LB_NUC140_BSP\SampleCode\Nu-LB-NUC140\GPIO_EXTINT\KEIL
2 修改MUC_init.h
//Define Clock source
#define MCU_CLOCK_SOURCE
#define MCU_CLOCK_SOURCE_HIRC // HXT, LXT, HIRC, LIRC
#define MCU_CLOCK_FREQUENCY 50000000 //Hz
//Define MCU Interfaces
#define MCU_INTERFACE_UART0
#define UART_CLOCK_SOURCE_HIRC // HXT, LXT, PLL, HIRC
#define UART_CLOCK_DIVIDER 3
#define PIN_UART0_RX_PB0
#define PIN_UART0_TX_PB1
//Define MCU Interfaces
#define MCU_INTERFACE_INT0_PB14
#define MCU_INTERFACE_INT1_PB15
//Define MCU Interfaces
3 在main.c中添加如下内容:
void EINT0_IRQHandler(void)
{
GPIO_CLR_INT_FLAG(PB, BIT14); // Clear GPIO interrupt flag
printf("PB14 EINT0 occurred.\n");
}
void EINT1_IRQHandler(void)
{
GPIO_CLR_INT_FLAG(PB, BIT15); // Clear GPIO interrupt flag
printf("PB15 EINT1 occurred.\n");
}
void Init_EXTINT(void)
{
// Configure EINT0 pin and enable interrupt by falling edge trigger
GPIO_SetMode(PB, BIT14, GPIO_MODE_INPUT);
GPIO_EnableEINT0(PB, 14, GPIO_INT_FALLING);
NVIC_EnableIRQ(EINT0_IRQn);
// Configure EINT1 pin and enable interrupt by rising and falling edge trigger
GPIO_SetMode(PB, BIT15, GPIO_MODE_INPUT);
GPIO_EnableEINT1(PB, 15, GPIO_INT_RISING); // RISING, FALLING, BOTH_EDGE, HIGH, LOW
NVIC_EnableIRQ(EINT1_IRQn);
// Enable interrupt de-bounce function and select de-bounce sampling cycle time
GPIO_SET_DEBOUNCE_TIME(GPIO_DBCLKSRC_LIRC, GPIO_DBCLKSEL_64);
GPIO_ENABLE_DEBOUNCE(PB, BIT14);
GPIO_ENABLE_DEBOUNCE(PB, BIT15);
}
在 main 函数中添加如下内容:
Init_EXTINT();
4 修改之后的main.c内容如下
//
// GPIO_LED : GPIO output to control an on-board red LED
//
// EVB : Nu-LB-NUC140
// MCU : NUC140VE3CN
// low-active output control by GPC12
#include <stdio.h>
#include "NUC100Series.h"
#include "MCU_init.h"
#include "SYS_init.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
#define THREAD_TEST_STACK_SIZE configMINIMAL_STACK_SIZE
#define THREAD_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
void Thread_Task1( void *pvParameters );
void Thread_Task2( void *pvParameters );
void vStartThreadTasks( void )
{
xTaskCreate( Thread_Task1, (const char * ) "Th_Task1", THREAD_TEST_STACK_SIZE, NULL, THREAD_TEST_PRIORITY, ( xTaskHandle * ) NULL );
xTaskCreate( Thread_Task2, (const char * ) "Th_Task2", THREAD_TEST_STACK_SIZE, NULL, THREAD_TEST_PRIORITY, ( xTaskHandle * ) NULL );
}
void Thread_Task1( void *pvParameters )
{
portTickType xLastTime1;
/* Get current system TickCount. */
xLastTime1 = xTaskGetTickCount();
for( ;; )
{
/* Run a time every 400 milliseconds. */
vTaskDelayUntil( &xLastTime1, 400 );
printf("Task1 called-\n");
}
}
void Thread_Task2( void *pvParameters )
{
portTickType xLastTime2;
/* Get current system TickCount. */
xLastTime2 = xTaskGetTickCount();
for( ;; )
{
/* Run a time every 800 milliseconds. */
vTaskDelayUntil( &xLastTime2, 800 );
printf("Task2 called--\n");
}
}
void EINT0_IRQHandler(void)
{
GPIO_CLR_INT_FLAG(PB, BIT14); // Clear GPIO interrupt flag
printf("PB14 EINT0 occurred.\n");
}
void EINT1_IRQHandler(void)
{
GPIO_CLR_INT_FLAG(PB, BIT15); // Clear GPIO interrupt flag
printf("PB15 EINT1 occurred.\n");
}
void Init_EXTINT(void)
{
// Configure EINT0 pin and enable interrupt by falling edge trigger
GPIO_SetMode(PB, BIT14, GPIO_MODE_INPUT);
GPIO_EnableEINT0(PB, 14, GPIO_INT_FALLING);
NVIC_EnableIRQ(EINT0_IRQn);
// Configure EINT1 pin and enable interrupt by rising and falling edge trigger
GPIO_SetMode(PB, BIT15, GPIO_MODE_INPUT);
GPIO_EnableEINT1(PB, 15, GPIO_INT_RISING); // RISING, FALLING, BOTH_EDGE, HIGH, LOW
NVIC_EnableIRQ(EINT1_IRQn);
// Enable interrupt de-bounce function and select de-bounce sampling cycle time
GPIO_SET_DEBOUNCE_TIME(GPIO_DBCLKSRC_LIRC, GPIO_DBCLKSEL_64);
GPIO_ENABLE_DEBOUNCE(PB, BIT14);
GPIO_ENABLE_DEBOUNCE(PB, BIT15);
}
int main(void)
{
SYS_Init();
UART_Open(UART0, 115200);
printf("Hello World \r\n");
GPIO_SetMode(PC, BIT12, GPIO_MODE_OUTPUT);
Init_EXTINT();
vStartThreadTasks();
vTaskStartScheduler();
while(1) {
PC12 =0; // turn on LED
CLK_SysTickDelay(100000); // Delay
PC12 =1; // turn off LED
CLK_SysTickDelay(100000); // Delay
}
}
5 效果
之前的FreeRTOS 的两个任务 照常的运行。
当按下按键的时候,会自动的进入按键中断函数的服务程序。
可以在这个程序的基础上,实验 通过中断服务程序,发送消息给freertos task