问题描述:
1.之前自己建立一个stm8的工程A,使用stm8的库函数,可以在线单步调试。
2.后面又多了一个工程B,忘记了是新建的还是从工程A拷贝过来的了,反正一在线调试就会程序跑跑飞,也不是一开始就跑非的,前面几步还是可以正常走,走着走着就会跑飞了。
3.工程A和工程B的代码基本功能一样。
4.我的怀疑有两点,一个是工程配置的问题,还有一点就是代码不一致,引出的在线debug跑飞的情况。
问题解决:
1.我新建一个工程C,使用可以在线debug的A工程的代码 ,结果是可以在线单步调试;
2.于是我对比着工程C和工程B的代码,一点一点的合并(此过程相当痛苦。一个下午加一个晚上的时间)。终于水落石出了。是代码的问题。
3.stm8串口库有个坑,默认的串口中断清除函数是USART_ClearITPendingBit(),具体如下:
void USART_ClearITPendingBit(USART_TypeDef* USARTx, USART_IT_TypeDef USART_IT)
{
uint8_t bitpos = 0x00, itmask = 0x00;
assert_param(IS_USART_CLEAR_IT(USART_IT));
bitpos = (uint8_t)( (uint8_t)((uint8_t)USART_IT & (uint8_t)0xF0) >> 0x04);
itmask = (uint8_t)( (uint8_t)0x01 << bitpos);
/*< Clear RXNE or TC pending bit */
USARTx->SR = (uint8_t)~itmask;
}
不知道什么原因,这个默认的库函数会导致在线debug时程序跑飞。
4.我自己改过(其实是华为demo改的)的库函数就不会出现程序跑飞的问题, 他的USART_ClearITPendingBit()函数如下:
void USART_ClearITPendingBit(USART_TypeDef* USARTx, USART_IT_TypeDef USART_IT)
{
assert_param(IS_USART_CLEAR_IT(USART_IT));
/*< Clear RXNE or TC pending bit */
USARTx->SR &= (uint8_t)(~USART_SR_TC);
}
5.别以为这样就OK了,这样仅仅是stm8在线单步debug没有问题了,但是使用华为修改的串口清除函数会引入另外一个问题,串口通讯不稳定,概率性死机,定在串口发送函数时,具体函数如下:
void WT_Usart_Send_Data(unsigned char *Dbuf,unsigned int len)
{
int i;
static char val=RESET;
//USART1->CR2 |= (uint8_t)USART_CR2_TEN;
for(i = 0;i < len;i++) {
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData8(USART1,Dbuf[i]);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == val);//华为库概率性卡在这里。。。。。。
}
//USART1->CR2 &= (uint8_t)~USART_CR2_TEN;
}
6.最后的解决办法,单步调试时使用华为库函数,发版本时使用stm8原生库函数。
7.最后最后的解决办法,使用我自己修改的库,不过暂时还没有测试完整,等我测完了再发布出来吧
解决方法2:上面的解决办法不是完全正确,后面使用stlink给单片机供电,撤掉usb接口的供电,完全可以单步调试,一点问题没有了,不管使用的是哪个串口中断处理函数,而且可以全速后在单步都没问题。
1.我开始怀疑是硬件问题了,因为stlink的供电是3.3V,但是我使用usb供电后都转换成1.8V。这样导致的电平不匹配有很大的疑点,于是我淘宝了一块电平转换小板,打算在stlink和板子之间做3.3V到1.8V之间的电平转换。
2.后面我发现在合并工程A工程到C工程的过度阶段,单步debug是可以的,但是不能全速后单步,否则会宕掉。一点点定位到是一个GPIO控制了整个系统的电源。这就奇怪了,到底啥问题呢!!!