分享定时器输入捕获程序,直接操作寄存器(看手册配置成功)

2019-07-21 08:11发布

 刚刚开始做定时器输入捕获的时候在这个论坛上找了好久,都没有人分享,也有很多人问,无奈自己动手写了。花了一天的时间,这个东西真的不好写了,对比了库的例子,仿真,等。可以说付出了很多。现在完成了和大家分享。希望大家多多支持。 程序说明:1、程序中定时器4的PB6用于输出频率为1K,占空比为50%的PWM信号。
               2、定时器2的PA0用于输入捕获,当程序下到板子上,只有两个脚连在一起才会发生捕获。
               3、串口用于发送捕获的值到PC机上。

我在这里再声明一下,如果你捕获的信号不是1K,那要先经过计算ARR和分频,在这里改Capture_Init(2000,72-1);
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
49条回答
正点原子
1楼-- · 2019-07-21 11:02
回复【8楼】冰是睡着的水:
---------------------------------
人家改了代码没改注释呢...
这种现象很常见的吧?
正点原子
2楼-- · 2019-07-21 14:12
 精彩回答 2  元偷偷看……
正点原子
3楼-- · 2019-07-21 19:56
#include "stm32f10x_lib.h"
#include "sys.h"
#include "delay.h" //延时子函数
#include "usart.h"

u16   IC2Value;
u16   DutyCycle;
u16   Frequency;

void WM_Init(u16 arr,u16 psc);
void Capture_Init(u16 arr,u16 psc);
int  main(void)
{
 Stm32_Clock_Init(9); //系统时钟设置
 delay_init(72);//延时函数初始化
 uart_init(72,9600);
 WM_Init(1500,72-1);  //不分频。PWM频率=72000/1440=5Khz 
 Capture_Init(2000,72-1);
 while(1)
 {
  printf("suqingxiao ");
delay_ms(100);
 }
}

//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void WM_Init(u16 arr,u16 psc)
{    
//此部分需手动修改 IO口设置  
RCC->APB2ENR|=1<<0;    //  
RCC->APB1ENR|=1<<2;       //TIM4 时钟使能 
RCC->APB2ENR|=1<<3;    //使能PORTB时钟 
  
GPIOB->CRL&=0XF0FFFFFF;//PB6 输出  
GPIOB->CRL|=0X0B000000;//复用功能输出       
GPIOB->ODR|=1<<6;//PB6 上拉   
  
TIM4->ARR=arr;//设定计数器自动重装值   
TIM4->SC=psc;//预分频器不分频  

TIM4->CCMR1|=7<<4;  //CH1 WM2模式      
TIM4->CCMR1|=1<<3; //CH1 预装载使能       
TIM4->CCER|=1<<0;  //OC1  输出使能      
TIM4->CR1=0x0080;  //ARPE使能   

TIM4->CR1|=0x01;    //使能定时器 3  

TIM4->CCR1   = 500;  //占空比初值 =  1440*50% = 720                    



void Capture_Init(u16 arr,u16 psc)
{
//此部分需手动修改 IO口设置  
RCC->APB2ENR|=1<<0;    //  
RCC->APB1ENR|=1<<0;       //TIM2 时钟使能 
RCC->APB2ENR|=1<<2;    //使能PORTA时钟 
   
  TIM2->ARR=arr;  //设定计数器自动重装值//刚好1ms    
TIM2->SC=psc;  //预分频器,

GPIOA->CRL&=0XFFFFFFF0;//PA0 输出  
GPIOA->CRL|=0X00000004;//复用功能输出       
GPIOA->ODR|=1<<0;//PA0 上拉
  
TIM2->SMCR|=0x00D4; 
//TIM2->SMCR|= 1<<5; //MSM=1 主/从模式 
//TIM2->SMCR|= 5<<4; //TS=101 触发选择 
//TIM2->SMCR|= 4<<0; //SMS=100 复位模式

TIM2->CCMR1|=1<<0;//CC1S=01 选择输入端  
TIM2->CCMR1|=3<<4; //IC1F=0011配置输入滤波器
TIM2->CCER|=0<<1; //CC1P=0 选择有交转换边沿
TIM2->CCMR1|=0<<2; //IC1PS=00 配置输入分频 
TIM2->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中

TIM2->DIER|=1<<1;   //允许更新捕获中断
   
TIM2->CR1|=0x01;    //使能定时器2
   MY_NVIC_Init(1,3,TIM2_IRQChannel,2);//抢占1,子优先级3,组2  
}

//定时器2中断服务程序  
void TIM2_IRQHandler(void)
{              
IC2Value = TIM2->CCR1;//读取CCR1也可以清CC1IF标志位
printf("IC2Value = %d ",1000000/IC2Value);               
TIM2->SR&=~(1<<1);//清除中断标志位      
}




正点原子
4楼-- · 2019-07-21 22:24
要的就是这种精神。值得学习!
suqingxiao
5楼-- · 2019-07-21 23:28
熬出来了有点成就感,熬不出来差点抓破脑瓜,呵。
5498折戟沉沙
6楼-- · 2019-07-22 01:35
问一下,那个滤波器有什么作用啊???一直对定时器的滤波器不解???

一周热门 更多>