FreeRTOS-03中断测试
根据正点原子FreeRTOS视频整理
单片机:STM32F207VC
FreeRTOS源码版本:v10.0.1
portDISABLE_INTERRUPTS(); /*关中断*/
portENABLE_INTERRUPTS(); /*开中断*/
工程列表:

实验说明:
1. 定时器3控制一个灯闪烁,抢占优先级为4;定时器5控制一个灯闪烁,抢占优先级为5.
2. InterruptTask()函数,一段时间后关闭中断,过一段时间再开启中断,如此反复。
3. 实验现象应该是,关闭中断后,优先级为4的灯继续闪烁,优先级为5的灯停止闪烁;
开启中断后,2个灯都在闪烁。
1. main.c
/*
* 实验说明:
* 1. 定时器3控制一个灯闪烁,抢占优先级为4;定时器4控制1个灯闪烁,抢占优先级为5.
* 2. InterruptTask()函数,一段时间后关闭中断,过一段时间再开启中断,如此反复。
* 备注:
* 1. portDISABLE_INTERRUPTS();关中断
* 2. portENABLE_INTERRUPTS();开中断
* 3. 关中断后,优先级低于configMAX_SYSCALL_INTERRUPT_PRIORITY的任务,会被关掉。
* 4. 数值越大,优先级越低。
*/
#include "main.h"
#include "gpio.h"
#include "delay.h"
#include "sys.h"
#include "timer.h" #include "stm32f2xx_gpio.h" #include "FreeRTOS.h"
#include "task.h" #define START_TASK_PRIO 1 /*任务优先级*/
#define START_STK_SIZE 128 /*任务堆栈大小*/
TaskHandle_t StartTask_Handle; /*任务句柄*/
void StartTask(void *pvParameters); /*任务函数*/ #define INTERRUPT_TASK_PRIO 2
#define INTERRUPT_STK_SIZE 256
TaskHandle_t InterruptTask_Handle;
void InterruptTask(void *pvParameters); /***** 声明 *****/
static void SystemInitial(void); void StartTask(void *pvParameters)
{
taskENTER_CRITICAL(); /*进入临界区*/ xTaskCreate((TaskFunction_t )InterruptTask, /*任务函数*/
(const char * )"InterruptTask", /*任务名称*/
(uint16_t )INTERRUPT_STK_SIZE, /*任务堆栈大小*/
(void * )NULL, /*传递给任务函数的参数*/
(UBaseType_t )INTERRUPT_TASK_PRIO, /*任务优先级*/
(TaskHandle_t )&InterruptTask_Handle); /*任务句柄*/ vTaskDelete(StartTask_Handle); /*删除开始任务*/
taskEXIT_CRITICAL(); /*推出临界区*/
} void InterruptTask(void *pvParameters)
{
static uint8_t i = ; while ()
{
i++;
if (==i)
{
portDISABLE_INTERRUPTS();
}
else if ( == i)
{
i = ;
portENABLE_INTERRUPTS();
}
else
; DelayXms();
}
} static void SystemInitial(void)
{
/*组4,16级抢占优先级,无响应优先级*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); DelayInitial();
GPIO_Initial();
TimerInitial();
} int main(void)
{
SystemInitial(); /*创建开始任务*/
xTaskCreate((TaskFunction_t )StartTask, /*任务函数*/
(const char * )"StartTask", /*任务名称*/
(uint16_t )START_STK_SIZE, /*任务堆栈大小*/
(void * )NULL, /*传递给任务函数的参数*/
(UBaseType_t )START_TASK_PRIO, /*任务优先级*/
(TaskHandle_t )&StartTask_Handle); /*任务句柄*/ /*开启任务调度*/
vTaskStartScheduler();
} /***************************END OF FILE***************************/
2. main.h
/**/
#ifndef __MAIN_H__
#define __MAIN_H__ #endif /*__MAIN_H__*/ /***************************END OF FILE***************************/
3. sys.c
/**/
#include "sys.h"
#include "stdio.h" #pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle; }; FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
// while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
// USART1->DR = (u8) ch;
return ch;
} /***************************END OF FILE***************************/
4. sys.h
/**/
#ifndef __SYS_H__
#define __SYS_H__ /*0不支持OS,1支持OS*/
#define SYSTEM_SUPPORT_OS 1 /*定义系统文件夹是否支持OS*/ #endif /*__SYS_H__*/ /***************************END OF FILE***************************/
5. delay.c
/**/
#include "delay.h"
#include "sys.h"
/*如果需要使用OS,则包括下面的头文件即可*/
#if SYSTEM_SUPPORT_OS
#include "FreeRTOS.h"
#include "task.h"
#endif __IO uint32_t TimingDelay; //////////////////////////
static uint8_t fac_us = ;
////////////////////////// /***** 声明 *****/
extern void xPortSysTickHandler(void); /*systick中断服务函数,使用FreeRTOS时用到*/
void SysTick_Handler(void)
{
TimingDelayDecrement(); if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) /*系统已运行*/
{
xPortSysTickHandler();
}
} void DelayInitial(void)
{
/*
* SystemCoreClock / 1000 1ms中断一次
* SystemCoreClock / 100000 10us中断一次
* SystemCoreClock / 1000000 1us中断一次
*/
if (SysTick_Config(SystemCoreClock / ))
{
while ();
}
/*关闭systick timer定时器*/
/* SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;*/ /*使能滴答定时器*/
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
} void DelayNus(uint32_t nus)
{
uint32_t ticks;
uint32_t told, tnow, tcnt = ;
uint32_t reload = SysTick->LOAD; fac_us = SystemCoreClock / ;
ticks = nus * fac_us;
told = SysTick->VAL; while ()
{
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)
{
tcnt += told - tnow;
}
else
{
tcnt += reload - tnow + told;
}
told = tnow;
if (tcnt >= ticks) break;
}
}
} /*不会引起调度*/
void DelayXms(uint32_t nms)
{
uint32_t i; for (i=;i<nms;++i)
{
DelayNus();
}
} /*
* 本函数在中断函数中调用,滴答定时器中断一次调用一次。
*/
void TimingDelayDecrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
} /*
* TimingDelay值在TimingDelayDecrement函数中递减
*/
void DelayNms(uint32_t nTimes)
{
TimingDelay = nTimes; while (TimingDelay!=); //等待计数停止
} /***************************END OF FILE***************************/
6. delay.h
/**/
#ifndef __DELAY_H__
#define __DELAY_H__ #include "stm32f2xx.h" #include <stdint.h> extern void DelayInitial(void);
extern void TimingDelayDecrement(void);
extern void DelayNms(uint32_t nTimes); /////////////////////////
extern void DelayXms(uint32_t nms);
///////////////////////// #endif /*__DELAY_H__*/
/***************************END OF FILE***************************/
7. gpio.c
/**/
#include "gpio.h" /***** 声明 *****/
static void GPIO_LED_Configuration(void); void GPIO_Initial(void)
{
GPIO_LED_Configuration();
} static void GPIO_LED_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin = LED_POWER | LED_RUN | LED_ALARM;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOE, &GPIO_InitStructure); LED_Power_On();
LED_Run_Off();
LED_Alarm_Off();
} /***************************END OF FILE***************************/
8. gpio.h
/**/
#ifndef __GPIO_H__
#define __GPIO_H__ #include "stm32f2xx_gpio.h" #define LED_POWER GPIO_Pin_2 /*PE2*/
#define LED_RUN GPIO_Pin_3 /*PE3*/
#define LED_ALARM GPIO_Pin_4 /*PE4*/ #define LED_Power_On() GPIO_ResetBits(GPIOE, LED_POWER)
#define LED_Power_Off() GPIO_SetBits(GPIOE, LED_POWER)
#define LED_Run_On() GPIO_ResetBits(GPIOE, LED_RUN)
#define LED_Run_Off() GPIO_SetBits(GPIOE, LED_RUN)
#define LED_Alarm_On() GPIO_ResetBits(GPIOE, LED_ALARM)
#define LED_Alarm_Off() GPIO_SetBits(GPIOE, LED_ALARM) extern void GPIO_Initial(void); #endif /*__GPIO_H__*/
/***************************END OF FILE***************************/
9. timer.c
/**/
#include "timer.h"
#include "gpio.h"
#include "stm32f2xx_tim.h" /***** 声明 *****/
static void Timer3Init(void);
static void Timer4Init(void); void TimerInitial(void)
{
Timer3Init();
Timer4Init();
} /*timer3:APB1 30MHz*/
static void Timer3Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseStructure.TIM_Prescaler = -; /*预分频系数,30MHz/30000=1KHz*/
TIM_TimeBaseStructure.TIM_Period = -; /*计数值,每计1000个数,产生一次中断. 1000*(1/1KHz) = 1s */
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /*设置计数器模式为向上计数模式*/
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; /*设置时钟分频系数,TIM_CKD_DIV1不分频*/
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /*初始化*/ TIM_Cmd(TIM3, ENABLE); /*使能TIM4外设。在使用外设时,不仅要使能其时钟,还要调用此函数使能外设才可以正常使用*/ TIM_ClearFlag(TIM3, TIM_FLAG_Update); /*清除溢出中断标志*/ TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); /*开启中断*/ /*4级抢占优先级,0级响应优先级*/
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
} /*timer4:APB1 30MHz*/
static void Timer4Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); TIM_TimeBaseStructure.TIM_Prescaler = -; /*预分频系数,30MHz/30000=1KHz*/
TIM_TimeBaseStructure.TIM_Period = -; /*计数值,每计1000个数,产生一次中断. 1000*(1/1KHz) = 1s */
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /*设置计数器模式为向上计数模式*/
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; /*设置时钟分频系数,TIM_CKD_DIV1不分频*/
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /*初始化*/ TIM_Cmd(TIM4, ENABLE); /*使能TIM4外设。在使用外设时,不仅要使能其时钟,还要调用此函数使能外设才可以正常使用*/ TIM_ClearFlag(TIM4, TIM_FLAG_Update); /*清除溢出中断标志*/ TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); /*开启中断*/ /*5级抢占优先级,0级响应优先级*/
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
} /*Timer3中断服务函数*/
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update)==SET) /*溢出中断*/
{
GPIOE->ODR ^= LED_RUN;
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
} /*Timer4中断服务函数*/
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update)==SET) /*溢出中断*/
{
GPIOE->ODR ^= LED_ALARM;
}
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
// TIM_ClearFlag(TIM4, TIM_FLAG_Update); /*清除溢出中断标志*/
} /***************************END OF FILE***************************/
10. timer.h
/**/
#ifndef __TIMER_H__
#define __TIMER_H__ extern void TimerInitial(void); #endif /*__TIMER_H__*/ /***************************END OF FILE***************************/
说明:
main.c文件InterruptTask()函数中,如果延时用DelayNms()函数,
在执行portDISABLE_INTERRUPTS()函数后,会无法进入到滴答定时器,
导致portENABLE_INTERRUPTS()函数无法执行。
FreeRTOS-03中断测试的更多相关文章
- FreeRTOS中断测试
configMAX_SYSCALL_INTERRUPT_PRIORITY 高于此优先级的中断,不能被禁止 #ifdef __NVIC_PRIO_BITS #define configPRIO_BITS ...
- Zynq-7000 FreeRTOS(二)中断:串口Uart中断
总结Zynq-7000器件的PS上的串口中断,为FreeRTOS中断实验做准备.
- Zynq-7000 FreeRTOS(二)中断:PL中断请求
总结Zynq-7000的PL发送给PS一个中断请求,为FreeRTOS中断做准备. UG585的P225显示了系统的中断框图,如下图所示. 图:ZYNQ器件的中断框图 UG585的P227画出来中断控 ...
- Zynq-7000 FreeRTOS(二)中断:Timer中断
总结Zynq-7000 这款器件中的Timer定时器中断,为FreeRTOS中断做准备.在 ZYNQ 的纯 PS 里实现私有定时器中断. 每隔一秒中断一次, 在中断函数里计数加 1, 通过串口打印输出 ...
- Linux Shell 03 条件测试
条件测试 方式一:在Bash中 test命令和[]是等价的. test命令: if test $n1 -eq $n2 then echo "The two number are equal& ...
- [03] react 测试
测试是开发周期中的一个重要组成部分.没有测试的代码被称为:遗留代码.对于我而言,第一次学习 React 和 JavaScript 的时候,感到很有压力.如果你也是刚开始学习 JS/React,并加入他 ...
- 03.基于测试开发讲解和Cobertura框架介绍
首先我们先 CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(200) DEFAULT ...
- 探究为什么FreeRTOS 有些API不能在中断服务函数中调用,转而需要调用带ISR的版本
用了好久的FreeRTOS以前只是知道,如果在中断服务程序中调用某一些FreeRTOS的API函数时需要注意,如果有ISR版本的一定要调用末尾带ISR的函数,并且中断服务程序要调用freeRTOS的A ...
- FreeRTOS - 中断使用注意
原文地址:http://www.cnblogs.com/god-of-death/p/6886823.html 注意点: 1.首先要将中断的嵌套全部设置为抢占优先级. 2.将freertos系统内核中 ...
随机推荐
- TensorFlow全新的数据读取方式:Dataset API入门教程
TensorFlow.data : http://tech.ifeng.com/a/20171109/44752505_0.shtml Pytorch:https://ptorch.com/docs/ ...
- js实现二级菜单显示和收缩
window.onload=function(){ var aLi=document.getElementsByTagName('li'); for(var i=0; i<aLi.length; ...
- bootstrap缩略图及警示框制作
缩略图在网站中最常用的地方就是产品列表页面,一行显示几张图片,有的在图片底下(左侧或右侧)带有标题.描述等信息.Bootstrap框架将这一部独立成一个模块组件.并通过“thumbnail”样式配合b ...
- mongo学习-稀疏索引
因为,如果要创建唯一索引,那么如果这个值有好几个为Null的,所以也会导致我们创建索引失败,那么我们可以引进系数索引这个概念,它可以做到,支持如果值存在的情况,它必须是唯一的,我们可以 将 uniqu ...
- [GO]方法集
指针变量的方法集 package main import "fmt" type Person struct { name string sex byte age int } fun ...
- bootstrap-海棠
12 缩略图和警告框 <p class='alert alert-info'>这个是警告组<button class='close' data-dismiss='alert'> ...
- NIOS II 软件程序固化的相关知识
片上RAM和ROM的SOPC系统1.生成hex文件2.将hex文件添加到quartus工程中(添加qip文件)3.对工程进行全编译4.下载sof就可以看到程序运行5.将sof转换为jic文件,烧写到E ...
- Atcoder 2566 3N Numbers(优先队列优化DP)
問題文N を 1 以上の整数とします. 長さ 3N の数列 a=(a1,a2,…,a3N) があります. すぬけ君は.a からちょうど N 個の要素を取り除き.残った 2N 個の要素を元の順序で並べ. ...
- Linq特取操作之ElementAt,Single,Last,First源码分析
Linq特取操作之ElementAt,Single,Last,First源码分析 一:linq的特取操作 First/FirstOrDefault, Last/LastOrDefault, Eleme ...
- Arduino I2C + 温湿度传感器AM2321
(2015.5.17:本日志的内容有所更新,参见<使用Arduino Wire Library读取温湿度传感器AM2321>.) AM2321是广州奥松电子生产的数字式温湿度传感器.虽是国 ...