九九的STM32笔记(一)TIM模块定时器向上溢出 &am

发布者:AngelicGrace最新更新时间:2016-02-25 来源: eefocus关键字: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固件库。




  以下是定时器向上溢出示例代码:




//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管脚输出指定频率的脉冲:




//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模块  定时器  向上溢出 引用地址:九九的STM32笔记(一)TIM模块定时器向上溢出 &am

上一篇:基于WINCE S3C2440 的LED驱动程序的编写
下一篇:STM32_TEST.axf: Error: L6218E: Undefi

推荐阅读最新更新时间:2024-03-16 14:45

STM32学习第一步:点灯
前言 任务需求:使用stm32c8点亮两个led小灯并实现闪烁效果 注:本次任务包含CubeMX+hal库以及单独使用标准库两种写法完成代码构建。并最后通过Proteus仿真测试运行结果 提示:以下是本篇文章正文内容,下面案例可供参考 一、CubeMX生成keil5工程文件 工程配置: 时钟配置: 生成Keil5工程文件:注意:路径及名称不能有中文 hal库完善代码逻辑 注意:前面我们通过cubemx将工程硬件配置完毕,所以这里只需要完善软件逻辑层代码 while (1) { /* USER CODE END WHILE */ HAL_GPIO_WritePin(GPIOB,GPIO_PI
[单片机]
<font color='red'>STM32</font>学习第一步:点灯
STM32官方固件库简析
STM32固件库目录结构如下图所示: 我们主要关注的是 Libraries这个文件夹。 1、_htmresc 是ST图标,Project是一些列子和模板可以参考学习,Utilities是ST官方评估板的例程。 2、Libraries 中 CMSIS(Cortex Microcontroller Software Interface Standand)为Cortex微控制器软件接口标准。 CoreSupport 中包含内核文件 core_cm3.h, core_cm3.c 用于访问CortexM3内核 设备驱动文件 stm32f10x.h, system_stm32f10
[单片机]
CAN_总线_STM32 (1)
1:STM32_CAN 在STM32上,自带了基本扩展CAN外设,称bxCAN, CAN1:主bxCAN,用于管理bxCAN与512字节SRAM存储器之间的通信。 CAN2:从bxCAN,无法直接访问SRAM存储器,但两个bxCAN单元共享512字节SRAM存储器 波特率最高达1Mbps 支持时间触发通信 具有3个发送邮箱 具有3级深度的2个接受FIFO 可变的筛选器组(也称过滤器组,最多28个) bxCAN有三种主要的工作模式:初始化、正常、睡眠,还有测试模式和调试模式,具体看数据手册 2:bx_CAN控制器框图 筛选器组,可以设置你需要的数据,不需要的就不接受,就是为降低CPU处理CAN通信的开销。具体怎么使用的,
[单片机]
CAN_总线_<font color='red'>STM32</font> (1)
关于STM32的ADC的扫描模式
下面这张截图是 我看的 STM32参考手册的关于ADC状态寄存器ADC1_SR的资料 我经过参考网上的资料 感觉EOC位 好像是每个通道转换结束 置位。而不是像书上这样说的 通道组转换结束时置位。 就像扫描模式,应该是每一个通道转换完就置一次,而不是等所有的通道都结束了才置位的。 不知道我理解的对不对? 书上写错了的? 1L: 额!这个还真不知道 2L(版主): 回复【楼主位】 utopia779 : --------------------------------- 这个要实验一下了.以实际实验结果为准. 3L: 应该是每一个通道转换完就置一次 这样的话DMA才能在每个通道转换完立即取出数据
[单片机]
STM32之RCC配置
采用8MHz 外部HSE 时钟,程序的时钟设置参数流程如下: 1.将 RCC 寄存器重新设置为默认值:RCC_DeInit(); 2.打开外部高速时钟晶振 HSE :RCC_HSEConfig(RCC_HSE_ON); 3.等待外部高速时钟晶振工作: HSEStartUpStatus = RCC_WaitForHSEStartUp(); 4.设置 AHB 时钟 (HCLK) :RCC_HCLKConfig(RCC_SYSCLK_Div1); 5.设置APB 2时钟 (APB2) :RCC_PCLK2Config(RCC_HCLK_Div1);
[单片机]
STM32基础设计(6)---ADC转换(DMA方式)
本文简单介绍了STM32F103C8,通过DMA方式读取ADC并通过串口中断向电脑端打印出当前电源ADC的值。 现在先将设计过程的主要步骤介绍如下: 1,串口配置 2,中断配置 3,DMA配置 4,ADC配置 5,中断服务函数 6,主函数 先总结下博主在这次基础设计中犯的错误,在中断初始化函数中,没有将中断通道使能,导致电脑端没有接收到数据,发现后就去检查串口初始化函数了,结果没有发现错误,而是检查了一遍代码才发现错误。发现串口无法工作后,先核查初始化函数,如果问题没有解决,第二步,如果是串口中断方
[单片机]
STM32如何实现可调频率、占空比的PWM波形
使用两个TIM定时器: 一个输出可调频率、占空比的PWM, 一个对输出PWM脉冲计数(计时)。 1.门控方式能实现,但需要复杂的配置和计算,不推荐。 2.脉冲计数是比较实际,也是比较简单的方式; 对输出PWM脉冲计数(计时)方法有多种: 1.IO中断计数,或同步定时中断计数:用另外一个定时器,按照相同频率中断计数(类似IO中断); 2.由PWM频率和脉冲个数,计算输出全部所需的时间,使用定时中断,关闭输出PWM; 3.利用定时器外部脉冲触发(外部时钟模式2功能),计数个数为所需脉冲个数(10个脉冲),则关闭输出PWM; STM32定时器 利用阻塞延时,控制IO高低变化输出PWM这种方式就行啦,也很简单。其实,这种方法的弊端很大。
[单片机]
<font color='red'>STM32</font>如何实现可调频率、占空比的PWM波形
99秒计时+99秒倒计时(中断触发定时器
___________________________________________ 功能:99秒计时 时间2010—7—18 ___________________________________________ #include reg52.h code unsigned char tab ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char Dis_Shiwei; unsigned char Dis_Gewei; void delay(unsigned int cnt) { while(--cnt); } main() {
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved