STM32F103ZE单片机中FSMC Bank2~4中断(INT2~3和INTR引脚)的使用

在FSMC中,INT2~3和INTR引脚是三个外部中断,可高电平触发(EXTI没有的功能)、上升沿或下降沿触发。中断引脚分别是PG6、PG7和PF10。不打开相应的FSMC Bank(FSMC_PCRx_PBKEN=0)也能触发中断。其中上升/下降沿可通过软件对标志位写1来触发。

下面的程序通过改变各中断引脚内部所接的上下拉电阻来改变引脚电平,进而触发相应的中断。

#include <stdio.h>
#include <stm32f10x.h>

int fputc(int ch, FILE *fp)
{
	if (fp == stdout)
	{
		if (ch == '\n')
		{
			while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
			USART_SendData(USART1, '\r');
		}
		while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
		USART_SendData(USART1, ch);
	}
	return ch;
}

int main(void)
{
	GPIO_InitTypeDef gpio;
	USART_InitTypeDef usart;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG | RCC_APB2Periph_USART1, ENABLE);
	
	gpio.GPIO_Mode = GPIO_Mode_AF_PP;
	gpio.GPIO_Pin = GPIO_Pin_9;
	gpio.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &gpio);
	
	gpio.GPIO_Mode = GPIO_Mode_IPD; // 接内部下拉电阻
	gpio.GPIO_Pin = GPIO_Pin_10; // PF10为INTR引脚
	GPIO_Init(GPIOF, &gpio);
	
	gpio.GPIO_Mode = GPIO_Mode_IPD; // 接内部下拉电阻
	gpio.GPIO_Pin = GPIO_Pin_7; // PG7为INT3引脚
	GPIO_Init(GPIOG, &gpio);
	
	USART_StructInit(&usart);
	usart.USART_BaudRate = 115200;
	USART_Init(USART1, &usart);
	USART_Cmd(USART1, ENABLE);
	printf("FSMC Interrupt Test\n");
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	NVIC_EnableIRQ(USART1_IRQn);
	
	FSMC_ITConfig(FSMC_Bank3_NAND, FSMC_IT_RisingEdge | FSMC_IT_FallingEdge, ENABLE);
	FSMC_ITConfig(FSMC_Bank4_PCCARD, FSMC_IT_RisingEdge | FSMC_IT_FallingEdge, ENABLE);
	NVIC_EnableIRQ(FSMC_IRQn);
	
	// FSMC的Bank3~4不启用也能触发中断
	// 外部存储芯片的ready/busy引脚应该全部接到NWAIT上, 不应该接到INT引脚上, 否则无法使用FSMC的WAIT引脚等待功能
	// ready/busy引脚通常为开漏输出, 所以只要有一个芯片拉低了NWAIT, PD6就为低电平
	
	while (1)
		__WFI();
}

void FSMC_IRQHandler(void)
{
	if (FSMC_GetITStatus(FSMC_Bank3_NAND, FSMC_IT_RisingEdge) == SET)
	{
		FSMC_ClearITPendingBit(FSMC_Bank3_NAND, FSMC_IT_RisingEdge);
		printf("Interrupt rising edge in Bank 3!\n");
	}
	if (FSMC_GetITStatus(FSMC_Bank3_NAND, FSMC_IT_FallingEdge) == SET)
	{
		FSMC_ClearITPendingBit(FSMC_Bank3_NAND, FSMC_IT_FallingEdge);
		printf("Interrupt falling edge in Bank 3!\n");
	}
	
	if (FSMC_GetITStatus(FSMC_Bank4_PCCARD, FSMC_IT_RisingEdge) == SET)
	{
		FSMC_ClearITPendingBit(FSMC_Bank4_PCCARD, FSMC_IT_RisingEdge);
		printf("Interrupt rising edge in Bank 4!\n");
	}
	if (FSMC_GetITStatus(FSMC_Bank4_PCCARD, FSMC_IT_FallingEdge) == SET)
	{
		FSMC_ClearITPendingBit(FSMC_Bank4_PCCARD, FSMC_IT_FallingEdge);
		printf("Interrupt falling edge in Bank 4!\n");
	}
}

void USART1_IRQHandler(void)
{
	uint8_t data = USART_ReceiveData(USART1);
	printf("[Key %c] ", data);
	switch (data)
	{
	case 'a':
		// 改变PG7上所接的内部上/下拉电阻
		printf("PG7=%d\n", GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_7));
		GPIOG->ODR ^= GPIO_ODR_ODR7;
		break;
	case 'b':
		// 高电平中断会反复触发, 所以放在这里
		if (FSMC_GetFlagStatus(FSMC_Bank3_NAND, FSMC_FLAG_Level) == SET)
		{
			FSMC_ClearFlag(FSMC_Bank3_NAND, FSMC_FLAG_Level);
			printf("Interrupt high-level occurred in Bank 3!\n");
		}
		else
			printf("\n");
		break;
	case 'c':
		// 改变PF10上所接的内部上/下拉电阻
		printf("PF10=%d\n", GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_10));
		GPIOF->ODR ^= GPIO_ODR_ODR10;
		break;
	case 'd':
		if (FSMC_GetFlagStatus(FSMC_Bank4_PCCARD, FSMC_FLAG_Level) == SET)
		{
			FSMC_ClearFlag(FSMC_Bank4_PCCARD, FSMC_FLAG_Level);
			printf("Interrupt high-level occurred in Bank 4!\n");
		}
		else
			printf("\n");
		break;
	case 'e':
		if (FSMC_GetFlagStatus(FSMC_Bank2_NAND, FSMC_FLAG_FEMPT) == SET)
			printf("FSMC Bank2 FIFO empty!\n");
		if (FSMC_GetFlagStatus(FSMC_Bank3_NAND, FSMC_FLAG_FEMPT) == SET)
			printf("FSMC Bank3 FIFO empty!\n");
		if (FSMC_GetFlagStatus(FSMC_Bank4_PCCARD, FSMC_FLAG_FEMPT) == SET)
			printf("FSMC Bank4 FIFO empty!\n");
		break;
	case 'f':
		// 可软件触发中断
		FSMC_Bank3->SR3 |= FSMC_SR3_IRS; // rising
		break;
	case 'g':
		FSMC_Bank3->SR3 |= FSMC_SR3_IFS; // falling
		break;
	case 'h':
		FSMC_Bank4->SR4 |= FSMC_SR4_IRS;
		break;
	case 'i':
		FSMC_Bank4->SR4 |= FSMC_SR4_IFS;
		break;
	default:
		printf("\n");
	}
	// 注意: 高电平中断ILS不可通过对标志位写1触发
}
程序运行结果:
FSMC Interrupt Test
Interrupt rising edge in Bank 3!
Interrupt falling edge in Bank 3!
Interrupt rising edge in Bank 4!
Interrupt falling edge in Bank 4!
[Key b] Interrupt high-level occurred in Bank 3!
[Key b]
[Key b]
[Key b]
[Key a] PG7=0
Interrupt rising edge in Bank 3!
[Key b] Interrupt high-level occurred in Bank 3!
[Key b] Interrupt high-level occurred in Bank 3!
[Key b] Interrupt high-level occurred in Bank 3!
[Key b] Interrupt high-level occurred in Bank 3!
[Key a] PG7=1
Interrupt falling edge in Bank 3!
[Key b] Interrupt high-level occurred in Bank 3!
[Key b]
[Key b]
[Key b]
[Key d] Interrupt high-level occurred in Bank 4!
[Key d]
[Key d]
[Key d]
[Key c] PF10=0
Interrupt rising edge in Bank 4!
[Key d] Interrupt high-level occurred in Bank 4!
[Key d] Interrupt high-level occurred in Bank 4!
[Key d] Interrupt high-level occurred in Bank 4!
[Key d] Interrupt high-level occurred in Bank 4!
[Key c] PF10=1
Interrupt falling edge in Bank 4!
[Key d] Interrupt high-level occurred in Bank 4!
[Key d]
[Key d]
[Key d]
[Key c] PF10=0
Interrupt rising edge in Bank 4!
[Key d] Interrupt high-level occurred in Bank 4!
[Key d] Interrupt high-level occurred in Bank 4!
[Key d] Interrupt high-level occurred in Bank 4!
[Key d] Interrupt high-level occurred in Bank 4!
[Key e] FSMC Bank2 FIFO empty!
FSMC Bank3 FIFO empty!
FSMC Bank4 FIFO empty!
[Key f] Interrupt rising edge in Bank 3!
[Key g] Interrupt falling edge in Bank 3!
[Key f] Interrupt rising edge in Bank 3!
[Key g] Interrupt falling edge in Bank 3!
[Key h] Interrupt rising edge in Bank 4!
[Key h] Interrupt rising edge in Bank 4!
[Key h] Interrupt rising edge in Bank 4!
[Key i] Interrupt falling edge in Bank 4!
[Key i] Interrupt falling edge in Bank 4!
[Key i] Interrupt falling edge in Bank 4!

程序最开始运行时标志位FSMC_SRx_IFS、FSMC_SRx_IRS、FSMC_SRx_ILS的状态是不定的,也可能都默认置位了,也可能部分置位,或者全部为0,所以打开FSMC中断前最好清除一下所有的标志位,防止误判:

FSMC_ClearFlag(FSMC_Bank3_NAND, FSMC_FLAG_Level);
FSMC_ClearFlag(FSMC_Bank3_NAND, FSMC_FLAG_RisingEdge);
FSMC_ClearFlag(FSMC_Bank3_NAND, FSMC_FLAG_FallingEdge);
FSMC_ClearFlag(FSMC_Bank4_PCCARD, FSMC_FLAG_Level);
FSMC_ClearFlag(FSMC_Bank4_PCCARD, FSMC_FLAG_RisingEdge);
FSMC_ClearFlag(FSMC_Bank4_PCCARD, FSMC_FLAG_FallingEdge);

FSMC_ITConfig(FSMC_Bank3_NAND, FSMC_IT_RisingEdge | FSMC_IT_FallingEdge, ENABLE);
FSMC_ITConfig(FSMC_Bank4_PCCARD, FSMC_IT_RisingEdge | FSMC_IT_FallingEdge, ENABLE);
NVIC_EnableIRQ(FSMC_IRQn);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巨大八爪鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值