OpenEdv-开源电子网

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

外部中断和定时器联用后的一个小BUG

[复制链接]

7

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2015-4-9
在线时间
19 小时
发表于 2017-7-17 20:32:41 | 显示全部楼层 |阅读模式
10金钱
void TIM5_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET)
        {
                g_mode.mode();
        }
        TIM_ClearITPendingBit(TIM5,TIM_IT_Update);
}

这是一个函数定时访问

void EXTI1_IRQHandler(void)
{
        g_exti.exti_flag ++;                                                                                                                                                                                                               
        g_mode.MODE_data.exti_count = g_exti.exti_flag;                                                                                                                                                                                                                                       
        EXTI_ClearITPendingBit(EXTI_Line1);                                                                                                                                                                 
}

这是一个外部中断  记下访问次数赋给  g_mode.MODE_data.exti_count

void Mode(void)
{
        if(g_mode.MODE_data.timer1_flag == 0)
        {
                g_mode.MODE_data.timer1_flag = 1;                                                                                                                                                                        //ÅD¶Ï±êÖ¾ÖÃ1
               
                if(g_mode.MODE_data.exti_count--)
                {                       
                                GPIO_ResetBits(GPIOA,GPIO_Pin_7);        //下面是另一个定时器写的定时函数
                                SoftwareTimers.Register_fun(g_motor.motor_left, 1, 0);
                               
                                SoftwareTimers.Register_fun(g_camera.camera_on, 5, 0);
                                SoftwareTimers.Register_fun(g_camera.camera_off, 10, 0);
                               
                                SoftwareTimers.Register_fun(g_motor.motor_mid, 15, 0);
                               
                                SoftwareTimers.Register_fun(g_camera.camera_on, 20, 0);
                                SoftwareTimers.Register_fun(g_camera.camera_off, 25, 0);
                               
                                SoftwareTimers.Register_fun(g_motor.motor_right, 30, 0);
                               
                                SoftwareTimers.Register_fun(g_camera.camera_on, 35, 0);
                                SoftwareTimers.Register_fun(g_camera.camera_off, 40, 0);
                               
                                SoftwareTimers.Register_fun(g_motor.motor_mid, 45, 0);
                               
                                SoftwareTimers.Register_fun(g_mode.clear_flag, 46, 0);
                }
        }
}

void Clear_Flag(void)
{
        g_mode.MODE_data.timer1_flag = 0;
}


这是那个定时触发的函数,标志最后清除

#ifndef __EXTI_H
#define __EXTI_H

#include "user_conf.h"  
#define pulse_mode_rising         1                               
#define capture_pulse 1

typedef struct
{
        u32 exti_flag;
        void(*exti_init)(void);       
}Exti_Fun;

void Exti_Init_Fun(void);

extern Exti_Fun g_exti;

#endif  


头文件exti.h

#ifndef __MODE_H
#define __MODE_H

#include "user_conf.h"  

typedef struct
{
        u8 timer1_flag;
        u32 exti_count;
}modedata;


typedef struct
{
  modedata MODE_data;
        void(*mode)(void);
        void(*clear_flag)(void);
}Mode_Fun;

void Mode(void);
void Clear_Flag(void);

extern Mode_Fun g_mode;

#endif


头文件 mode.h

现在的BUG是  外部中断来了之后  函数在if(g_mode.MODE_data.exti_count--) 判断不过,实时调试g_mode.MODE_data.exti_count为5为6仍进不去
我如果我把if(g_mode.MODE_data.exti_count--) 去掉
会定时触发


请各位看一下




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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165462
金钱
165462
注册时间
2010-12-1
在线时间
2114 小时
发表于 2017-7-18 00:53:21 | 显示全部楼层
回复

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3348
金钱
3348
注册时间
2013-5-28
在线时间
468 小时
发表于 2017-7-18 09:29:13 | 显示全部楼层
库函数我不用的,但是
if(g_mode.MODE_data.exti_count--)
我建议你别贪图省事...嵌入式需要理解计算机是怎么去理解数据的
if(g_mode.MODE_data.exti_count>0)
{
    g_mode.MODE_data.exti_count--;
}
回复

使用道具 举报

25

主题

683

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1351
金钱
1351
注册时间
2012-4-25
在线时间
195 小时
发表于 2017-7-18 18:11:19 | 显示全部楼层
一般出现这个问题和编译器的优化选项有关,要么关闭优化,要么加关键字volatile.
再回复楼上,f(g_mode.MODE_data.exti_count--)  这写法是可以的,如果 这都不行的话,那程序都不用写了
1-1
回复

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3348
金钱
3348
注册时间
2013-5-28
在线时间
468 小时
发表于 2017-7-21 09:03:49 | 显示全部楼层
mygod 发表于 2017-7-18 18:11
一般出现这个问题和编译器的优化选项有关,要么关闭优化,要么加关键字volatile.
再回复楼上,f(g_mode.MO ...

从逻辑上来说,if中判定的语句是要执行的,你一个递减在那里,有一定的可能会导致g_mode.MODE_data.exti_coun在0时被简称255吧?假设如果是8位的话,而且这个到底怎么样应该还跟编译器有关
回复

使用道具 举报

25

主题

683

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1351
金钱
1351
注册时间
2012-4-25
在线时间
195 小时
发表于 2017-7-21 09:09:31 | 显示全部楼层
聚东风 发表于 2017-7-21 09:03
从逻辑上来说,if中判定的语句是要执行的,你一个递减在那里,有一定的可能会导致g_mode.MODE_data.exti_cou ...

为0 时候进不了 if() 里面了
1-1
回复

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3348
金钱
3348
注册时间
2013-5-28
在线时间
468 小时
发表于 2017-7-21 09:16:57 | 显示全部楼层
mygod 发表于 2017-7-21 09:09
为0 时候进不了 if() 里面了

QQ图片20170721091525.png
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-7-21 10:27:26 | 显示全部楼层
我想说 不可能进不去的,试试设一个简单的变量,不要这么多的结构体
回复

使用道具 举报

1

主题

101

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2017-5-10
在线时间
55 小时
发表于 2017-7-23 20:39:05 来自手机 | 显示全部楼层
试试在定义exti_coun前面加volatile,原因可以百度volatile的用处
回复

使用道具 举报

7

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2015-4-9
在线时间
19 小时
 楼主| 发表于 2017-7-31 11:19:44 | 显示全部楼层
wxjhby 发表于 2017-7-21 10:27
我想说 不可能进不去的,试试设一个简单的变量,不要这么多的结构体

  受教了   但是如果一个比较大的工程  还是喜欢把所有的变量封装到一个结构体中,这样这个变量的作用就一目了然
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-4-19 22:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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