STM32开发记录一: 外部中断之软中断SWI使用

一、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();	
}

 

  • 12
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103ZET6是一款功能强大的微控制器,具有多种外围设备和接口。其中,GPIO外部中断是一种非常有用的功能,可以通过该功能实现对外部事件的快速响应。 在STM32F103ZET6中,GPIO外部中断的实现需要以下步骤: 1. 配置GPIO口为输入模式,并使能外部中断。 2. 配置中断触发方式,可以选择上升沿触发、下降沿触发、双边沿触发等方式。 3. 编写中断服务函数,在该函数中实现对外部事件的处理。 以下是一个简单的示例代码,演示如何在STM32F103ZET6上实现GPIO外部中断: //配置GPIO口为输入模式 GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //配置PA0引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //配置为输入模式,上拉 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA //使能外部中断 NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能AFIO时钟 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //选择中断线路 EXTI_InitStructure.EXTI_Line = EXTI_Line0; //选择中断线0 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //选择中断模式 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //选择上升沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断线 EXTI_Init(&EXTI_InitStructure); //初始化中断 //编写中断服务函数 void EXTI0_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line0) != RESET) //判断中断是否发生 { //处理外部事件 //... EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志位 } } 以上代码演示了如何在PA0引脚上实现上升沿触发的GPIO外部中断,并在中断服务函数中处理外部事件。实际应用中,可以根据需要选择不同的GPIO口和中断触发方式,并编写相应的中断服务函数来实现更加复杂的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值