STM32单片机TIM模块定时器向上溢出的输出比较

首先我们必须肯定st公司的实力,也承认stm32的确是一款非常不错的cortex-m3核单片机,但是,他的手册实在是让人觉得无法理解,尤其是其中的tim模块,没有条理可言,看了两天几乎还是不知所云,让人很是郁闷。同时配套的固件库的说明也很难和手册上的寄存器对应起来,研究起来非常费劲!功能强大倒是真的,但至少也应该配套一个让人看的明白的说明吧~~
两天时间研究了stm32定时器的最最基础的部分,把定时器最基础的两个功能实现了,余下的功能有待继续学习。
首先有一点需要注意:fwlib固件库目前的最新版应该是v2.0.x,v1.0.x版本固件库中,tim1模块被独立出来,调用的函数与其他定时器不同;在v2.0系列版本中,取消了tim1.h,所有的tim模块统一调用tim.h即可。网络上流传的各种代码有许多是基于v1版本的固件库,在移植到v2版本固件库时,需要做些修改。本文的所有程序都是基于v2.0固件库。
以下是定时器向上溢出示例代码:
c语言: tim1模块产生向上溢出事件
//step1.时钟设置:启动tim1
rcc_apb2periphclockcmd(rcc_apb2periph_tim1, enable);
//step2.中断nvic设置:允许中断,设置优先级
nvic_initstructure.nvic_irqchannel = tim1_up_irqchannel; //更新事件
nvic_initstructure.nvic_irqchannelpreemptionpriority = 0; //抢占优先级0
nvic_initstructure.nvic_irqchannelsubpriority = 1; //响应优先级1
nvic_initstructure.nvic_irqchannelcmd = enable; //允许中断
nvic_init(&nvic_initstructure); //写入设置
//step3.tim1模块设置
void tim_configuration(void)
{
tim_timebaseinittypedef tim_baseinitstructure;
tim_ocinittypedef tim_ocinitstructure;
//tim1 使用内部时钟
//tim_internalclockconfig(tim1);
//tim1基本设置
//设置预分频器分频系数71,即apb2=72m, tim1_clk=72/72=1mhz
//tim_period(tim1_arr)=1000,计数器向上计数到1000后产生更新事件,计数值归零
//向上计数模式
//tim_repetitioncounter(tim1_rcr)=0,每次向上溢出都产生更新事件
tim_baseinitstructure.tim_period = 1000;
tim_baseinitstructure.tim_prescaler = 71;
tim_baseinitstructure.tim_clockdivision = 0;
tim_baseinitstructure.tim_countermode = tim_countermode_up;
tim_baseinitstructure.tim_repetitioncounter = 0;
tim_timebaseinit(tim1, &tim_baseinitstructure);
//清中断,以免一启用中断后立即产生中断
tim_clearflag(tim1, tim_flag_update);
//使能tim1中断源
tim_itconfig(tim1, tim_it_update, enable);
//tim1总开关:开启
tim_cmd(tim1, enable);
}
//step4.中断服务子程序:
void tim1_up_irqhandler(void)
{
gpioc-》odr ^= (1《《4); //闪灯
tim_clearitpendingbit(tim1, tim_flag_update); //清中断
}
下面是输出比较功能实现tim1_ch1管脚输出指定频率的脉冲:
c语言: tim1模块实现输出比较,自动翻转并触发中断
//step1.启动tim1,同时还要注意给相应功能管脚启动时钟
rcc_apb2periphclockcmd(rcc_apb2periph_tim1, enable);
rcc_apb2periphclockcmd(rcc_apb2periph_gpioa, enable);
//step2. pa.8口设置为tim1的oc1输出口
gpio_initstructure.gpio_pin = gpio_pin_8;
gpio_initstructure.gpio_mode = gpio_mode_af_pp;
gpio_initstructure.gpio_speed = gpio_speed_50mhz;
gpio_init(gpioa, &gpio_initstructure);
//step3.使能tim1的输出比较匹配中断
nvic_initstructure.nvic_irqchannel = tim1_cc_irqchannel;
nvic_initstructure.nvic_irqchannelpreemptionpriority = 1;
nvic_initstructure.nvic_irqchannelsubpriority = 1;
nvic_initstructure.nvic_irqchannelcmd = enable;
nvic_init(&nvic_initstructure);
//step4. tim模块设置
void tim_configuration(void)
{
tim_timebaseinittypedef tim_baseinitstructure;
tim_ocinittypedef tim_ocinitstructure;
//tim1基本计数器设置
tim_baseinitstructure.tim_period = 0xffff; //这里必须是65535
tim_baseinitstructure.tim_prescaler = 71; //预分频71,即72分频,得1m
tim_baseinitstructure.tim_clockdivision = 0;
tim_baseinitstructure.tim_countermode = tim_countermode_up;
tim_baseinitstructure.tim_repetitioncounter = 0;
tim_timebaseinit(tim1, &tim_baseinitstructure);
//tim1_oc1模块设置
tim_ocstructinit(& tim_ocinitstructure);
tim_ocinitstructure.tim_ocmode = tim_ocmode_toggle; //管脚输出模式:翻转
tim_ocinitstructure.tim_pulse = 2000; //翻转周期:2000个脉冲
tim_ocinitstructure.tim_outputstate = tim_outputstate_enable; //使能tim1_ch1通道
tim_ocinitstructure.tim_ocpolarity = tim_ocpolarity_high; //输出为正逻辑
tim_oc1init(tim1, &tim_ocinitstructure); //写入配置
//清中断
tim_clearflag(tim1, tim_flag_cc1);
//tim1中断源设置,开启相应通道的捕捉比较中断
tim_itconfig(tim1, tim_it_cc1, enable);
//tim1开启
tim_cmd(tim1, enable);
//通道输出使能
tim_ctrlpwmoutputs(tim1, enable);
}
step5.中断服务子程序
void tim1_cc_irqhandler(void)
{
u16 capture;
if(tim_getitstatus(tim1, tim_it_cc1) == set)
{
tim_clearitpendingbit(tim1, tim_it_cc1 );
capture = tim_getcapture1(tim1);
tim_setcompare1(tim1, capture + 2000);
//这里解释下:
//将tim1_ccr1的值增加2000,使得下一个tim事件也需要2000个脉冲,
//另一种方式是清零脉冲计数器
//tim_setcounter(tim2,0x0000);
}
}
关于tim的操作,要注意的是stm32处理器因为低功耗的需要,各模块需要分别独立开启时钟,所以,一定不要忘记给用到的模块和管脚使能时钟,因为这个原因,浪费了我好多时间阿~~!
九九的stm32笔记(二)tim模块产生pwm
这个是stm32的pwm输出模式,stm32的tim1模块是增强型的定时器模块,天生就是为电机控制而生,可以产生3组6路pwm,同时每组2路pwm为互补,并可以带有死区,可以用来驱动h桥。
下面的代码,是利用tim1模块的1、2通道产生一共4路pwm的代码例子,类似代码也可以参考st的固件库中相应example
c语言: tim1模块产生pwm,带死区
//step1.开启tim和相应端口时钟
//启动gpio
rcc_apb2periphclockcmd(rcc_apb2periph_gpioa | rcc_apb2periph_gpiob | \
rcc_apb2periph_gpioc | rcc_apb2periph_gpiod,\
enable);
//启动afio
rcc_apb2periphclockcmd(rcc_apb2periph_afio, enable);
//启动tim1
rcc_apb2periphclockcmd(rcc_apb2periph_tim1, enable);
//step2. gpio做相应设置,为af输出
//pa.8/9口设置为tim1的oc1输出口
gpio_initstructure.gpio_pin = gpio_pin_8 | gpio_pin_9;
gpio_initstructure.gpio_mode = gpio_mode_af_pp;
gpio_initstructure.gpio_speed = gpio_speed_50mhz;
gpio_init(gpioa, &gpio_initstructure);
//pb.13/14口设置为tim1_ch1n和tim1_ch2n输出口
gpio_initstructure.gpio_pin = gpio_pin_13 | gpio_pin_14;
gpio_initstructure.gpio_mode = gpio_mode_af_pp;
gpio_initstructure.gpio_speed = gpio_speed_50mhz;
gpio_init(gpiob, &gpio_initstructure);
//step3. tim模块初始化
void tim_configuration(void)
{
tim_timebaseinittypedef tim_baseinitstructure;
tim_ocinittypedef tim_ocinitstructure;
tim_bdtrinittypedef tim_bdtrinitstructure;
//tim1基本计数器设置(设置pwm频率)
//频率=tim1_clk/(arr+1)
tim_baseinitstructure.tim_period = 1000-1;
tim_baseinitstructure.tim_prescal

人工智能开始退潮?资本偏爱哪一种AI?
瑞丰推出全新一代ErP新能效产品,助力能源革命
环网柜是中压成套设备电气设备,它的优势是什么
Intel指责AMD公布的游戏性能都是精心挑选过的
什么是去中心化金融DeFi它有什么应用
STM32单片机TIM模块定时器向上溢出的输出比较
小程序开发新选择!华为云耀云服务器 L 实例快人一步
关于差模共模电感的详细说明
以单片机为控制核心的缓降器设计
互联网金融与金融产业化之间有什么联系
我国光伏行业蓬勃发展,分布式光伏新增装机1224万千瓦
关于SMT的主要工作流程,它的流程介绍
欧姆龙开关在智能锁领域中的应用是怎样的
M30系列OHV电缆振荡波局放测试系统的性能特点
特斯拉Model 3更换电池成本逾10万人民币
或非门,或非门是什么意思
邬贺铨院士“十问”边缘计算
算法级可编程性技术 可固定功能功率 性能和面积效率
惠普企业(HPE)宣布了五项新的重返工作解决方案
可适配多企业需求,华为云等保合规安全解决方案选择灵活!