根据正点原子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中断测试的更多相关文章

  1. FreeRTOS中断测试

    configMAX_SYSCALL_INTERRUPT_PRIORITY 高于此优先级的中断,不能被禁止 #ifdef __NVIC_PRIO_BITS #define configPRIO_BITS ...

  2. Zynq-7000 FreeRTOS(二)中断:串口Uart中断

    总结Zynq-7000器件的PS上的串口中断,为FreeRTOS中断实验做准备.

  3. Zynq-7000 FreeRTOS(二)中断:PL中断请求

    总结Zynq-7000的PL发送给PS一个中断请求,为FreeRTOS中断做准备. UG585的P225显示了系统的中断框图,如下图所示. 图:ZYNQ器件的中断框图 UG585的P227画出来中断控 ...

  4. Zynq-7000 FreeRTOS(二)中断:Timer中断

    总结Zynq-7000 这款器件中的Timer定时器中断,为FreeRTOS中断做准备.在 ZYNQ 的纯 PS 里实现私有定时器中断. 每隔一秒中断一次, 在中断函数里计数加 1, 通过串口打印输出 ...

  5. Linux Shell 03 条件测试

    条件测试 方式一:在Bash中 test命令和[]是等价的. test命令: if test $n1 -eq $n2 then echo "The two number are equal& ...

  6. [03] react 测试

    测试是开发周期中的一个重要组成部分.没有测试的代码被称为:遗留代码.对于我而言,第一次学习 React 和 JavaScript 的时候,感到很有压力.如果你也是刚开始学习 JS/React,并加入他 ...

  7. 03.基于测试开发讲解和Cobertura框架介绍

    首先我们先 CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(200) DEFAULT ...

  8. 探究为什么FreeRTOS 有些API不能在中断服务函数中调用,转而需要调用带ISR的版本

    用了好久的FreeRTOS以前只是知道,如果在中断服务程序中调用某一些FreeRTOS的API函数时需要注意,如果有ISR版本的一定要调用末尾带ISR的函数,并且中断服务程序要调用freeRTOS的A ...

  9. FreeRTOS - 中断使用注意

    原文地址:http://www.cnblogs.com/god-of-death/p/6886823.html 注意点: 1.首先要将中断的嵌套全部设置为抢占优先级. 2.将freertos系统内核中 ...

随机推荐

  1. C#读取EXCEL到内存

    public class ExcelUtils { private static string strcon = "Server=48.12.1.28;initial catalog=NBS ...

  2. Error creating bean with name 'us' defined in class path resource [com/liuyang/test/DI/beans2.xml]: Cannot resolve reference to bean 'daoa' while setting bean property 'daoa'; nested exception is org.

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'us' defined ...

  3. 用word发CSDN blog

    目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写 ...

  4. JS 封装的结构关系

    /* -- 封装 -- */var _packaging = function() { //私有属性和方法 var age = "12"; var method1 = functi ...

  5. 设计模式16:Mediator 中介者模式(行为型模式)

    Mediator 中介者模式(行为型模式) 依赖关系的转化 动机(Motivation) 在软件构建过程中,经常出现多个对象互相关联交互的情况,对象之间经常会维持一种复杂的应用关系,如果遇到一些需求的 ...

  6. javascript 面试题之一

    function setName(obj){ obj.name="tom"; obj=new Object(); obj.name="mike"; } var ...

  7. UT源码 065

    NextDate函数问题 NextDate函数说明一种复杂的关系,即输入变量之间逻辑关系的复杂性 NextDate函数包含三个变量month.day和year,函数的输出为输入日期后一天的日期. 要求 ...

  8. C# xsd 验证 XML数据有效性 问题

    使用XSD进行批量数据导入时生成的XML数据有效性这样的功能已经不是第一次做了,之前做的时候都没有碰到什么问题,这些天在开发中遇到了一个很头痛的问题就是无论XSD文件规则怎么写,验证都是通过的. 下面 ...

  9. js常用的校验代码 (整理)

    /* 用途:检查输入手机号码是否正确 输入:str:字符串 返回:如果通过验证返回true,否则返回false */ function checkMobile(str){ var regu =/^[1 ...

  10. 基于flask的轻量级webapi开发入门-从搭建到部署

    基于flask的轻量级webapi开发入门-从搭建到部署 注:本文的代码开发工作均是在python3.7环境下完成的. 关键词:python flask tornado webapi 在python虚 ...