GD32系列外部中断

起因介绍

因为公司之前用GD32F4和周立功的CSM300产品的一个SPI转CAN模块,做了个产品,其在收到CAN帧时INT引脚会为由高电平转为低电平。需要做一个中断接收的程序防止丢包。
在这里插入图片描述

GD32的外部中断介绍

◼ 高效的中断处理;
◼ 支持异常抢占和咬尾中断;
◼ 将系统从省电模式唤醒;
◼ 3 种触发类型:上升沿触发,下降沿触发和任意沿触发;
◼ 软件中断或事件触发;
◼ 可配置的触发源。
在这里插入图片描述
简单介绍下它的一些必备知识,后面我们能用得到的。

首先就是GD32的中断线

在这里插入图片描述
这个图很清楚的表示了中断线硬件引脚之间的关系
即:所有的0号引脚例如PA0/PB0/PC0等由0线代表,所有的1号引脚有1线表示以此类推。

各系列外部中断的差异

在这里插入图片描述

软件配置

1. 时钟配置

不同系列的GD32单片机的时钟配置略有差别,

void rcu_config(void)
{
#if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X
rcu_periph_clock_enable(RCU_GPIOA);
#elif defined GD32F1X0 || GD32F4XX || GD32F3X0 || GD32E23X
rcu_periph_clock_enable(RCU_GPIOA);
#if defined GD32F1X0 || GD32F3X0 || GD32E23X
rcu_periph_clock_enable(RCU_CFGCMP);
#elif defined GD32F4XX
rcu_periph_clock_enable(RCU_SYSCFG);
#endif
#endif
}

代码意思为,前两个if所判断的单片机只需要配置相应引脚所在的组的时钟就可以了,第三个if意思为开启RCU_CFGCMP时钟,第四个意思为开启系统时钟。

2. GPIO引脚的配置

对需要配置外部中断的引脚进行初始化

void gpio_config(void)
{
#if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X
 gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
#elif defined GD32F1X0 || GD32F4XX || GD32F3X0 || GD32E23X
 gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_0);
#endif
}

主要区别就是不同系列单片机的初始化函数不同,一个是gpio_init一个是gpio_mode_set

3. 外设配置

在代码中,首先使能
EXTI中断,之后配置EXTI源以及所需要的边沿,最后清除EXTI中断标志。

void exti_config(void)
{
#if defined GD32F10X_HD|| GD32F30X_HD || GD32F1X0 || GD32F20X_CL || GD32F4XX || GD32F3X0 || GD32E10X ||
GD32E23X
#if defined GD32F1X0 || GD32F3X0 || GD32E23X || GD32F4XX
#if defined GD32E23X
/* enable and set key EXTI interrupt to the lowest priority */
nvic_irq_enable(EXTI0_1_IRQn, 2U);
 #elif defined GD32F4XX
 nvic_irq_enable(EXTI0_IRQn, 2U,0U);
#elif defined GD32F1X0 || GD32F3X0
nvic_irq_enable(EXTI0_1_IRQn, 2U,0U);
#endif
/* connect key EXTI line to key GPIO pin */
syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN0);
/* configure key EXTI line */
exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(EXTI_0);
#else
 nvic_irq_enable(EXTI0_IRQn, 2U,0U);
 gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_0);
/* configure key EXTI line */
exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(EXTI_0);
#endif
#endif
}

这个意思也很清楚,根据不同系列单片机,选择不同语句,我这里用的是GD32F4系列所以使用到

        //nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  
		nvic_irq_enable(EXTI5_9_IRQn, 2U, 0U);

        /* connect key EXTI line to key GPIO pin */
        syscfg_exti_line_config(EXTI_SOURCE_GPIOD, EXTI_SOURCE_PIN6);

        /* configure key EXTI line */
        exti_init(EXTI_6, EXTI_INTERRUPT, EXTI_TRIG_RISING);
        exti_interrupt_flag_clear(EXTI_6);
	 

这四句话。
详细解读下重要语句
第一句,因为我这里用的是D6脚所以这里的中断号选择EXTI5_9_IRQn,后面参数参考上面的代码选择就可以了
第二句,这里需要配置为你所需要配置的外部中断引脚(我这里是D6脚)
第三句,因为我这里是D6脚,由上面那个表可知我们需要选择6号中断线EXTI_6
第四句,清EXTI_6的中断标志位

4. 中断处理函数

void EXTI5_9_IRQHandler(void)
{
if(exti_interrupt_flag_get(EXTI_6) == SET)
{
//用户代码
 exti_interrupt_flag_clear(EXTI_6);
}
}

因为我的中断号为EXTI5_9_IRQn所以我的中断函数名为EXTI5_9_IRQHandler

工程示例

#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "GPIO.h"
#include "SPI.h"
#include "CSM300.h"


/************************************************************************
 GD32F407开发板实验:SPI通讯实验
 技术支持:010-57273301
 淘宝店铺:乾勤科技
 官网:http://www.qianqin.com.cn/
 作者:	QianQin
*************************************************************************/
/************************************************************************
发送和接收数组组成
*第一个字节       帧头
*第二个字节       帧数据长度(除了帧头帧尾都算)
*第三个字节		    帧类型  扩展帧为0x08 标准帧为0x00
*第四第五个字节   帧ID,此为标准帧ID仅有两个字节,扩展帧字节变为四个
*第六~十三字节    数据  
*第十四字节       帧尾
******************************************************************************/
unsigned char send1[8]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
unsigned char send2[8]={0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11};
unsigned char get[14];
void  initexit(void);


int main(void)
{
 	Gpio_Init();
	systick_config();
	rcu_config();
	SPI0_Init();//SPI初始化
	ConfigModule();		//配置CSM300芯片参数
	Mode_Init();
    initexit();
	while(1)
	{		
	
		delay_1ms(100);
		Write_bytes(send1,0x555);//发数据测试
//		delay_1ms(100);	
//		Write_bytes(send2,0x285);//发数据测试
		
	
	
	//read_status();//读状态测试
		
	/*	此为查询接收
	//can卡发数据接收测试解除这部分函数屏蔽记得把前面的  delay_1ms(100);   给屏蔽
		if(0==gpio_input_bit_get(GPIOD, GPIO_PIN_6))//检测INT脚是否为低电平
		{
		read_data(get);
		}
			*/
	}
}
//外部中断初始化函数引脚为D6
 void  initexit(void)
 {
	    rcu_periph_clock_enable(RCU_SYSCFG);
	 	//	rcu_periph_clock_enable(RCU_GPIOD);//要读取PC12的电平,需要开启RCU_GPIOC时钟
		  gpio_mode_set(RCU_GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_NONE,GPIO_PIN_6);//将引脚PC12设为下拉输入 	
	
	    //nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  
			nvic_irq_enable(EXTI5_9_IRQn, 2U, 0U);                               //因为下面是EXTI_6所以这里要选EXTI5_9_IRQn,其中断函数就是EXTI5_9_IRQHandler

        /* connect key EXTI line to key GPIO pin */
        syscfg_exti_line_config(EXTI_SOURCE_GPIOD, EXTI_SOURCE_PIN6); //这边因为是D6脚所以要选EXTI_6  同理A4脚就是EXTI_4

        /* configure key EXTI line */
        exti_init(EXTI_6, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
        exti_interrupt_flag_clear(EXTI_6);
	 
	 
	 
 
 }

 //中断服务函数
 void EXTI5_9_IRQHandler(void)
{
	
    if (exti_interrupt_flag_get(EXTI_6) ==1) 
			{
        read_data(get);
        exti_interrupt_flag_clear(EXTI_6);	
    }
}

  • 6
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值