版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xqw19891201/article/details/83578504
一、SWI使用
1、学习FreeRTOS过程中需要软件产生一个中断,stm32提供了很好的方法。直接调用EXTI_GenerateSWInterrupt()即可。
二、具体参考如下:
1、exti配置,假定用EXTI_Line2 (EXTI_Linex where x can be (0..19))
#include "exit.h"
void ExitConfig(void)
{
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitStruct.EXTI_Line=EXTI_Line2;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //下降沿触发
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct); //初始化中断线参数
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //选择外部中断2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
}
2、在需要的地方打开中断: EXTI_GenerateSWInterrupt(EXTI_Line2);
#include "FreeRTOS.h"
#include "task.h"
#include "sys.h"
#include "led.h"
#include "uart.h"
#include "delay.h"
#define LED1_GPIO_GROUP GPIOB
#define LED1_GPIO_PIN_NUM (GPIO_Pin_5)
#define LED1_CLOCK_ENABLE RCC_APB2Periph_GPIOB
/*-----------------------------------------------------------------------------*
* name :led_init
* brief :led呼吸灯初始化设定,即IO口设定
* parameter :无
* return :无
* caller :外部调用
*-----------------------------------------------------------------------------*/
void led_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(LED1_CLOCK_ENABLE, ENABLE);
GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN_NUM;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LED1_GPIO_GROUP, &GPIO_InitStructure);
}
/*-----------------------------------------------------------------------------*
* name :led_control()
* brief :控制呼吸灯开关
* parameter :无
* return :无
* caller :led_breath调用
*-----------------------------------------------------------------------------*/
void led_control(int led_num, int status)
{
led_num = led_num;
if(status == LED_ON){
GPIO_SetBits(LED1_GPIO_GROUP, LED1_GPIO_PIN_NUM);
}
else if(status == LED_OFF){
GPIO_ResetBits(LED1_GPIO_GROUP, LED1_GPIO_PIN_NUM);
}
}
/*-----------------------------------------------------------------------------*
* name :led_breath()
* brief :呼吸灯外部调用控制接口
* parameter :无
* return :无
* caller :外部调用
*-----------------------------------------------------------------------------*/
void led_breath(void *pvParameters)
{
int i = 0;
for(;;)
{
myprintf("led task\n\r");
vTaskDelay(1000/portTICK_RATE_MS);
if(i % 5 == 0)
{
EXTI_GenerateSWInterrupt(EXTI_Line2);
}
i++;
}
}
3、stm32f10x_it.c里添加中断处理函数,运行EXTI_GenerateSWInterrupt(EXTI_Line2)后立即进入中断。
extern void myprintf(char *Data,...);
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus( EXTI_Line2) != RESET)
{
EXTI_ClearFlag(EXTI_Line2); //清除中断标志位
EXTI_ClearITPendingBit(EXTI_Line2); //清除EXTI线路挂起位
myprintf("SWInterrupt in\n\r");
}
}
4、main()函数
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "stm32f10x.h"
#include "exit.h"
#include "delay.h"
#include "led.h"
#include "lcd.h"
#include "uart.h"
//static const char *pcTextForTask1 = "Task 1 is running\r\n";
//static const char *pcTextForTask2 = "Task 2 is running\r\n";
//如果不加强制转换(signed char*),编译器GCC 会报错
const signed char * const Ledtask = (signed char*)"led task";
const signed char * const Lcdtask = (signed char*)"lcd task";
//const signed char * const task2 = "Task 1\n";
//const signed char * const task3 = "Task 2\n";
//xSemaphoreHandle xBinarySemaphore;
void reset(void)
{
ExitConfig();
USART1_Config();
delay_init();
led_init();
LcdInit();
}
int main(void)
{
reset();
//创建信号量
// vSemaphoreCreateBinary(xBinarySemaphore);
//
xTaskCreate(led_breath, Ledtask, configMINIMAL_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(LcdTask, Lcdtask, configMINIMAL_STACK_SIZE, NULL, 1, NULL);
vTaskStartScheduler();
}