根据正点原子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. Oracle 自增长id

    CREATE SEQUENCE to38_import_result_seq INCREMENT BY 1 START WITH 10000 NOMAXVALUE NOCYCLE NOCACHE CR ...

  2. 打开程序出现.Net Framework Initialization Error – Unable to find a version of the runtime to run this applicatio的解决办法

    部署一个VS2010开发的程序时遇到 了一个非常奇怪的问题,客户端上已经安装了.net framework 4.0,但运行时还是会弹出错误: .Net Framework Initialization ...

  3. Vmware下CentOs7 桥接模式下配置固定IP

    1.安装完CentOS7后 修改虚拟机网络适配器配置:改成桥接模式 2.设置Vmware的 编辑->虚拟网络编辑器 3.重启CentOs7 , 查看网络 # ip addr interface是 ...

  4. [GO]获取命令行参数

    package main import ( "os" "fmt" ) func main() { list := os.Args n := len(list) ...

  5. QT之Variant

    QVariant识别类型的注册 QVariant识别类型的注册 QVariant为一个万能的数据类型--可以作为许多类型互相之间进行自动转换.将C++变为弱数据类型成为可能--也是许多控件中用户定义数 ...

  6. C# SendKeys用法

    功能:将一个或多个按键消息发送到活动窗口,就如同在键盘上进行输入一样. 语法:SendKeys.Send(string keys);SendKeys.SendWait(string keys); 说明 ...

  7. Android开发之深入理解NFC(一)

    深入理解NFC NFC(Near field communication,近场通信)也叫做近距离无线通信技术. 从原理来说,NFC和wifi类似,二者都利用无线射频技术来实现设备之间的通信. 但是,和 ...

  8. Java的sun.misc.Unsafe类

    阅读目录 前言 Unsafe类的作用 获取Unsafe对象 Unsafe类中的API 前言 以下sun.misc.Unsafe源码和demo基于jdk1.7: 最近在看J.U.C里的源码,很多都用到了 ...

  9. ARM启动代码中_main 与用户主程序main()的区别

    1.1  问题描述     __main函数的作用是什么呀?1.2  问题剖析     __main函数是C/C++运行时库的一个函数,嵌入式系统在进入应用主程序之前必须有一个初始化的过程,使用__m ...

  10. 正确理解volatile与happens-before

    1. 双重校验锁实现单例的问题 在延迟实现单例时,一般代码形式如下: public class Foo { private static volatile Foo instance; public s ...