博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32 定时器用于外部脉冲计数(转)
阅读量:4695 次
发布时间:2019-06-09

本文共 3769 字,大约阅读时间需要 12 分钟。

源:

STM32 定时器(一)——定时器时间的计算

STM32的定时器是灰常NB的,也是灰常让人头晕的(当然是对于白菜来说的)。

STM32中的定时器有很多用法:

(一)系统时钟(SysTick)

设置非常简单,以下是产生1ms中断的设置,和产生10ms延时的函数:

void RCC_Configuration(void){    RCC_ClocksTypeDef RCC_ClockFreq;    SystemInit();//源自system_stm32f10x.c文件,只需要调用此函数,则可完成RCC的配置.    RCC_GetClocksFreq(&RCC_ClockFreq);    //SYSTICK分频--1ms的系统时钟中断    if (SysTick_Config(SystemFrequency / 1000))    {            while (1);   // Capture error     } }void SysTick_Handler(void)//在中断处理函数中的程序{    while(tim)    {        tim--;    }}//调用程序:Delay_Ms(10);

当然,前提是要设置好,变量tim要设置成volatile类型的。

(二)第二种涉及到定时器计数时间(TIMx)

/*TIM3时钟配置*/TIM_TimeBaseStructure.TIM_Prescaler = 2;       //预分频(时钟分频)72M/(2+1)=24MTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   //向上计数TIM_TimeBaseStructure.TIM_Period = 65535;        //装载值18k/144=125hzTIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

定时时间计算:

TIM_TimeBaseStructure.TIM_Prescaler = 2;//分频2      72M/(2+1)/2=24MHzTIM_TimeBaseStructure.TIM_Period = 65535; //计数值65535 ((1+TIM_Prescaler )/72M)*(1+TIM_Period )=((1+2)/72M)*(1+65535)=0.00273秒=366.2Hz */

注意两点(来自大虾网,未经检验)

(1)TIMx(1-8),在库设置默认的情况下,都是72M的时钟;
(2)TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
是重复计数,就是重复溢出多少次才给你来一个溢出中断,
它对应的寄存器叫TIM1 RCR.
如果这个值不配置,上电的时候寄存器值可是随机的,本来1秒中断一次,可能变成N 秒中断一次,让你超级头大!

 

STM32 定时器用于外部脉冲计数

     因为用stm32f103c8作主控制器,来控制小车,小车的转速由两路光电编码盘输入(左右各一路).因此想到外部时钟触发模式(TIM——ETRClockMode2Config)。

     可以试好好久,发现TIM1不能计数,到网上查了很久,也没有找到相关的文章,开始怀疑TIM1是不是需要特殊设置。经过很久的纠结,终于找到了问题——其实是我自己在GPIO设置的时候,后面的不小心覆盖了前面的了——没想到自己也会犯这么SB的事情。

     现总结程序如下:

第一步,设置GPIO

GPIO_InitTypeDef GPIO_InitStructure;/* PA0,PA12-> 左右脉冲输入 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_12;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度GPIO_Init(GPIOA, &GPIO_InitStructure);

注意:

(1)stm32f103c8只有TIM1_ETR(PA12,Pin33),和TIM2_CH1_ETR(PA0,Pin10)两个可以用。其它更多管脚的芯片,有更多的可以输入(如100管脚的有4个可以输入的);(2)外部时钟输入与中断无关;

(3)stm32f103c8的这个两个应用中,不需要重映射。

对于哪些需要重映射,参考数据手册。

第二步:设置RCC

RCC_ClocksTypeDef RCC_ClockFreq;SystemInit();//源自system_stm32f10x.c文件,只需要调用此函数,则可完成RCC的配置.RCC_GetClocksFreq(&RCC_ClockFreq);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

第三步,设置定时器模式

void TIM1_Configuration(void) //只用一个外部脉冲端口{    TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;    //配置TIMER1作为计数器    TIM_DeInit(TIM1);    TIM_TimeBaseStructure.TIM_Period = 0xFFFF;    TIM_TimeBaseStructure.TIM_Prescaler = 0x00;    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // Time base configuration    TIM_ETRClockMode2Config(TIM1, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);    TIM_SetCounter(TIM1, 0);    TIM_Cmd(TIM1, ENABLE);}void TIM2_Configuration(void) //只用一个外部脉冲端口{    TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;    //配置TIMER2作为计数器    TIM_DeInit(TIM2);    TIM_TimeBaseStructure.TIM_Period = 0xFFFF;    TIM_TimeBaseStructure.TIM_Prescaler = 0x00;    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // Time base configuration    TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);    TIM_SetCounter(TIM2, 0);    TIM_Cmd(TIM2, ENABLE);}

第四步,可以在主函数中读取计数器的值,其它的应用,就看具体的情况了。

u16 COUN1=0;u16 COUN2=0;int main(void){    ChipHalInit();    ChipOutHalInit();    while(1)    {       COUN1=TIM1->CNT;       COUN2=TIM2->CNT;    }}

 

转载于:https://www.cnblogs.com/LittleTiger/p/4595816.html

你可能感兴趣的文章
mini2440 U-boot 编译
查看>>
在UTF-8中,一个汉字为什么需要三个字节?
查看>>
浅谈 WPF控件
查看>>
学习ThreadLocal
查看>>
在 Visual Studio 调试器中指定符号 (.pdb) 和源文件
查看>>
直接量
查看>>
leetcode 115. 不同的子序列(Distinct Subsequences)
查看>>
三元表达式
查看>>
Go初接触之libjpeg-turbo
查看>>
python--生成器协程运算
查看>>
INFT 3030 Concurrent Programming
查看>>
小心了,这个设置会导致你的vm重启时被强制重装系统!
查看>>
邮票面值设计 (动态规划+DFS)
查看>>
解决INSTALL_FAILED_MISSING_SHARED_LIBRARY (转载)
查看>>
Linux内核高端内存
查看>>
HTML列表
查看>>
Redis集群创建报错
查看>>
DispacherServlet 的作用
查看>>
POJ - 1426(Find The Multiple)
查看>>
一张图带你看懂原始dao与SQL动态代理开发的区别-Mybatis
查看>>