单片机问题总结:外设初始化必须放在时钟初始化之后

本文介绍了单片机外部中断配置中遇到的问题及解决方法。通过调整时钟初始化与外设初始化的顺序,解决了外部中断无法正常工作的难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单片机问题总结:外设初始化必须放在时钟初始化之后

问题复现

最近配置IO口复用为EXTI外部中断功能,发现外部中断进不去,代码如下

static void UltrasonicGpioConfig(void)
{
	GPIO_InitTypeDef GpioInitStructure;

	RCC_APB2PeriphClockCmd(ULTRASONIC_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);

	GpioInitStructure.GPIO_Pin = ECHO_PIN;
	GpioInitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(ECHO_PORT, &GpioInitStructure);

	GpioInitStructure.GPIO_Pin = TRIG_PIN;
	GpioInitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GpioInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(TRIG_PORT, &GpioInitStructure);
}
static void UltrasonicModExtiConfig(void)
{
	EXTI_InitTypeDef EXTIInitStructure;

 	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);

	EXTIInitStructure.EXTI_Line = EXTI_Line1;
	EXTIInitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTIInitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTIInitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTIInitStructure);
}
UltrasonicModExtiConfig();	/**< 因为GPIO_EXTILineConfig()函数需要用到AFIO功能, 一定要放到AFIO时钟初始化的后面 */
UltrasonicGpioConfig();		/**< AFIO时钟初始化在这里 */

原因总结

原因就是 在外部中断初始化中GPIO_EXTILineConfig()函数需要用到AFIO功能,他在此配置了AFIO功能的寄存器,但是ARM的芯片,外设通常都是给了时钟后才能设置它的寄存器(即才能使用这个外设)。STM32、LPC1XXX等等都是这样,这么做的目的是为了省电,使用了所谓时钟门控的技术。寄存器是基于触发器的,触发器的赋值是一定需要时钟的,而寄存器的时钟是由总线时钟提供的,就是说没有总线时钟的话,你给寄存器值它是不会读入的。

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
{
  uint32_t tmp = 0x00;
  /* Check the parameters */
  assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));
  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
  
  tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));
  AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;
  AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));
}

错误改正

UltrasonicGpioConfig();		/**< AFIO时钟初始化在这里 */
UltrasonicModExtiConfig();	/**< 因为GPIO_EXTILineConfig()函数需要用到AFIO功能, 一定要放到AFIO时钟初始化的后面 */

**< 因为GPIO_EXTILineConfig()函数需要用到AFIO功能, 一定要放到AFIO时钟初始化的后面 */


可正常进入外部中断,超声波模块读取数据成功
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值