你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

keil5 Debug下正常,MCU直接执行异常

[复制链接]
Crazy0qwer 提问时间:2018-12-22 00:59 /
大家好,

请问keil5 Debug调试和直接运行有什么不同的地方吗?执行时间有区别吗?DEBUG时候也没有使用断点。

我有一对C8T6+24L01无线模块,大概流程是这样:
无标题.png

1、使用keil5 Debug调试时候一切正常。
2、代码烧录到MCU后,复位执行而不使用Debug调试时,传输0x56开头的小数据也是正常的,
    在传输0x55开头的一万个数据后,串口无法再接收电脑发来的任何数据。

问题基本定位在串口接收部分,因为串口接收指示灯没有反应。串口使用DMA接收。

延时函数用的这个网上找的:
void Delay_us(uint32_t nTime)
{
        SysTick->LOAD=72*nTime;                                //装载计数值,因为时钟72M,72次为1us
        SysTick->CTRL=0x00000005;                        //时钟来源为HCLK(72M),打开定时器
        while(!(SysTick->CTRL&0x00010000));                //等待计数到0
        SysTick->CTRL=0x00000004;                        //关闭定时器
}
void Delay_ms(uint32_t nTime)
{
        for(;nTime>0;nTime--)
                Delay_us(1000);
}


以下为串口接收部分代码。
  /*********************************************************************************/      
        if (DMA1_Channel5->CNDTR < DMA_URX_LEN) //无线发送
        {
            USART_RX=1;
            while (1)       //等待串口接收完成
            {
                i=DMA1_Channel5->CNDTR;               
                Delay_ms(10);
                if (i==DMA1_Channel5->CNDTR) break ;
            }
            if (RS485_RX_LEN==0){RS485_RX_LEN=DMA_URX_LEN;}

            for (j=0;j<DMA_URX_LEN-j;j++)
            {
                if(RS485_RX_BUF[j]!=0x00)
                {
                    RS485_RX_NUM=j;
                    break;
                }
            }
            RS485_RX_LEN=DMA_URX_LEN-i-RS485_RX_NUM+1;
            NRF24L01_TX_Mode();      
            switch (RS485_RX_BUF[RS485_RX_NUM])
            {
                case 0x55:
                {
                    for (i=RS485_RX_NUM+1313;i<RS485_RX_LEN;i=i+30)
                    {
                        if(i+30<RS485_RX_LEN)
                        {
                            Delay_ms(20);
                            if(NRF24L01_TxPacket(i,0,30+RadioTx_num)!=TX_OK)
                            {
                                RadioTx_failnum++;
                            }
                            RadioTx_num++;
                        }
                        else
                        {
                            Delay_ms(20);
                            if(NRF24L01_TxPacket(i,1,DMA_URX_LEN-i)!=TX_OK)
                            {
                                RadioTx_failnum++;
                            }
                            RadioTx_num++;
                        }
                    }
                    break;
                }
                case 0x56:
                {
                    for (i=RS485_RX_NUM;i<RS485_RX_LEN;i=i+30)
                    {
                        if(i+30<RS485_RX_LEN)
                        {
                            Delay_ms(20);
                            if(NRF24L01_TxPacket(i,0,30+RadioTx_num)!=TX_OK)
                            {
                                RadioTx_failnum++;
                            }
                            RadioTx_num++;
                        }
                        else
                        {
                            Delay_ms(20);
                            if(NRF24L01_TxPacket(i,1,RS485_RX_LEN-i+RS485_RX_NUM)!=TX_OK)
                            {
                                RadioTx_failnum++;
                            }
                            RadioTx_num++;
                        }
                    }
                    break;
                }
            }
            USART_RX=0;         //LED指示
            USART_DE=0;         //485芯片接收使能
            Delay_ms(5);
            MYDMA_Enable_RX();  //DMA接收使能
            Delay_ms(5);
            NRF24L01_RX_Mode(); //无线发送模式使能
        }   //无线发送
  /*********************************************************************************/   


收藏 评论7 发布时间:2018-12-22 00:59

举报

7个回答
sylar.z 回答时间:2018-12-25 09:27:18
可以重新定义下fputc()函数到串口,通过串口答应打印调试信息,确定出问题的地方

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

wuhuiskt 回答时间:2018-12-25 10:08:30
我也遇到过类似的问题,2.4GHZ是高频,容易干扰整个电路,建议从干扰上找问题

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

wh8 回答时间:2018-12-25 11:43:55
不知道你的这段代码是不是放到中断服务函数里。因为带了阻塞式延迟,这断代码运行时间是较长的;如果你把它放在中断服务里,就可能因重复进入中断服务函数次数过多,最后导致爆栈

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

Crazy0qwer 回答时间:2018-12-25 18:27:23
sylar.z 发表于 2018-12-25 09:27
可以重新定义下fputc()函数到串口,通过串口答应打印调试信息,确定出问题的地方 ...

感谢您的回答。
板子有LED指示,USART_RX=1就是点亮发光二极管,而且放在了第一行。不debug的时候传输完大数据后就不亮了。
经过测试发现问题在DMA上,CNDTR计数到0后没有能重新装载。但是我的MYDMA_Enable_RX();  函数有重新赋值。void MYDMA_Enable_RX(void)
{
    USART_DE=0;
    Delay_ms(1);
        DMA1_Channel5->CCR&=~(1<<0);       //关闭DMA传输
        DMA1_Channel5->CNDTR=DMA_URX_LEN+1; //DMA1,传输数据量
        DMA1_Channel5->CCR|=1<<0;          //开启DMA传输
}          

我加大DMA接收长度,防止它倒计到0就好了。
            while (1)       //等待串口接收完成
            {
                i=DMA1_Channel5->CNDTR;               
                Delay_ms(5);
                if (i==DMA1_Channel5->CNDTR) break ;
                if(DMA1_Channel5->CNDTR<DMA_URX_LEN-2626) break;   //接收2626个数据就退出,防止CNDTR到0.
            }

            USART_DE=1;    //485芯片设置为发送模式,停止接收数据

Crazy0qwer 回答时间:2018-12-25 18:33:10
wuhuiskt 发表于 2018-12-25 10:08
我也遇到过类似的问题,2.4GHZ是高频,容易干扰整个电路,建议从干扰上找问题 ...

谢谢您的回答。
我用示波器测量USART RX脚,可以看到数据进来,而且数据是正确的。
所以应该不是干扰问题,基本确定为DMA问题,如我楼上回复。
Crazy0qwer 回答时间:2018-12-25 18:37:54
wh8 发表于 2018-12-25 11:43
不知道你的这段代码是不是放到中断服务函数里。因为带了阻塞式延迟,这断代码运行时间是较长的;如果你把它 ...

感谢回答。
这断代码是main主函数里面的。
就是因为串口频繁进入中断,所以我才用DMA来接收。DMA也是循环检测CNDTR寄存器来判断是否接收完成而没有使用中断。
整个代码只有RTC的秒中断,而且里面只是计数和切换心跳灯亮灭而已。
已经确定是DMA计数到0无法重新装载。但是为什么debug时候正常,而不debug时候异常还没有找到原因。
addo 回答时间:2018-12-26 01:01:45
可能是初始化的问题

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版