前期准备:
STM32CubeMX
STM32RCT6核心板
IDE Keil(MDK-ARM)
STM32CubeMX部分
1 配置时钟
选择STM32F103RCTx系列芯片,配置时钟的同时会自动配置IO口引脚
在这里插入描述
将HCLK设置为最大频率72MHz
在这里插入描述
2配置TIM
在这里插入描述
Internal Clock(内部时钟)
Prtscaler (定时器分频系数) : 71
Counter Mode(计数模式) Up(向上计数模式)
Counter Period(自动重装载值) : 999
CKD(时钟分频因子) :No Division (不分频 )
auto-reload-preload(自动重装载) : Enable (使能)
在这里插入描述
勾选update interrupt(更新中断)
1 定时器溢出时间计算公式:
在这里插入描述
Tout:中断溢出的时间
arr:自动重装载值
psc:定时器分频系数
Tclk:时钟频率
Tout = ((71+1)(999+1))/72 us
Tout = ( 72 1000 ) / 72 us
1000us = 1ms
所以这里我们的定时时间为:1ms
也就是说单片机1ms进入一次定时器中断
2 定时器计数模式:
向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
向上/向下计数模式(中央对齐模式):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
在这里插入描述
2 计数时钟:
内部时钟(TIMx_CLK):
外部时钟模式1:外部捕捉比较引脚(TIx)
外部时钟模式2:外部引脚输入(TIMx_ETR)
内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。
3配置IO口
在这里插入描述
将PB0设置为:
低电平
Output模式
既不上拉也不下拉
响应速度低
4 工程生成
在这里插入描述
在这里插入描述
工程管理依旧是这几个选项,然后GENERATE CODE,STM32CubeMX部分完成。
MDK 5部分
HAL_TIM_IRQHandler(&htim1);//定时器中断处理函数
此函数的作用是判断中断是否正常,是哪一类定时器中断(溢出中断/捕获中断/PWM中断…),然后进入相应的中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef htim)//定时器溢出中断回调函数
定时器中断时,每进行完一个中断,并不会立刻退出,而是会进入到中断回调函数中
点开mainc在这里插入描述
在如图位置上添加
HAL_TIM_Base_Start_IT(&htim1);//开启定时器1
1
1
然后再timc文件中,添加
/ USER CODE BEGIN 0 /
uint16_t Tim_cnt = 0; //定时器计数
/ USER CODE END 0 /
1
2
3
1
2
3
然后在timc文件中重写
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef htim)函数
在这里插入描述
/ USER CODE BEGIN 1 /
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef htim)
{
if (htim->Instance == htim1Instance)
{
Tim_cnt++;
if(Tim_cnt==500) //05s进行一次下列代码
{
Tim_cnt=0; //清0
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
}
}
}
/ USER CODE END 1 /
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
设一个全局变量,每进一次中断+1,因为1ms进入一次中断,所以当Tim_cnt=500的时候(即05s)写入我们需要运行的代码(不要忘记清0)
编译下载时需要选择相对应的下载器,勾选以下
在这里插入描述
运行即可
本期工程文档——>Gitee
在这里插入描述
前面省略了
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/ 通道1工作模式 /
TIM_OCStructInit(&TIM_OCInitStructure); //其它默认值
//110:PWM模式1- 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;
TIM_OCInitStructureTIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructureTIM_OCPolarity = TIM_OCPolarity_High; //TIM_OCPolarity_Low;//输出极性0:高电平有效
TIM_OCInitStructureTIM_OutputState = TIM_OutputState_Enable;//输出
TIM_OCInitStructureTIM_Pulse = 50(SYSTEM_CLOCK/1000000); //50us高电平
//1通道pwm
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC3FastConfig(TIM3, TIM_OCFast_Enable);
TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable); //通道预装载使能
/ //12模拟输入捕获上升下降沿/
TIM_ICInitStructureTIM_Channel = TIM_Channel_4;
TIM_ICInitStructureTIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructureTIM_ICSelection = TIM_ICSelection_DirectTI;//TIM_ICSelection_IndirectTI;//
TIM_ICInitStructureTIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructureTIM_ICFilter = 0x08;
TIM_ICInit(TIM3, &TIM_ICInitStructure); TIM_ClearFlag(TIM3,TIM_FLAG_Update|TIM_FLAG_CC1|TIM_FLAG_CC2|TIM_FLAG_CC3|TIM_FLAG_CC4);
TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC4, ENABLE);
TIM_Cmd(TIM3, ENABLE);
再加中断配置,不保证一定行大概意思就是这样了
不会吧,参考手册里是这样说的:
软件可以读此位,也可以通过写’0’清除此位,写’1’对此位无影响
所以是可以写0清零的, 实在不行可以通过读相应寄存器清零,如读TIMx_CCRx可以清零CCxIF位
实现10ms定时需要使用STM32的定时器模块,并且要将系统时钟频率设置为足够高的值。以下是实现10ms定时的步骤:
设置系统时钟:使用RCC寄存器设置PLL倍频系数,将系统时钟频率设置为72 MHz。
选择合适的定时器:在STM32中有多个定时器可供选择,根据需要选取合适的定时器。假设在这里我们选用TIM2定时器。
配置定时器:使用TIM2的相关寄存器配置定时器的时钟源、分频系数和计数周期等参数。可以将定时器的时钟源设置为内部时钟,将分频系数设置为7200,则每秒钟定时器计数器会自增100次。
启动定时器:将TIM2的控制寄存器使能,并设置定时器计数器初值为0。
编写中断服务程序:在定时器溢出时会产生中断请求,在中断服务程序中可以进行相应的 *** 作。例如,可以使用GPIO输出引脚控制LED闪烁。
启用全局中断:调用__enable_irq();函数启用全局中断
在以上代码中,使用了TIM2定时器,并将计数周期设置为100,即每秒钟会产生10次溢出中断。在中断服务程序中,控制LED引脚状态的改变,从而实现了10ms的定时效果。
#include "stm32f10xh"
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
//定时器中断执行的内容
GPIO_WriteBit(GPIOC, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)));
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
int main(void)
{
//开启GPIOC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
//配置LED引脚为推挽输出模式
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructureGPIO_Pin = GPIO_Pin_13;
GPIO_InitStructureGPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructureGPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//开启TIM2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//设置定时器参数
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStructTIM_Prescaler = 7200-1; //预分频系数
TIM_TimeBaseInitStructTIM_Period = 100-1; //自动重载计数值
TIM_TimeBaseInitStructTIM_ClockDivision = TIM_CKD_DIV1; //时钟分割
TIM_TimeBaseInitStructTIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
//使能TIM2中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
//启动TIM2定时器
TIM_Cmd(TIM2, ENABLE);
//注册中断服务程序
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructureNVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructureNVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructureNVIC_IRQChannelSubPriority = 0;
NVIC_InitStructureNVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//启用全局中断
__enable_irq();
while(1)
{
//主循环程序
}
}
谢谢您的指点,是不是
前者来自于
CCR3
的匹配
(或捕捉)
触发之后CNT计数就,不再向ARR上累计了,而是CNT
重新计数了?而通常是计数器溢出是指CNT计数到ARR是时候产生中断,这样理解对吗
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Disable); //如果使能则定时器等待下一次定时器溢出才会发生变化 -- 同步
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable); //不使能则会立即发生变化 -- 异步
所以不使能的话就会立刻变化,今天遇到相同的问题翻芯片手册才看到这个。
以上就是关于stm32获取定时器溢出状态但不中断全部的内容,包括:stm32获取定时器溢出状态但不中断、想用stm32的TIM3的通道3做PWM输出,通道4做捕获输入,但是不知道怎么使用,请高手指教!、如何清除STM32 定时器TIM1的状态寄存 (能解按要求决问题有赏)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)