OpenEdv-开源电子网

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

寄存器版本的TIM3输入捕获始终没效果,开发板是STM32F103ZET6

[复制链接]

1

主题

6

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2021-5-27
在线时间
8 小时
发表于 2021-6-6 00:16:33 | 显示全部楼层 |阅读模式
11金钱
使用了TIM3的CH1, CH2, CH3,以下为输入捕获初始化和中断函数,不知道问题出在了哪里,求助!
————————————————
#include "timer.h"

void TIM3_Cap_Init(u16 arr, u16 psc)
{
        RCC->APB1ENR |= 1 << 1;                        // TIM3 时钟使能1
        RCC->APB2ENR |= 1 << 2;                        // PORTA 时钟使能
        RCC->APB2ENR |= 1 << 3;                        // PORTB 时钟使能
       
        GPIOA->CRL &= 0X00FFFFFF;                // 清除 PA6, PA7 之前的设置
        GPIOA->CRL |= 0X88FFFFFF;                // PA6, PA7 输入
        GPIOA->ODR |= 0X00FFFFFF;                // PA6, PA7 下拉
        GPIOB->CRL &= 0XFFFFFFF0;                // 清除 PB0 之前的设置
        GPIOB->CRL |= 0XFFFFFFF8;                // PB0 输入
        GPIOB->ODR |= 0XFFFFFFF0;                // PB0 下拉
       
        TIM3->ARR = arr;                                // 设置计数器自动装填
        TIM3->PSC = psc;                                // 预分频器
       
        TIM3->CCMR1 |= 0X0101;                        //
        TIM3->CCMR2 |= 0X0001;                        // CC3S = 01 选择输入端, IC3 映射到 TI3 上; IC3F = 0000, 不滤波, IC3PS = 00, 不分频
       
        TIM3->CCER |= 0X0111;                        // CCxP = 0, 上升沿捕获, CCxE = 1, 允许捕获计数器的值到捕获寄存器中
        TIM3->DIER |= 0X000F;                        // 允许捕获中断, 允许更新中断
       
        TIM3->CR1 |= 0X01;                                // 使能计数器
       
        MY_NVIC_Init(2, 0, TIM3_IRQn, 2);                        // 抢占 2, 子优先级 0, 组 2
}

u8 TIM3CH1_CAPTURE_STA = 0;                        // 输入捕获状态 1
u8 TIM3CH2_CAPTURE_STA = 0;                        // 输入捕获状态 2
u8 TIM3CH3_CAPTURE_STA = 0;                        // 输入捕获状态 3
u16 TIM3CH1_CAPTURE_VAL;                        // 输入捕获值 1
u16 TIM3CH2_CAPTURE_VAL;                        // 输入捕获值 2
u16 TIM3CH3_CAPTURE_VAL;                        // 输入捕获值 3
u8 tag = 0x00;

void TIM3_IRQHandler(void)
{
        u16 tsr;
        tsr = TIM3->SR;
        if(0 == (TIM3CH1_CAPTURE_STA&0X80))                        // 还未成功捕获
        {
                if(tsr&0X01)                                                        // 溢出
                {
                        if(TIM3CH1_CAPTURE_STA&0X40)                // CH1 已经捕获到高电平
                        {
                                TIM3CH1_CAPTURE_STA |= 0X80;        // 标记 CH1 成功捕获了一次
                                TIM3CH1_CAPTURE_VAL = 0XFFFF;
                                tag = 0x00;
                        }
                        if(TIM3CH2_CAPTURE_STA&0X40)                // CH2 已经捕获到高电平了
                        {
                                TIM3CH2_CAPTURE_STA |= 0X80;        // 标记 CH2 成功捕获了一次
                                TIM3CH2_CAPTURE_VAL = 0XFFFF;
                                tag = 0x01;
                        }
                        if(TIM3CH3_CAPTURE_STA&0X40)                // CH3 已经捕获到高电平了
                        {
                                TIM3CH3_CAPTURE_STA |= 0X80;        // 标记 CH3 成功捕获了一次
                                TIM3CH3_CAPTURE_VAL = 0XFFFF;
                                tag = 0x02;
                        }
                        else
                        {
                                TIM3CH1_CAPTURE_STA++;
                                TIM3CH2_CAPTURE_STA++;
                                TIM3CH3_CAPTURE_STA++;
                        }                               
                }
                if(tsr&0x02)                                                        // 捕获 1 发生捕获
                {
                        tag = 0x00;
                        if(TIM3CH1_CAPTURE_STA&0X40)                // 捕获到一个下降沿
                        {
                                TIM3CH1_CAPTURE_STA |= 0X80;        // 标记成功捕获到一次高电平脉宽
                                TIM3CH1_CAPTURE_VAL = TIM3->CCR1;        // 获取当前捕获值
                                TIM3->CCER &= ~(1<<1);                        // CC1P = 0, 设置为上升沿捕获
                        }
                        else
                        {
                                TIM3CH1_CAPTURE_STA = 0;                // 清空
                                TIM3CH1_CAPTURE_VAL = 0;               
                                TIM3CH1_CAPTURE_STA |= 0X40;        // 标记捕获到了上升沿
                                TIM3->CNT = 0;                                        // 计数器情况
                                TIM3->CCER |= 1<<1;                                // CC1P = 1, 设置为下降沿捕获
                        }
                }
                if(tsr&0x04)                                                        // 捕获 2 发生捕获
                {
                        tag = 0x01;
                        if(TIM3CH2_CAPTURE_STA&0X40)                // 捕获到一个下降沿
                        {
                                TIM3CH2_CAPTURE_STA |= 0X80;        // 标记成功捕获到一次高电平脉宽
                                TIM3CH2_CAPTURE_VAL = TIM3->CCR2;        // 获取当前捕获值
                                TIM3->CCER &= ~(1<<5);                        // CC2P = 0, 设置为上升沿捕获
                        }
                        else
                        {
                                TIM3CH2_CAPTURE_STA = 0;                // 清空
                                TIM3CH2_CAPTURE_VAL = 0;               
                                TIM3CH2_CAPTURE_STA |= 0X40;        // 标记捕获到了上升沿
                                TIM3->CNT = 0;                                        // 计数器情况
                                TIM3->CCER |= 1<<5;                                // CC2P = 1, 设置为下降沿捕获
                        }
                }
                if(tsr&0x08)                                                        // 捕获 3 发生捕获
                {
                        tag = 0x02;
                        if(TIM3CH3_CAPTURE_STA&0X40)                // 捕获到一个下降沿
                        {
                                TIM3CH3_CAPTURE_STA |= 0X80;        // 标记成功捕获到一次高电平脉宽
                                TIM3CH3_CAPTURE_VAL = TIM3->CCR2;        // 获取当前捕获值
                                TIM3->CCER &= ~(1<<9);                        // CC3P = 0, 设置为上升沿捕获
                        }
                        else
                        {
                                TIM3CH3_CAPTURE_STA = 0;                // 清空
                                TIM3CH3_CAPTURE_VAL = 0;               
                                TIM3CH3_CAPTURE_STA |= 0X40;        // 标记捕获到了上升沿
                                TIM3->CNT = 0;                                        // 计数器情况
                                TIM3->CCER |= 1<<9;                                // CC3P = 1, 设置为下降沿捕获
                        }
                }
        }
        TIM3->SR;                                                                        // 清楚标志中断位
}


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

使用道具 举报

1

主题

6

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2021-5-27
在线时间
8 小时
 楼主| 发表于 2021-6-6 00:18:09 | 显示全部楼层
这是我的主函数
————————————————
#include "timer.h"
#include "usart.h"
#include "delay.h"

extern u8 TIM3CH1_CAPTURE_STA;
extern u8 TIM3CH2_CAPTURE_STA;
extern u8 TIM3CH3_CAPTURE_STA;
extern u16 TIM3CH1_CAPTURE_VAL;
extern u16 TIM3CH2_CAPTURE_VAL;
extern u16 TIM3CH3_CAPTURE_VAL;
extern u8 tag;

int main()
{
        u32 temp = 0;
        Stm32_Clock_Init(9);                        // 系统时钟设置
        uart_init(72, 115200);                        // 串口初始化为 115200
        delay_init(72);                                        // 延时初始化
        TIM3_Cap_Init(0XFFFF, 72-1);        // 以 1MHz 的频率计数
        while(1)
        {
                delay_ms(10);
                CH1_TRIG =CH2_TRIG=CH3_TRIG= 1;
                CH1_TRIG = 1;
                delay_us(15);
                CH1_TRIG = 0;
                CH1_TRIG =CH2_TRIG =CH3_TRIG= 0;
                switch(tag)
                {
                        case 0:
                                temp = TIM3CH1_CAPTURE_STA&0X3F;
                                temp *= 65536;
                                temp += TIM3CH1_CAPTURE_VAL;
                                printf("TAG: %x, HIGH:%d us \r\n",tag,temp);
                                TIM3CH1_CAPTURE_STA = 0;
                                break;
                        case 1:
                                temp = TIM3CH2_CAPTURE_STA&0X3F;
                                temp *= 65536;
                                temp += TIM3CH2_CAPTURE_VAL;
                                printf("TAG: %x, HIGH:%d us \r\n",tag,temp);
                                TIM3CH2_CAPTURE_STA = 0;
                                break;
                        case 2:
                                temp = TIM3CH3_CAPTURE_STA&0X3F;
                                temp *= 65536;
                                temp += TIM3CH2_CAPTURE_VAL;
                                TIM3CH3_CAPTURE_STA = 0;
                                break;
                }
               
        }
}
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2021-5-27
在线时间
8 小时
 楼主| 发表于 2021-6-6 00:36:06 | 显示全部楼层
发现了第一个问题是中断函数那里TIM3->SR没有清零 目前有数据但都是65535
回复

使用道具 举报

11

主题

2147

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4891
金钱
4891
注册时间
2015-1-10
在线时间
612 小时
发表于 2021-6-8 09:31:18 | 显示全部楼层
TIM3->SR这么一下就清除了?不需要赋值吗
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2021-6-8 23:59:06 | 显示全部楼层
学会仿真找问题
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-22 21:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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