OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2999|回复: 2

STM32F407xx定时器(TIM1_CH1)(TIM8_CH4)输入捕获--寄存器版+标准库函数版V1.8

[复制链接]

10

主题

123

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1660
金钱
1660
注册时间
2017-10-9
在线时间
140 小时
发表于 2020-6-23 14:39:28 | 显示全部楼层 |阅读模式
本帖最后由 千湖 于 2020-6-23 14:46 编辑

寄存器版:
TIM1_CH1:
/**
  *********************************************
  * @file       tim1.c
  * @Author     WangYI
  * @version    V1.0
  * @date       2020-June-3
  * @brief      输入捕获
  *********************************************
  * @attention  None
  *********************************************
  */

/**
  * @brief   定时器1捕获中断函数
  */
void TIM1_CC_IRQHandler(void)
{   
    if((TIM1->SR) & 0x02)       // 捕获1发生捕获事件
    {
        ;    // 写捕获后需要实现的功能
    }
    TIM1->SR = 0;   // 清楚中断标志位
}


/**
  * @brief   定时器1通道1初始化
  * @param   arr    自动重装载值  
  *          psc    分频
  * @retval  None
  */
void TIM1_CH1_Init(uint16_t arr, uint16_t psc)
{
    RCC->APB2ENR |= 1 << 0;     // 使能TIM1时钟
    RCC->AHB1ENR |= 1 << 0;     // 使能GPIOA时钟

    GPIO_Set(GPIOA, PIN8, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PD);
    GPIO_AF_Set(GPIOA, 8, 1);   // PA8,AF1  TIM1

    TIM1->ARR = arr;            // 设定计算器自动重装载值
    TIM1->PSC = psc;            // 预分频器

    TIM1->CCMR1 |= 1 << 0;      // CC1S = 01 选择输入端 IC1映射到IT1上
    TIM1->CCMR1 |= 0 << 4;      // IC1F = 0000, 配置输入滤波器,不滤波
    TIM1->CCMR1 |= 0 << 2;      // IC1PS = 00 配置输入分频,0分频

    TIM1->CCER |= 0 << 1;       // CC1P = 0, 上升沿捕获
    TIM1->CCER |= 1 << 0;       // CC1E = 1, 使能捕获

    TIM1->EGR |= 1 << 0;        // 软件控制产生更新事件,使写入PSC的值立即生效,否则将会等到定时器溢出时才会生效!!!
    TIM1->DIER |= 1 << 1;       // 使能捕获1中断
    TIM1->DIER |= 1 << 0;       // 更新中断使能
    TIM1->CR1 |= 0x01;          // 使能定时器

    MY_NVIC_Init(2, 0, TIM1_CC_IRQn, 2);    // 抢占优先级2,子优先级0,组2
}


TIM8_CH4:

/**
  *********************************************
  * @file       tim8.c
  * @author     WangYI
  * @version    V1.0
  * @date       2020-June-6
  * @brief      输入捕获
  *********************************************
  * @attention  None
  *********************************************
  */

#include "tim8.h"

/**
  * @brief   定时器8捕获中断函数
  */
void TIM8_CC_IRQHandler(void)
{

    if((TIM8->SR) & 0x10)      // 捕获4发生捕获事件
    {
          ;    // 写捕获后需要实现的功能
    }
    TIM8->SR = 0;   // 清楚中断标志位
}




/**
  * @brief   定时器8通道4初始化
  * @param   arr    自动重装载值  
  *          psc    分频
  * @retval  None
  */
void TIM8_CH4_Init(uint16_t arr, uint16_t psc)
{
    RCC->APB2ENR |= 1 << 1;     // 使能TIM8时钟
    RCC->AHB1ENR |= 1 << 2;     // 使能GPIOC时钟

    GPIO_Set(GPIOC, PIN9, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PD);
    GPIO_AF_Set(GPIOC, 9, 3);   // PC9,AF3  TIM8

    TIM8->ARR = arr;            // 设定计算器自动重装载值
    TIM8->PSC = psc;            // 预分频器

    TIM8->CCMR2 |= 1 << 8;      // CC4S = 01 选择输入端 IC4映射到IT4上
    TIM8->CCMR2 |= 0 << 12;     // IC4F = 0000, 配置输入滤波器,不滤波
    TIM8->CCMR2 |= 0 << 10;     // IC4PS = 00 配置输入分频,不分频

    TIM8->CCER |= 0 << 13;      // CC4P = 0, 上升沿捕获
    TIM8->CCER |= 1 << 12;      // CC4E = 1, 使能捕获

    TIM8->EGR |= 1 << 0;        // 软件控制产生更新事件,使写入PSC的值立即生效,否则将会等到定时器溢出时才会生效!!!
    TIM8->DIER |= 1 << 4;       // 使能捕获4中断
    TIM8->DIER |= 1 << 0;       // 更新中断使能
    TIM8->CR1 |= 0x01;          // 使能定时器

    MY_NVIC_Init(2, 1, TIM8_CC_IRQn, 2);    // 抢占优先级2,子优先级0,组2
}
库函数版:
TIM1_CH1:
/**
  *********************************************
  * @file       tim1.c
  * @author     WangYI
  * @version    V1.0
  * @date       2020-June-22
  * @brief      输入捕获
  *********************************************
  * @attention  None
  *********************************************
  */


/**
  * @brief   定时器1捕获中断函数
  */
void TIM1_CC_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET)      // 发生中断
    {
        ;       //  None
    }
    TIM_ClearITPendingBit(TIM1, (TIM_IT_Update | TIM_IT_CC1));        // 清除中断标志位
}


/**
  * @brief   定时器1通道1初始化
  * @param   arr    自动重装载值  
  *          psc    分频
  * @retval  None
  */
void TIM1_CH1_Init(uint16_t arr, uint16_t psc)
{
    GPIO_InitTypeDef            GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef     TIM_TimeBaseStructure;
    TIM_ICInitTypeDef           TIM1_ICInitStructure;
    NVIC_InitTypeDef            NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);    // 使能定时器1时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);   // 使能GPIOA时钟


    /*=============================配置TIM1对应的GPIO=============================*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;               // PA8
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;            // 复用功能
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;      // 速度100MHz
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;          // 推挽复用输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;        // 无上下拉
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8 ,GPIO_AF_TIM1); // PA8复用为定时器1

    /*=============================配置TIM1基本设置=============================*/
    TIM_TimeBaseStructure.TIM_Prescaler = psc;                  // 定时器分频
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数
    TIM_TimeBaseStructure.TIM_Period = arr;                     // 自动重装载值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    /*=============================配置TIM1捕获通道1的参数=============================*/
    TIM1_ICInitStructure.TIM_Channel  = TIM_Channel_1;          // CC1S = 01 选择输入 IC1映射到TI1上
    TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;// 上升沿
    TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;    // 映射到TI1
    TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;      // 输入输入分频,不分频
    TIM1_ICInitStructure.TIM_ICFilter = 0x00;                   // 不滤波
    TIM_ICInit(TIM1, &TIM1_ICInitStructure);

    TIM_ITConfig(TIM1, (TIM_IT_Update | TIM_IT_CC1), ENABLE);     // 允许更新中断,允许CC1IE捕获中断

    TIM_Cmd(TIM1, ENABLE);      // 使能定时器1


    /*=============================配置TIM1的中断=============================*/
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;      // 定时器1捕获中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;   // 抢占优先级2
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          // 子优先级0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         // IRQn使能

    NVIC_Init(&NVIC_InitStructure);
}

TIM8_CH4:



/**
  *********************************************
  * @file       tim8.c
  * @author     WangYI
  * @version    V1.0
  * @date       2020-June-6
  * @brief      输入捕获
  *********************************************
  * @attention  None
  *********************************************
  */


/**
  * @brief   定时器8捕获中断函数
  */
void TIM8_CC_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM8, TIM_IT_CC4) != RESET)      // 发生中断
    {
        ;           // None
    }
    TIM_ClearITPendingBit(TIM8, (TIM_IT_Update | TIM_IT_CC4));        // 清除中断标志位
}


/**
  * @brief   定时器8通道4初始化
  * @param   arr    自动重装载值  
  *          psc    分频
  * @retval  None
  */
void TIM8_CH4_Init(uint16_t arr, uint16_t psc)
{
    GPIO_InitTypeDef            GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef     TIM_TimeBaseStructure;
    TIM_ICInitTypeDef           TIM8_ICInitStructure;
    NVIC_InitTypeDef            NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);    // 使能定时器8时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);   // 使能GPIOC时钟


    /*=============================配置TIM1对应的GPIO=============================*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;               // PC9
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;            // 复用功能
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;      // 速度100MHz
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;          // 推挽复用输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;        // 无上下拉
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOC, GPIO_PinSource9 ,GPIO_AF_TIM8); // PC9复用为定时器8

    /*=============================配置TIM8基本设置=============================*/
    TIM_TimeBaseStructure.TIM_Prescaler = psc;                  // 定时器分频
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数
    TIM_TimeBaseStructure.TIM_Period = arr;                     // 自动重装载值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

    /*=============================配置TIM1捕获通道1的参数=============================*/
    TIM8_ICInitStructure.TIM_Channel  = TIM_Channel_4;          // CC4S = 01 选择输入 IC1映射到TI4上
    TIM8_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;// 上升沿
    TIM8_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;    // 映射到TI1
    TIM8_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;      // 输入输入分频,不分频
    TIM8_ICInitStructure.TIM_ICFilter = 0x00;                   // 不滤波
    TIM_ICInit(TIM8, &TIM8_ICInitStructure);

    TIM_ITConfig(TIM8, (TIM_IT_Update | TIM_IT_CC4), ENABLE);     // 允许更新中断,允许CC4IE捕获中断

    TIM_Cmd(TIM8, ENABLE);      // 使能定时器8


    /*=============================配置TIM1的中断=============================*/
    NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;      // 定时器1捕获中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;   // 抢占优先级2
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          // 子优先级0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         // IRQn使能

    NVIC_Init(&NVIC_InitStructure);
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

83

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
205
金钱
205
注册时间
2019-11-12
在线时间
77 小时
发表于 2020-6-24 15:53:12 | 显示全部楼层
请教一下 这是捕获外部中断方式计数, 有没有定时器计数方式的代码
回复 支持 反对

使用道具 举报

10

主题

123

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1660
金钱
1660
注册时间
2017-10-9
在线时间
140 小时
 楼主| 发表于 2020-7-1 08:45:17 | 显示全部楼层
nstopb 发表于 2020-6-24 15:53
请教一下 这是捕获外部中断方式计数, 有没有定时器计数方式的代码

定时器计数很简单的,设置好定时器,就行了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-1 04:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表