[MCU] 【AT-START-F425测评】 四、外部中断及其代码分析

kit7828   2022-4-23 22:12 楼主

AT-START-F425提供了官方例程,还是相当齐全的,在外部中断例程中,看到了2个例程,分别是外部中断以及软件触发中断

具体代码位于  AT32F425_Firmware_Library_V2.0.1\project\at_start_f425\examples\exint

外部中断触发毕竟简单,就是用户按键

具体代码及解释如下

void exint_line0_config(void)
{
  exint_init_type exint_init_struct;				//外部中断结构体

  crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);		//开启端口复用时钟,便于将端口挂在外部中断线上
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);	//开启端口A时钟,用户按键是连接的PA0
  
  scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOA, SCFG_PINS_SOURCE0);		//将PA0挂在外部中断线上

  exint_default_para_init(&exint_init_struct);						//初始化结构体变量
  exint_init_struct.line_enable = TRUE;										
  exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;		
  exint_init_struct.line_select = EXINT_LINE_0;						//外部0号中断,对应管脚0
  exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;			//上升沿触发
  exint_init(&exint_init_struct);

  nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);			//	< 4 bits for preemption priority, 0 bits for subpriority >  可见配置的是全抢占中断,没有响应中断
  nvic_irq_enable(EXINT1_0_IRQn, 1, 0);										//抢占优先级1级
}

/**
  * [url=home.php?mod=space&uid=159083]@brief[/url] exint0 interrupt handler
  * @param  none
  * @retval none
  */
void EXINT1_0_IRQHandler(void)
{
  if(exint_flag_get(EXINT_LINE_0) != RESET)							//中断标志位置位?
  {
    at32_led_toggle(LED2);															//各LED翻转
    at32_led_toggle(LED3);
    at32_led_toggle(LED4);
    exint_flag_clear(EXINT_LINE_0);											//中断标志位清零
  }
}

按下用户按钮,触发外部0号中断,中断例程中直接翻转LED2\3\4

AT32F425-2.gif

运行过程中发现,有时候会产生错乱,按照代码,应该是上升沿触发或者设置成下降沿,但有时候会出现一次按键触发两次翻转的情况,应该是按钮电路部分未做处理导致的,建议后面的开发板中按钮两端并联一颗电容。

另一个中断是软件触发中断,比较有意思

main函数设置的是全部抢占优先级

nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);            //全部抢占优先级

定时器设置函数

static void tmr1_config(void)
{
  crm_clocks_freq_type crm_clocks_freq_struct = {0};

  /* get system clock */
  crm_clocks_freq_get(&crm_clocks_freq_struct);
	//上述两行代码感觉是多余的,因为后面没有用到这个结构及数组
	//打开定时器1时钟,实际应该是打开总线,使能定时器1的总线
  crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);

  /* (systemclock / (system_core_clock/10000)) / 10000 = 1Hz(1s) */
	//由于系统主频为96Mhz,分频10000后,即system_core_clock/10000 = 9.6Khz
	//以9.6Khz计数10000个数,即9600 / 10000  = 0.96s  约为1Hz
  tmr_base_init(TMR1, 10000-1, system_core_clock/10000-1);
  tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);								//向上计数
  tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1);			//不分频
  tmr_interrupt_enable(TMR1, TMR_OVF_INT, TRUE);			//溢出中断,即0.96S产生一次中断
  nvic_irq_enable(TMR1_BRK_OVF_TRG_HALL_IRQn, 0, 0);	//前面0抢占优先级,后面0响应优先级
}

定时器中断例程

void TMR1_BRK_OVF_TRG_HALL_IRQHandler(void)
{
  if(tmr_flag_get(TMR1,TMR_OVF_FLAG) != RESET)
  {
    at32_led_toggle(LED2);													//LED2翻转		
    exint_software_interrupt_event_generate(EXINT_LINE_4);			//软件设置外部4号中断标志位
    tmr_flag_clear(TMR1,TMR_OVF_FLAG);
  }
}

外部中断4号设置

void exint_line4_config(void)
{
  exint_init_type exint_init_struct;

  crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);

  exint_default_para_init(&exint_init_struct);
  exint_init_struct.line_enable = TRUE;
  exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
  exint_init_struct.line_select = EXINT_LINE_4;
  exint_init_struct.line_polarity = EXINT_TRIGGER_FALLING_EDGE;		//EXINT_TRIGGER_FALLING_EDGE		EXINT_TRIGGER_RISING_EDGE
  exint_init(&exint_init_struct);
  exint_flag_clear(EXINT_LINE_4);
  nvic_irq_enable(EXINT15_4_IRQn, 1, 0);								//抢占优先级1,响应优先级0
}

由于是软件触发,所以觉得上升沿和下降沿的设置效果是一样的

中断例程中翻转LED3\4

void EXINT15_4_IRQHandler(void)
{
  if(exint_flag_get(EXINT_LINE_4) != RESET)
  {
    at32_led_toggle(LED3);											//LED3\4翻转
    at32_led_toggle(LED4);
    exint_flag_clear(EXINT_LINE_4);
  }
}

按照软件逻辑,定时器1溢出中断例程中软件触发外部4号中断,LED2翻转后,在外部4号中断中LED3\4翻转

这个时间差应该是感觉不到的,也就是LED2\3\4应该一起翻转,可实际效果

AT32F425-4.gif

从优先级的角度来说,定时器1号设置的中断优先级更高,外部4号中断级别要低,所以这种情况,应该是程序启动时,就产生了外部4号中断,然后定时器1才产生溢出中断。

但是还没找到外部4号中断标志位置位的相关部分。

回复评论 (6)

那外部4号中断标志是怎么回事

点赞  2022-4-24 09:14
引用: Jacktang 发表于 2022-4-24 09:14 那外部4号中断标志是怎么回事

外部4号是定时器中断中软件设置的

点赞  2022-4-24 12:56

谢谢分享!

默认摸鱼,再摸鱼。2022、9、28
点赞  2022-4-24 19:19
很用心的学习了,感谢分享。有空也得学习学习中断。
点赞  2022-4-25 08:32
引用: lugl4313820 发表于 2022-4-25 08:32 很用心的学习了,感谢分享。有空也得学习学习中断。

惭愧啊,复杂的感觉没精力,也没时间,只能整点简单的了。感谢大佬的鼓励!

点赞  2022-4-25 16:47
引用: freebsder 发表于 2022-4-24 19:19 谢谢分享!

客气了,我从网友这边也学到了不少,也谢谢你

 

点赞  2022-4-25 16:48
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复