keil5 Debug下正常,MCU直接执行异常
大家好,请问keil5 Debug调试和直接运行有什么不同的地方吗?执行时间有区别吗?DEBUG时候也没有使用断点。
我有一对C8T6+24L01无线模块,大概流程是这样:
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!=0x00)
{
RS485_RX_NUM=j;
break;
}
}
RS485_RX_LEN=DMA_URX_LEN-i-RS485_RX_NUM+1;
NRF24L01_TX_Mode();
switch (RS485_RX_BUF)
{
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(); //无线发送模式使能
} //无线发送
/*********************************************************************************/
可以重新定义下fputc()函数到串口,通过串口答应打印调试信息,确定出问题的地方 我也遇到过类似的问题,2.4GHZ是高频,容易干扰整个电路,建议从干扰上找问题 不知道你的这段代码是不是放到中断服务函数里。因为带了阻塞式延迟,这断代码运行时间是较长的;如果你把它放在中断服务里,就可能因重复进入中断服务函数次数过多,最后导致爆栈 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芯片设置为发送模式,停止接收数据
wuhuiskt 发表于 2018-12-25 10:08
我也遇到过类似的问题,2.4GHZ是高频,容易干扰整个电路,建议从干扰上找问题 ...
谢谢您的回答。
我用示波器测量USART RX脚,可以看到数据进来,而且数据是正确的。
所以应该不是干扰问题,基本确定为DMA问题,如我楼上回复。 wh8 发表于 2018-12-25 11:43
不知道你的这段代码是不是放到中断服务函数里。因为带了阻塞式延迟,这断代码运行时间是较长的;如果你把它 ...
感谢回答。
这断代码是main主函数里面的。
就是因为串口频繁进入中断,所以我才用DMA来接收。DMA也是循环检测CNDTR寄存器来判断是否接收完成而没有使用中断。
整个代码只有RTC的秒中断,而且里面只是计数和切换心跳灯亮灭而已。
已经确定是DMA计数到0无法重新装载。但是为什么debug时候正常,而不debug时候异常还没有找到原因。 可能是初始化的问题
页:
[1]