//main.c
#include "sys.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "delay.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#define START_TASK_PRIO 1 //任务优先级
#define START_STK_SIZE 100 //任务堆栈大小
TaskHandle_t StartTask_Handler ; //任务句柄
void start_task(void *parm); //任务函数
#define INTERRUPT_task_pro 2
#define INTERRUPT_STK_SIZE 100
TaskHandle_t INTERRUPTTask_Handler ;
void interrupt_task(void *parm);
#define LED_task_pro 2
#define LED_STK_SIZE 100
TaskHandle_t LEDTask_Handler ;
void LED_task(void *parm);
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
delay_init();
uart_init(115200);
LED_Init();
TIM3_INIT(36000-1,2000-1); //定时周期1s
TIM2_INIT(36000-1,2000-1);
//创建一个开始任务
xTaskCreate(
(TaskFunction_t ) start_task,
(const char * ) "startTask", //任务名
(uint16_t ) START_STK_SIZE, //任务堆栈大小
(void * ) NULL, //任务输入参数
(UBaseType_t ) START_TASK_PRIO, //任务优先级
(TaskHandle_t * ) & StartTask_Handler); //任务句柄
vTaskStartScheduler(); //开启任务调度
}
void start_task(void *parm)
{
taskENTER_CRITICAL();//进入临界区
// 创建中断测试任务
xTaskCreate(
(TaskFunction_t ) interrupt_task,
(const char * ) "interruptask", //任务名
(uint16_t ) INTERRUPT_STK_SIZE, //任务堆栈大小
(void * ) NULL, //任务输入参数
(UBaseType_t ) INTERRUPT_task_pro, //任务优先级
(TaskHandle_t * ) & INTERRUPTTask_Handler); //任务句柄
// 创建led测试任务
xTaskCreate(
(TaskFunction_t ) LED_task,
(const char * ) "LEDtask", //任务名
(uint16_t ) LED_STK_SIZE, //任务堆栈大小
(void * ) NULL, //任务输入参数
(UBaseType_t ) LED_task_pro, //任务优先级
(TaskHandle_t * ) & LEDTask_Handler); //任务句柄
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
void interrupt_task(void *parm)
{
static u16 toral_num = 0;
while(1)
{
toral_num +=1;
if(toral_num == 5)
{
toral_num = 0;
printf("关闭中断\n");
portDISABLE_INTERRUPTS(); //portmacro.h文件里面定义的。关闭优先级低于5的中断。
delay_xms(5000);
printf("打开中断\n");
portENABLE_INTERRUPTS();
}
vTaskDelay(1000);//注意这个延时一秒的作用。
}
}
void LED_task(void *parm)
{
while(1)
{
LED1 = !LED1;
vTaskDelay(1000);
}
}
//timer.c
#include "timer.h"
#include "usart.h"
void TIM3_INIT(u16 arr,u16 pre)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = pre;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
NVIC_Init(& NVIC_InitStructure);
TIM_Cmd(TIM3, ENABLE);
}
void TIM2_INIT(u16 arr,u16 pre)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = pre;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
NVIC_Init(& NVIC_InitStructure);
TIM_Cmd(TIM2, ENABLE);
}
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
{
printf("TIM3\n");
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
printf("TIM2\n");
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
遇到的问题:
(1)刚开始我是用的定时器3和定时器4,但是他们一起使用的话抢占优先级低的定时器中断不会进入中断服务函数,也就打印不出来那句话。但是我改成定时器2和3后两个定时器都会进入中断服务函数。原因我也不太清楚。
(2)led的闪烁:其实led的闪烁是受到
portDISABLE_INTERRUPTS();
portENABLE_INTERRUPTS();
中断的打开与关闭的影响的。