OpenEdv-开源电子网

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

为什么我的输入捕获会捕获不到部分电平呢?

[复制链接]

8

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
108
金钱
108
注册时间
2023-2-8
在线时间
23 小时
发表于 2023-6-4 12:20:13 | 显示全部楼层 |阅读模式
为什么我的输入捕获会捕获不到部分电平呢?


我用PA0输出一个1khz,占空比80%的波形,我用输入捕获能捕获到高电平80,低电平20的数据出来
但是我用源码去捕获一个433接收模块时,老是捕获不完整,是不是因为433接收模块一开始会有很多杂波的原因?要怎么解决呢?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8462
金钱
8462
注册时间
2020-5-11
在线时间
3904 小时
发表于 2023-6-5 11:00:34 | 显示全部楼层
printf就不对,它是利用串口发出数据,串口假如是9600的波特率,那么发送1字节就约需1ms的时间,
你发送那一串字符至少有5字节吧,那就需要耗费5ms时间,你说你在中断里待了这么长的时间,那下一个中断还能及时响应不?
专治疑难杂症
回复 支持 2 反对 0

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8462
金钱
8462
注册时间
2020-5-11
在线时间
3904 小时
发表于 2023-6-5 09:49:32 | 显示全部楼层
上代码
回复 支持 反对

使用道具 举报

8

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
108
金钱
108
注册时间
2023-2-8
在线时间
23 小时
 楼主| 发表于 2023-6-5 10:44:11 | 显示全部楼层
本帖最后由 caihaijie 于 2023-6-5 10:58 编辑
void Tele_Tim_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_ICInitTypeDef TIM3_ICInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM3时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟


    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_Init(GPIOA, &GPIO_InitStructure); //采用的是PA7用来输入
    GPIO_ResetBits(GPIOA, GPIO_Pin_7); //将PA7设置成低电平

    //初始化定时器3 TIM3
    TIM_TimeBaseStructure.TIM_Period = 0xfff;                     //设定计数器自动重装值
    TIM_TimeBaseStructure.TIM_Prescaler = 720 -1;                  //预分频器
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //设置时钟分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);             //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

    //初始化TIM3输入捕获参数
    TIM3_ICInitStructure.TIM_Channel = TIM_Channel_2;                //CC1S=01         选择输入端 IC1映射到TI1上
    TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;     
    TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
    TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;           //配置输入分频,不分频
    TIM3_ICInitStructure.TIM_ICFilter = 0x00;                        //IC1F=0000 配置输入滤波器 不滤波
    TIM_ICInit(TIM3, &TIM3_ICInitStructure);

    //中断分组初始化
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;           //TIM3中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        //从优先级0级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);                           //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

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

    TIM_Cmd(TIM3, ENABLE); //使能定时器5

}
u8 overload=0;  //定时器溢出计数
u8 capture_status=0; //定时捕获状态
u32 high_time;  //高电平时间
u8 capture_val=0 , t = 0;

void TIM3_IRQHandler(void)
{

    if ((TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) & capture_status)//在测量高电平期间产生更新中断
    {
        overload++;
    }
    if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)  //触发捕获
    {

        switch (capture_status)
        {
        case 0: //第一个状态  捕获到高电平
            TIM_SetCounter(TIM3, 0); //将当前计数器的值CNT设置成0
                        if(t == 0)
                        {
                                TIM_OC2PolarityConfig(TIM3, TIM_ICPolarity_Rising);
                                t = 1;
                        }
                        else if(t == 1)
                        {
                                TIM_OC2PolarityConfig(TIM3, TIM_ICPolarity_Falling);
                                t = 0;
                        }
                        

            capture_status = 1;//切换到下一个状态
            break;

        case 1://第二个状态  捕获到低电平
            capture_val = TIM_GetCapture2(TIM3); //获取当前CCR1的值 也就是高电平的时间(不包含溢出的时间)
            high_time = capture_val + 65536 * overload;  //计算高电平的时间 包含高电平定时器溢出的时间
                        printf("\r\n%d", capture_val);

                        TIM_OC2PolarityConfig(TIM3, TIM_ICPolarity_Rising);
                        overload = 0;  
            capture_val = 0;
            high_time = 0;
            capture_status = 0;

            break;
        }
    }
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2 | TIM_IT_Update); //清除中断标志位
}




麻烦看一下我这个地方那里出错了
回复 支持 反对

使用道具 举报

8

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
108
金钱
108
注册时间
2023-2-8
在线时间
23 小时
 楼主| 发表于 2023-6-5 20:29:33 | 显示全部楼层
LcwSwust 发表于 2023-6-5 11:00
printf就不对,它是利用串口发出数据,串口假如是9600的波特率,那么发送1字节就约需1ms的时间,
你发送那一串 ...

我是用printf打印出来波形,如果我去掉printf的话,直接用if判断电平时间,如果是我要的时间,就直接打印出来,应该也是可以吧?这个中断我是用于捕获按键值,因为433杂波很多,所以我还要另外一个内部中断定时100us进这个捕获按键中断判断是否有按键按下
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-25 00:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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