打印

GD32定时器触发HardFault_Handler

[复制链接]
5634|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
恩成|  楼主 | 2022-11-15 18:42 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
想用GD32F330开发板的定时器1做个定时的角度反馈,设了个10K频率的定时器中断,每计数10次反馈一次角度,结果发现了加了if语句来判断后,一直触发HardFault_Handler,无法执行if里面打印角度操作;关了if语句,又没问题了,操作正常执行。然后我一步步注释代码,发现在判断语句前,用串口打印一次在进行判断,判断语句也不会触发HardFault_Handler,里面指令也是正常进行。想请教一下大伙儿,这是个什么问题?是我定时器配置错了嘛?这是我的定时器配置:
void timer1_interrupt(void)
{
    rcu_periph_clock_enable(RCU_TIMER1);
    timer_parameter_struct timer_initpara;
    timer_deinit(TIMER1);
    timer_initpara.prescaler         =35;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 199;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
        timer_initpara.repetitioncounter =0;
    timer_init(TIMER1, &timer_initpara);
         timer_interrupt_enable(TIMER1,TIMER_INT_UP);       
    timer_enable(TIMER1);
}

void nvic_config(void)
{
    nvic_irq_enable(TIMER1_IRQn,1,1);       
}

int i= 0;
uint16_t angle;
void TIMER1_IRQHandler(void)
{
        if ( timer_interrupt_flag_get(TIMER1 , TIMER_INT_UP) != RESET )
        {   
                i = i+1;
                timer_interrupt_flag_clear(TIMER1 , TIMER_INT_UP);
               if(time ==10)
                {
                angle = ssi_ReadAngle();
                printf(" %d \r\n",angle);
                i=0;
                }
        }
}

使用特权

评论回复
沙发
恩成|  楼主 | 2022-11-15 19:52 | 只看该作者
通过调试模式发现在if语句if(time ==0)打断点,可以执行到;把断点打到printf就跑不动了,进入hardfault函数了就

使用特权

评论回复
板凳
hjl2832| | 2022-11-16 08:30 | 只看该作者
你的程序中,time==10的条件是怎么来的,中断中并没有time这个变量的赋值操作,而是一个i 变量,但是这个i变量你在这里面又没调用。

使用特权

评论回复
地板
恩成|  楼主 | 2022-11-16 08:56 | 只看该作者
hjl2832 发表于 2022-11-16 08:30
你的程序中,time==10的条件是怎么来的,中断中并没有time这个变量的赋值操作,而是一个i 变量,但是这个i ...

这里是注释错了,之前用的变量定义的就是time,这里粘贴的时候注释改错了。这里把变量统一为i,还是一样的问题

使用特权

评论回复
5
ningling_21| | 2022-11-16 10:04 | 只看该作者
有可能是 ssi_ReadAngle(); 这个函数的问题

使用特权

评论回复
6
moticsoft| | 2022-11-16 10:29 | 只看该作者
不要用printf函数,改成自己的函数来发串口数据。

使用特权

评论回复
7
恩成|  楼主 | 2022-11-16 11:01 | 只看该作者
ningling_21 发表于 2022-11-16 10:04
有可能是 ssi_ReadAngle(); 这个函数的问题

我把ssi_readangle()注释了,就直接打印time的数值也不行,还是同样的问题。

使用特权

评论回复
8
恩成|  楼主 | 2022-11-16 11:12 | 只看该作者
moticsoft 发表于 2022-11-16 10:29
不要用printf函数,改成自己的函数来发串口数据。

意思是直接用UART发送嘛?

使用特权

评论回复
9
憨厚诚实大叔| | 2022-11-16 11:16 | 只看该作者
不建议在中断中串口打印,特别是触发频率高的中断。你知道执行你的串口打印语句要多少时间么。

使用特权

评论回复
10
恩成|  楼主 | 2022-11-16 11:46 | 只看该作者
憨厚诚实大叔 发表于 2022-11-16 11:16
不建议在中断中串口打印,特别是触发频率高的中断。你知道执行你的串口打印语句要多少时间么。 ...

但是中断程序的判断外打印是正常的,难道是判断+打印两个一起的时间太长了?

使用特权

评论回复
11
forgot| | 2022-11-16 13:24 | 只看该作者
调试的话可以参考一下这个贴子
https://bbs.21ic.com/icview-3265796-1-1.html

使用特权

评论回复
12
恩成|  楼主 | 2022-11-16 18:34 | 只看该作者
本帖最后由 恩成 于 2022-11-16 18:35 编辑
forgot 发表于 2022-11-16 13:24
调试的话可以参考一下这个贴子
https://bbs.21ic.com/icview-3265796-1-1.html

通过调试我的错误是0xFFFFFFF9,然后我发现两种寻址方式的报错也不一样,通过“Show Disassemblyat Address”给的错误,说我设置中断优先级这里出了问题;Call Stack又说我移位有问题;哎,真不懂啊

zhongduan.png (243.9 KB )

zhongduan.png

yiwei.png (81.98 KB )

yiwei.png

使用特权

评论回复
13
xch| | 2022-11-16 18:38 | 只看该作者
不能在中断中使用 原装的printf函数。除非你改写putchr 函数,将输出数据虚拟打印到RAM之中,然后靠高优先级中断或者DMA 从串口输出数据。还得确保输出吞吐速度远高于打印速度,避免过载。

使用特权

评论回复
14
ningling_21| | 2022-11-16 18:52 | 只看该作者
恩成 发表于 2022-11-16 11:01
我把ssi_readangle()注释了,就直接打印time的数值也不行,还是同样的问题。

试试打印函数不放到中断里

使用特权

评论回复
评论
恩成 2022-11-16 19:07 回复TA
在main函数里能够正常打印,打印放在中断里,不开if语句也能正常打印。但是把打印放在if里面就不行,除非if外事先进行了串口打印。 
15
恩成|  楼主 | 2022-11-16 19:32 | 只看该作者
本帖最后由 恩成 于 2022-11-16 19:41 编辑

我通过串口调试,然后用MSP定位到了NVIC初始化模块这部分,难道是初始化没对嘛

NVIC模块.png (409.86 KB )

NVIC模块.png

使用特权

评论回复
16
duzhiqiang521| | 2022-11-16 19:56 | 只看该作者
恩成 发表于 2022-11-16 19:32
我通过串口调试,然后用MSP定位到了NVIC初始化模块这部分,难道是初始化没对嘛 ...

定时器中断触发时间改长一点,改成1ms一次,还能打印不

使用特权

评论回复
17
duzhiqiang521| | 2022-11-16 19:58 | 只看该作者
恩成 发表于 2022-11-16 19:32
我通过串口调试,然后用MSP定位到了NVIC初始化模块这部分,难道是初始化没对嘛 ...

试试其他定时器的中断会出现这个问题不

使用特权

评论回复
18
恩成|  楼主 | 2022-11-16 20:32 | 只看该作者
duzhiqiang521 发表于 2022-11-16 19:56
定时器中断触发时间改长一点,改成1ms一次,还能打印不

改成1ms一次,发现效果更差了,之前在if语句前加个打印函数,if里面的还能照常执行。现在直接卡在中断里面,然后跳到hardfualt里面了

使用特权

评论回复
19
ayb_ice| | 2022-11-17 10:56 | 只看该作者

GD32定时器触发HardFault_Handler

printf是不可重入函数,使用要非常注意,而且这个函数很大,执行时间也长

使用特权

评论回复
20
yangxiaor520| | 2022-11-17 19:14 | 只看该作者
你的串口打印是中断模式,还是啥?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

24

帖子

0

粉丝