【转载】STM32 Timer定时器开机立即进入中断问题(HAL库)
原文链接:https://blog.csdn.net/Robotzzg/article/details/90712340
学习过程中发现配置号Timer定时器功能之后,原本应该定时到指定的时间再进入中断,结果MCU开机就会进入一次中断,不符合逻辑,所以尝试解决这个问题。
拜读各大佬的博客后发现没有HAL库的解决办法,于是转身向Google走去,找到了解决办法,分享给大家。
解决办法
在TIM初始化函数 HAL_TIM_Base_Init() 与 HAL_TIM_Base_Start_IT();
之间加一条语句 __HAL_TIM_CLEAR_FLAG(&htim7, TIM_SR_UIF); //注意将htim7改成自己的timer
其中TIM_SR_UIF是 Update interrupt Flag 寄存器。
原因就是HAL库中定时器初始化后没有更新中断标志位,__HAL_TIM_CLEAR_FLAG(&htim7, TIM_SR_UIF)后清除了更新中断标志位,此时TIM_SR_UIF为0,中断产生后TIM_SR_UIF为1。
另外
细心的朋友会发现TIM_SR_UIF其实是SR(定时器状态寄存器)的最低位,初始化时若TIM_SR_UIF为1则SR也为1,若TIM_SR_UIF为0则SR也为0,因此存在另一种解决办法:将__HAL_TIM_CLEAR_FLAG(&htim7, TIM_SR_UIF);换成htim7.Instance->SR = 0也是可以的。
示范
/**
* @brief TIM7 Initialization Function
* @param None
* @retval None
*/
void MX_TIM7_Init(uint16_t arr, uint16_t psc)
{
/* USER CODE BEGIN TIM7_Init 0 */
/* USER CODE END TIM7_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM7_Init 1 */
//(uint32_t)ceil(SECOND_WAKEUP) * 10000 / 2, 8400 - 1
/* USER CODE END TIM7_Init 1 */
htim7.Instance = TIM7;
htim7.Init.Prescaler = psc;
htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
htim7.Init.Period = arr;
htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim7) != HAL_OK)// 定时器初始化
{
Error_Handler();
}
/* USER CODE BEGIN TIM7_Init 2 */
__HAL_TIM_CLEAR_FLAG(&htim7, TIM_SR_UIF);//添加这条语句解决问题
//htim7.Instance->SR = 0; //这是另一种解决办法
HAL_TIM_Base_Start_IT(&htim7);//开启定时器中断
/* USER CODE END TIM7_Init 2 */
}
原文链接:https://blog.csdn.net/qq_40945384/article/details/106716108

TIMx->EGR = TIM_PSCReloadMode;这段语句就是把EGR寄存器的UG位配置为1,UG位说明如下

看到了对TIMX->EGR寄存器UG位的解释,就明白了,官方库中让PSC预分频器立即更新的方式竟然是粗暴的强行产生一次事件更新,程序在定时器配置之后会被强行进入一次中断。好了,到此整个问题的诊断结束,接下来探究一下解决办法。
通过上网搜索,有一种较广泛的说法是在使能定时器之前调用TIM_ClearITPendingBit(TIM1, TIM_IT_Update);但是在我的工程中使用这种办法并没有效果。
我坚信羊毛都是出在羊身上~~~~~
果然在手册上查到了TIMX->CR1寄存器

该寄存器的URS位如下解释:

TIMX->CR1寄存器的URS位特别提到了设置EGR寄存器UG位产生的更新事件。URS位配置为1时则可以筛选掉除了计数上溢、下溢以外的更新事件。
最后在定时器配置过程中,修改预分频器PSC之前的位置调用一下TIM4->CR1 |= TIM_CR1_URS;语句可完美解决定时器配置后默认进入一次中断的问题。
https://www.armbbs.cn/forum.php?mod=viewthread&tid=4187&fromuid=58
http://www.51hei.com/bbs/dpj-40940-1.html

https://www.armbbs.cn/forum.php?mod=viewthread&tid=94677&extra=page%3D1
HAL库启动定时器运行和中断是HAL_TIM_Base_Start_IT(); 但是,执行一次中断后就会停止。需要在中断函数中重新调用一次才可继续执行。然而,第二次打开的时候就直接进入中断了,定时器没有完整计数!
分析结果如下:
定时器的中断处理函数是:HAL_TIM_IRQHandler(&htim4);//以定时器4作为例子。
这个函数里面的update中断处理部分如下://update的中断处理最常用,其他的冗长代码省略。
/* TIM Update event /
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); //这个句子很诡异!查询得知这个是禁止update event中断!并不是容易理解的“清除中断标志”
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->PeriodElapsedCallback(htim);
#else
HAL_TIM_PeriodElapsedCallback(htim);
#endif / USE_HAL_TIM_REGISTER_CALLBACKS */
}
}
全程的处理函数,没有清除中断标志!!需要人为在HAL_TIM_PeriodElapsedCallback()中加上__HAL_TIM_CLEAR_FLAG(htim,TIM_FLAG_UPDATE);
总结: __HAL_TIM_CLEAR_FLAG()和__HAL_TIM_CLEAR_IT()是完全不同的意义,及其容易混淆!
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl
require'mechanize'agent=Mechanize.newlogin=agent.get('http://www.schoolnet.ch/DE/HomeDE.htm')agent.clicklogin.link_withtext:/Login/然后我得到Mechanize::UnsupportedSchemeError。 最佳答案 Mechanize不支持javascript但您可以将搜索字段添加到表单并为其分配搜索词并使用mechanize提交表单form=page.forms.firstform.add_fie
在几个项目中,我希望有一个类似rakeserver的rake任务,它将通过任何需要的方式开始为该应用程序提供服务。这是一个示例:task:serverdo%x{bundleexecrackup-p1234}end这行得通,但是当我准备停止它时,按Ctrl+c并没有正常关闭;它中断了Rake任务本身,它说rakeaborted!并给出堆栈跟踪。在某些情况下,我必须执行Ctrl+c两次。我可能可以用Signal.trap写一些东西来更优雅地中断它。有没有更简单的方法? 最佳答案 trap('SIGINT'){puts"Yourmessa
我有可变数量的表格和可变数量的行,我想让它们一个接一个地显示,但如果表格不适合当前页面,请将其放在下一页,然后继续。我已将表格放入事务中,以便我可以回滚然后打印它(如果高度适合当前页面),但我如何获得表格高度?我现在有这段代码pdf.transactiondopdf.table@data,:font_size=>12,:border_style=>:grid,:horizontal_padding=>10,:vertical_padding=>3,:border_width=>2,:position=>:left,:row_colors=>["FFFFFF","DDDDDD"]pdf.
我正在寻找一个用ruby演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent
LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L
目录一、ESP32简单介绍二、ESP32Wi-Fi模块介绍三、ESP32Wi-Fi编程模型四、ESP32Wi-Fi事件处理流程 五、ESP32Wi-Fi开发环境六、ESP32Wi-Fi具体代码七、ESP32Wi-Fi代码解读6.1主程序app_main7.2自定义代码wifi_init_sta()八、ESP32Wi-Fi连接验证8.1测试方法8.2服务器模拟工具sscom58.3测试代码8.4测试结果前言为了开发一款亚马逊物联网产品,开始入手ESP32模块。为了能够记录自己的学习过程,特记录如下操作过程。一、ESP32简单介绍ESP32是一套Wi-Fi(2.4GHz)和蓝牙(4.2)双模解决方
如果您希望在Spring中启用定时任务功能,则需要在主类上添加 @EnableScheduling 注解。这样Spring才会扫描 @Scheduled 注解并执行定时任务。在大多数情况下,只需要在主类上添加 @EnableScheduling 注解即可,不需要在Service层或其他类中再次添加。以下是一个示例,演示如何在SpringBoot中启用定时任务功能:@SpringBootApplication@EnableSchedulingpublicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.ru
有道无术,术尚可求,有术无道,止于术。本系列SpringBoot版本3.0.4本系列SpringSecurity版本6.0.2本系列SpringAuthorizationServer版本1.0.2源码地址:https://gitee.com/pearl-organization/study-spring-security-demo文章目录前言1.OAuth2AuthorizationServerMetadataEndpointFilter2.OAuth2AuthorizationEndpointFilter3.OidcProviderConfigurationEndpointFilter4.N