[国产单片机] 使用MM32F0144的一个奇怪的bug,一段代码影响串口接收中断

[复制链接]
2207|9
ljxh401 发表于 2025-9-16 11:43 | 显示全部楼层 |阅读模式
本帖最后由 ljxh401 于 2025-9-16 11:51 编辑

我使用mm32的串口2做485,9位通信,

然后又使用 spi2+dma 进行控制ws2812的灯带,给灯带填充数据的代码会影响485的接收中断,
我只要将#if 1 里面的代码 禁止运行 改为 #if 0
我的485通信就很OK,允许运行 485 就经常错误,
我将这个任务的优先级提高或者降低都是这样,
我感觉跟这段代码里面的多个跳转if判断有关,

void ColorDataSend(INT32U *pdata,INT8U len)
{
#if 1
        INT8U i,bitcnt,*pDst;
        INT32U d;
        INT16U bitaddr=1;
        for(i=0;i<len;i++)
        {
                d=*pdata++;
                for(bitcnt=0;bitcnt<24;bitcnt++)
                {
                        if(d&0x800000)
                                spiData[bitaddr/8]=BitTab[bitaddr&7];
                        else
                                spiData[bitaddr/8]&=~BitTab[bitaddr&7];
                        bitaddr+=3;
                        d<<=1;
                }
                if(i&1)        OSTimeDly(1);
        }
#endif
        SPI2DmaSend(spiData,sizeof(spiData)-1);
}


最后我将代码 改为 用查表法,用空间换时间,减少if的跳转,485的通信就OK了


void ColorDataSend(INT32U *pdata,INT8U len)
{
        INT8U  pos,*pdst=spiData;
        INT16U i;
        INT32U d;
        for(i=0;i<len;i++)
        {
                d=*pdata++;

                pos=(d&0xFF)*3;d>>=8;
                *pdst++=Color2DataTab[pos];
                *pdst++=Color2DataTab[pos+1];
                *pdst++=Color2DataTab[pos+2];

                pos=(d&0xFF)*3;d>>=8;
                *pdst++=Color2DataTab[pos];
                *pdst++=Color2DataTab[pos+1];
                *pdst++=Color2DataTab[pos+2];

                pos=(d&0xFF)*3;                //d>>=8;
                *pdst++=Color2DataTab[pos];
                *pdst++=Color2DataTab[pos+1];
                *pdst++=Color2DataTab[pos+2];
        }
        SPI2DmaSend(spiData,sizeof(spiData)-1);
}

 楼主| ljxh401 发表于 2025-9-18 11:50 | 显示全部楼层
总感觉这个像是CPU的bug,在命令流水线上密集的跳转
xch 发表于 2025-9-18 17:44 | 显示全部楼层
if(i&1)        OSTimeDly(1); //后面代码这句被删了。
xch 发表于 2025-9-18 18:09 | 显示全部楼层
本帖最后由 xch 于 2025-9-18 18:33 编辑
  1. <div class="blockcode"><blockquote>
  2. void ColorDataSend(uint32_t *pdata,uint8_t len)
  3. {
  4.         uint8_t  *pdst = spiData, *psrc = (uint8_t *) pdata;
  5.         
  6.         while(len--)
  7.         {
  8.                 *pdst++ = Color2DataTab[(*psrc++)+0];
  9.                  *pdst++ = Color2DataTab[(*psrc++)+1];
  10.                   *pdst++ = Color2DataTab[(*psrc++)+2];
  11.                 psrc++
  12.         }
  13.         SPI2DmaSend(spiData,sizeof(spiData)-1); //好奇怪的 长度 -1
  14. }

xch 发表于 2025-9-18 18:18 | 显示全部楼层
SPI2DmaSend(spiData,3*(uint16_t) len); ?
 楼主| ljxh401 发表于 2025-9-26 11:42 | 显示全部楼层
xch 发表于 2025-9-18 17:44
if(i&1)        OSTimeDly(1); //后面代码这句被删了。

加入这句,接收的成功率反而好一点,去掉 丢包率更高

评论

xch
SPI2DmaSend 把它屏蔽了是不是就不丢包  发表于 2025-9-26 15:21
 楼主| ljxh401 发表于 2025-9-26 11:47 | 显示全部楼层

我也忘了长度-1 是为什么了,不过我的 spiData 的长度是超过 色彩部分的  后面都是 00
这个也不是影响485接收的关键点
xch 发表于 2025-9-26 15:14 | 显示全部楼层
ljxh401 发表于 2025-9-26 11:47
我也忘了长度-1 是为什么了,不过我的 spiData 的长度是超过 色彩部分的  后面都是 00
这个也不是影响485 ...

试试我写的,补上一个 ;号
xch 发表于 2025-9-26 15:17 | 显示全部楼层
ljxh401 发表于 2025-9-26 11:42
加入这句,接收的成功率反而好一点,去掉 丢包率更高

SPI2DmaSend 这个函数也许有问题。看不见它怎么写的。是不是在里面死等传输结束了?使得 DMA 没有发挥腾出MCU的作用。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

53

主题

235

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部