硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1486|回复: 4
收起左侧

[技术讨论] STM32 RTC 只要进一次中断,就会一直重复进中断,不管有没有触发

[复制链接]

2

主题

7

回帖

13

积分

新手上路

积分
13
发表于 2024-8-4 17:26:28 | 显示全部楼层 |阅读模式
本帖最后由 SongShu007 于 2024-8-4 17:50 编辑

我使用的单片机是STM32L051C8T6,使用RTC的闹钟中断

屏幕截图 2024-08-04 171922.jpg
下面这里是中断函数
屏幕截图 2024-08-04 171904.jpg
现在单片机复位,闹钟A中断应该在5秒后触发,
但是现在的情况是,闹钟确实是成功触发了,并且标志位也成功清除了,但是之后就会一直进RTC_IRQHandler这个中断服务函数,不管有没有中断被触发,导致main函数里的其它代码运行不了,无限卡死在了中断里

下面是EXTI的配置
屏幕截图 2024-08-04 171939.jpg

代码:
[C] 纯文本查看 复制代码
void RTC_Fun(void)
{
	NVIC_SetPriority(RTC_IRQn, 0);
	NVIC_EnableIRQ(RTC_IRQn);
	EXTI->IMR  |= EXTI_IMR_IM20; // 开放20线上的中断请求
	EXTI->RTSR |= EXTI_IMR_IM20; // 允许输入线 20 上升沿触发
	EXTI->IMR  |= EXTI_IMR_IM17; // 开放17线上的中断请求
	EXTI->RTSR |= EXTI_IMR_IM17; // 允许输入线 17 上升沿触发
	
	// RTC 使用LSE
	RCC->APB1ENR |= RCC_APB1ENR_PWREN;  // 使能PWR时钟
	PWR->CR |= (0x01 << 8);    // 允许访问 RTC、RTC 备份寄存器和 RCC CSR 寄存器
	RCC->CSR |= (0x01 << 19);  // 复位RTC
	RCC->CSR &= ~(0x01 << 19);
	RCC->CSR |= (0x01 << 16);  // 使用LSE作为RTC时钟
	RCC->CSR |= (0x01 << 18);  // 使能RTC时钟
	
	RCC->CSR |= (0x01 << 8);  // 外部低速振荡器ON
	while ( (RCC->CSR & (0x01 << 9)) == 0 );
	
	RTC->WPR = 0xCA;  // 写入密钥
	RTC->WPR = 0x53;
	RTC->ISR |= (0x01 << 7);  // 进入INIT模式
	while ( (RTC->ISR &(0x01 << 6)) == 0 );
	
	RTC->CR &= ((uint32_t)~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL));
	RTC->CR |= (uint32_t)(0x00 | 0x00 | 0x00); // 24小时制 禁止输出 输出为高电平
	RTC->PRER = 0x007F00FF;  // 预分频
	
	RTC->DR = 0x00242930;  // 2024/9/30
	RTC->TR = 0x00235900;  // 23:59:00
	
	RTC->CR &= ~(0x01 << 8);    // 失能闹钟A
	RTC->ALRMAR = 0x80808005;  // 设置A闹钟
	RTC->TR = 0;               // 设置时间
	RTC->CR |= (0x01 << 8);    // 使能闹钟A
	RTC->CR |= (0x01 << 12);   // 使能闹钟A中断
	
	RTC->ISR &= ~(0x01 << 7);  // 退出INIT模式
	
	RTC->WPR = 0xFF;  // 锁起来
//	PWR->CR &= ~(0x01 << 8);
}

__IO uint8_t printf_flag = 0;

void RTC_IRQHandler(void)
{
	if ( (RTC->CR & (0x01 << 12)) )
	{
		if ( (RTC->ISR & (0x01 << 8)) )
		{
			RTC->ISR &= ~(0x01 << 8);  // 清闹钟A标志
		}
	}
}


回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2024-8-4 18:41:29 | 显示全部楼层
我找到问题了,不光要清RTC的标志位,还要把ETXI的PR寄存器清了
[C] 纯文本查看 复制代码
EXTI->PR |= EXTI_IMR_IM20;  // EXTI的也要清,不然会一直触发
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-8-5 09:22:35 | 显示全部楼层
SongShu007 发表于 2024-8-4 18:41
我找到问题了,不光要清RTC的标志位,还要把ETXI的PR寄存器清了
[mw_shl_code=c,true]EXTI->PR |= EXTI_IM ...

谢谢告知最终问题解决办法。
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2024-8-5 11:27:34 | 显示全部楼层
eric2013 发表于 2024-8-5 09:22
谢谢告知最终问题解决办法。

谢谢老大回复
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2024-12-1 23:21:39 | 显示全部楼层
SongShu007 发表于 2024-8-4 18:41
我找到问题了,不光要清RTC的标志位,还要把ETXI的PR寄存器清了
[mw_shl_code=c,true]EXTI->PR |= EXTI_IM ...

我也遇到这个问题,但是只能通过屏蔽EXTI17让它进不了中断,调试发现闹钟中断还是清除不掉
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 02:43 , Processed in 0.054711 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表