HC32F460外部中断的使用

本次主要是使用按键触发外部中断,打印按下的按键,同时操作led灯。

外部中断操作流程参考《HC32F460系列的中断控制器INTC Rev1.1.pdf》中的使用方法。

1. 首先是介绍硬件电路的接法

 1.1 按键电路

 

                按键对应管脚 端口号:

按键

端口号

管脚

备注

KEY1

PortA

Pin04

低电平触发

KEY2

PortA

Pin05

低电平触发

KEY3

PortA

Pin06

低电平触发

        1.2 led对应电路图:

 LED对应管脚 端口号:

按键

端口号

管脚

备注

LED1

PortD

Pin02

输出模式

LED2

PortB

Pin03

输出模式

LED3

PortB

Pin04

输出模式(特殊脚需要处理)

LED4

PortB

Pin05

输出模式

2. 初始化GPIO

        2.1 led 按键管脚定义

        


#define LED1_PORT   PortD
#define LED1_Pin    Pin02

#define LED2_PORT   PortB
#define LED2_Pin    Pin03

#define LED3_PORT   PortB
#define LED3_Pin    Pin04

#define LED4_PORT   PortB
#define LED4_Pin    Pin05

#define KEY1_PORT   PortA
#define KEY1_Pin    Pin04

#define KEY2_PORT   PortA
#define KEY2_Pin    Pin05

#define KEY3_PORT   PortA
#define KEY3_Pin    Pin06

#define ReadPort		PortA
#define ReadPin			Pin07

 2.2 管脚配置

void User_Gpio_Init(void)
{
  stc_port_init_t Port_CFG;

	MEM_ZERO_STRUCT(Port_CFG);

	Port_CFG.enPinMode = Pin_Mode_Out;

	PORT_Init(LED1_PORT, LED1_Pin, &Port_CFG);
	PORT_Init(LED2_PORT, LED2_Pin, &Port_CFG);
	PORT_Init(LED3_PORT, LED3_Pin, &Port_CFG);
	PORT_Init(LED4_PORT, LED4_Pin, &Port_CFG);
   
}

2.3 点亮 熄灭方法(led1为例):        

PORT_SetBits(LED1_PORT,LED1_Pin);

PORT_ResetBits(LED1_PORT,LED1_Pin);

3. 中断配置

      3.1 中断函数配置

    stc_exint_config_t stcExtiConfig;	/* 外部中断配置结构体 */
    stc_irq_regi_conf_t stcIrqRegiConf; /*irq配置结构体 */
    stc_port_init_t stcPortInit;	/*管脚配置结构体 */

     /* configuration structure initialization */
    MEM_ZERO_STRUCT(stcExtiConfig);
    MEM_ZERO_STRUCT(stcIrqRegiConf);
    MEM_ZERO_STRUCT(stcPortInit);

    /* Set PD06 as External Int Ch.6 input */
    stcPortInit.enExInt = Enable;
	PORT_Init(KEY1_PORT, KEY1_Pin, &stcPortInit);
	PORT_Init(KEY2_PORT, KEY2_Pin, &stcPortInit);
	PORT_Init(KEY3_PORT, KEY3_Pin, &stcPortInit);

    stcExtiConfig.enExitCh = ExtiCh01;
	/* 过滤器配置 */
    stcExtiConfig.enFilterEn = Enable;
    stcExtiConfig.enFltClk = Pclk3Div8;
    /* 低电平触发(触发模式) */
    stcExtiConfig.enExtiLvl = ExIntLowLevel;
    EXINT_Init(&stcExtiConfig);

    /* 选择外部中断通道 Ch.1 */
    stcIrqRegiConf.enIntSrc = INT_PORT_EIRQ1;
    /*注册外部中断 to Vect.No.000 */
    stcIrqRegiConf.enIRQn = Int000_IRQn;
    /* 绑定回调函数 */
    stcIrqRegiConf.pfnCallback = &key_1_callback;
    enIrqRegistration(&stcIrqRegiConf);

    /* Clear Pending */
    NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);

    /* 配置优先级 */
    NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_15);

    /* 使能 NVIC */
    NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
    

3.2 回调函数配置

        自己定义了两个结构体测试用

typedef struct{
	uint8_t	key1:1;
	uint8_t	key2:1;
	uint8_t	key3:1;
	uint8_t	key4:1;
	uint8_t	key5:1;
	uint8_t	key6:1;
	uint8_t	key7:1;
	uint8_t	key8:1;
}Key_IO_bit_t;

typedef union{
	Key_IO_bit_t keys;
	uint8_t status;
}KEY_status_t;

        回调函数:

static void key_1_callback(void){
		static int i = 0;
		KEY_status_t keyGroup = {0};
		if(i == 65534){
				i = 0;
		}
		if(Set == EXINT_IrqFlgGet(ExtiCh01)){

				
			do{
				keyGroup.keys.key1 =  PORT_GetBit(KEY1_PORT, KEY1_Pin);
				keyGroup.keys.key2 =  PORT_GetBit(KEY2_PORT, KEY2_Pin);
				keyGroup.keys.key3 =  PORT_GetBit(KEY3_PORT, KEY3_Pin);
				if(keyGroup.status != 7) break;
			}while(1);
			
			Ddl_Delay1ms(40);
			
			if((keyGroup.keys.key1 == Reset) && (Reset == PORT_GetBit(KEY1_PORT, KEY1_Pin))){
				
				if(i%2== 1){
				PORT_ResetBits(LED1_PORT,LED1_Pin);
				}else{
					PORT_SetBits(LED1_PORT,LED1_Pin);
				}
				logDebug("key1Press! cnt:%d\n",i);
				i++;
			}else if((keyGroup.keys.key2 == Reset) && (Reset == PORT_GetBit(KEY2_PORT, KEY2_Pin))){
				if(i%2== 1){
				PORT_ResetBits(LED2_PORT,LED2_Pin);
				}else{
					PORT_SetBits(LED2_PORT,LED2_Pin);
				}
				logDebug("key2Press! cnt:%d\n",i);
				i++;
			}else if((keyGroup.keys.key3 == Reset) && (Reset == PORT_GetBit(KEY3_PORT, KEY3_Pin))){
				
				if(i%2== 1){
				PORT_ResetBits(LED3_PORT,LED3_Pin);
				}else{
					PORT_SetBits(LED3_PORT,LED3_Pin);
				}
				logDebug("key3Press! cnt:%d\n",i);
				i++;
			}
			
       /* clear int request flag */
      EXINT_IrqFlgClr(ExtiCh01);
		}
}

剩下的就是编译,烧录测试!

备注:

关于部分io 比如swd下载的部分管脚默认上电以后是swd功能如果需要使用io功能则需要屏蔽对应的swd功能, 参考之前的帖子或者使用代码:

		PORT_DebugPortSetting(TDO_SWO | TDI | TRST, Disable);

版权声明:本文为CSDN博主「smaller_maple」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011624093/article/details/120132308

生成海报
点赞 0

smaller_maple

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

ESP8266 无限重启踩坑

最近做了一个电子墨水屏万年历,在移植屏幕代码时遇到了esp8266无限软复位的问题,如果你的串口打印是以下图片所示,那么恭喜你问题解决了。 造成软复位的原因是因为,程序里有死循环&#xf

4路红外循迹模块使用教程

4路红外循迹模块使用教程 个人原创博客:点击浏览模块详细信息: 工作电压:DC 3.3V~5V 工作电流:尽量选择1A以上电源供电 工作温度:-10℃~50℃ 安装孔

HAL库串口中断

一,配置串口初始化 void MX_USART1_UART_Init(void) {huart1.Instance USART1;huart1.Init.BaudRate 115200;huart1.Init.WordLen