搜索
bottom↓
回复: 9

CDBUS调试过程总结

[复制链接]

出50入135汤圆

发表于 2023-12-19 15:13:55 | 显示全部楼层 |阅读模式
第一使用CDBUS,感谢版主dukelec热心指导,调试完成,分享调试过程中遇到的问题。
1:使用STM32cubemX生成SPI初始化代码,读寄存器成功,写寄存器不成功,在版主dukelec的指导下发现写寄存器的时候没有加0x80,加上0x80后写寄存器正常;
2:在使用HAL库HAL_SPI_TransmitReceive函数时,无接收数据时把接收缓存区指针设置为空,导致没有发送数据,修改为HAL_SPI_Transmit和HAL_SPI_Receive后能通道;
3:测试发现,上电后第一次收到数据不对,经版主dukelec指点发现是由于初始化的时候读了一遍所有寄存器(调试1问题的时候把所以寄存器读出来),导致RX指针不对,删除读所以寄存器代码后,上电后第一次数据接收正常;
4:1,2,3是使用10M波特率,将波特率调整到20M后偶尔能收到数据,经版主dukelec检测发现是由于bridge的波特率设置为20M时偏差教大,bridge与我的板子调整到25M后,通信正常;
5:查看HAL SPI发送与接收相关函数,发现很复杂,使用寄存器方式重写读写函数,测试发现只写不接收时也须要读DR寄存器(__HAL_SPI_CLEAR_OVRFLAG(hspi));
6:使用串口助手连续发数据,发现有时会收不到数据,经主dukelec指点后,改成在主循环读中段引脚电平,为低表示须要处理数据(版言主解析为数据太快时,中段中还没有读完数据又收到下一帧数据,导致STM32无法过中断,STM32只能边沿触发中断).
以下为寄存器操作SPI代码:
void SPI_ReadWriteByte(SPI_TypeDef *spi,unsigned char *pTxData, uint8_t txlen,unsigned char  *pRxData, uint8_t rxlength)//寄存器版本
{        
        //volatile unsigned char tmpreg;
        unsigned short TxXferCount,RxXferCount;
        unsigned char *pRxBuffPtr  = pRxData;
        unsigned char *pTxBuffPtr  = pTxData;
        unsigned char txallowed = 1U;
        __IO unsigned int tmpreg_ovr = 0x00U;
       
        if(txlen>0)
                TxXferCount=txlen;
        else
                TxXferCount=rxlength;
       
        RxXferCount=rxlength;

        //如果 FIFO 占用水平大于或等于 1/4(8 位),将生成 RXNE 事件
        SET_BIT(spi->CR1, SPI_CR1_SPE);
        SET_BIT(spi->CR2, SPI_RXFIFO_THRESHOLD);

        while((TxXferCount > 0) || (RxXferCount > 0))
        {
            if(txallowed && ((spi->SR & SPI_FLAG_TXE) == SPI_FLAG_TXE) && (TxXferCount > 0))
            {
                 if(txlen>0)
                {
                        *((__IO unsigned char *)(&spi->DR)) = (*pTxBuffPtr++);
                 }
                 else
                {
                        *((__IO unsigned char *)(&spi->DR))=0x00;
                 }
                                 
                txallowed = 0U;
            }
           if((spi->SR & SPI_FLAG_RXNE) == SPI_FLAG_RXNE)
           {
                 TxXferCount--;
                 txallowed = 1U;
                if(RxXferCount > 0)
                {
                        RxXferCount--;
                        (*pRxBuffPtr++) =  *(__IO unsigned char *)&spi->DR;
               }
              else
              {
                        tmpreg_ovr=*(__IO unsigned char *)&spi->DR;
                        tmpreg_ovr=*(__IO unsigned char *)&spi->SR;
                        UNUSED(tmpreg_ovr);   
                }
           }
     }        
}

以下为CDBUS初始化代码,12M晶振,低速波特率1M,高速波特率25M
void CdBusInit(void)
{
        uint8_t version=CdBusReadReg(VERSION);
       
        CdBusWriteReg(CLK_CTRL, 0x80);    // Soft reset
        CdBusWriteReg(PLL_ML,0x30);     //取默认值      
  //CdBusWriteReg(PLL_OD_MH,0x00);  //取默认值      
  CdBusWriteReg(PLL_N,0x02);     //取默认值
        CdBusWriteReg(PLL_CTRL, 0x10);    //启用PLL
        HAL_Delay(10);
        CdBusWriteReg(CLK_CTRL, 0x01);    //时钟选择 PLL 12M晶振  sysclk=60Mhz
       
        CdBusWriteReg(PIN_RE_CTRL, 0x10); // Set RE_N pin to low
        CdBusWriteReg(SETTING, 0x11);     // Enable push-pull output
        CdBusWriteReg(FILTER, 0x0c);      // Set FILTER
        // Set baudrates
        CdBusWriteReg(DIV_LS_L, 74);      // 1 Mbps @75MHz sysclk
        CdBusWriteReg(DIV_LS_H, 0);
       
        CdBusWriteReg(DIV_HS_L, 2);       // 25 Mbps @75MHz sysclk  75/(2+1)=75/3=25MHz
        CdBusWriteReg(DIV_HS_H, 0);
       
        CdBusWriteReg(RX_CTRL, 0x11);     // Reset RX buffers and flags (optional)
        //Enable interrupts (optional)
        CdBusWriteReg(INT_MASK, BIT_FLAG_TX_ERROR | BIT_FLAG_RX_ERROR | BIT_FLAG_RX_LOST | BIT_FLAG_RX_PENDING);
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

有一句段子是这样说的,身家过亿的只关心自己的身体,身家千万的,在担心传承,勉强糊口度日才天天看国际新闻,关心国家大事。

出50入135汤圆

 楼主| 发表于 2023-12-19 15:15:18 | 显示全部楼层
发送数据函数:
uint8_t CdBusSendData(uint8_t src_addr,uint8_t des_addr,uint8_t *buf,uint8_t length)
{
        CD_BUS_CS_L;
       
        uint8_t txbuf[4]={0};
        txbuf[0]=TX+0x80;
        txbuf[1]=src_addr;
        txbuf[2]=des_addr;
        txbuf[3]=length;
        SPI_ReadWriteByte(SPI3,txbuf,4,NULL,0);
        SPI_ReadWriteByte(SPI3,buf,length,NULL,0);
        CD_BUS_CS_H;
       
        while(!(CdBusReadReg(INT_FLAG) & 0x20)); // Make sure we can successfully switch to the next page
        CdBusWriteReg(TX_CTRL, 0x03); // Trigger send by switching TX page
       
        return 0;
}

出50入135汤圆

 楼主| 发表于 2023-12-19 15:15:37 | 显示全部楼层
接收数据函数:
void CdBusReadChunk(uint8_t *buf,uint8_t length)
{
        uint8_t txbuf[4]={0};
        txbuf[0]=RX;
       
        CD_BUS_CS_L;
        SPI_ReadWriteByte(SPI3,txbuf,1,NULL,0);
        SPI_ReadWriteByte(SPI3,NULL,0,buf,length);
        CD_BUS_CS_H;
}

void CdBusRecvData()
{
        if(CdBusReadReg(INT_FLAG) & BIT_FLAG_RX_PENDING)
        {
                memset(rxbuf,0,256);
                CdBusReadChunk(rxbuf,3);
                CdBusReadChunk(rxbuf+3,rxbuf[2]);
                CdBusWriteReg(RX_CTRL, 0x03);
                bRecvData=1;
                DataProcess();
                //printinfo("recv data");
                CdBusSendData(0x0c,0x00,&rxbuf[3],rxbuf[2]);
        }
}

出0入147汤圆

发表于 2023-12-19 15:46:33 | 显示全部楼层
如果不使用类似版主的CDCTL01A这种软件的实现,有没有可能通过搭电路来检测485芯片前后的电平是否对应,来实现相同的功能呢?

出50入135汤圆

 楼主| 发表于 2023-12-19 15:54:10 | 显示全部楼层
芯片很便宜,

出715入1076汤圆

发表于 2023-12-19 16:06:53 | 显示全部楼层
其实可以考虑移植我现有的代码:

hal 查询版本:
https://github.com/dukelec/cdnet/blob/master/dev/cdctl.c

hal dma 版本:
https://github.com/dukelec/cdnet/blob/master/dev/cdctl_it.c

寄存器 + dma 版本的:
https://github.com/dukelec/cdbus ... ge/usr/cdctl_fast.c

出50入135汤圆

 楼主| 发表于 2023-12-19 16:10:58 | 显示全部楼层
多谢版主的汤圆。

出100入143汤圆

发表于 2023-12-19 16:12:22 | 显示全部楼层
谢谢分享!很快我也要试试这个芯片

出50入135汤圆

 楼主| 发表于 2023-12-19 16:12:38 | 显示全部楼层
下午用电脑通过bridge以25M的速度每隔1MS发10字节数据给我的板子,板子收到后回传收的数据,测试500W+数据没有丢失.

出50入135汤圆

 楼主| 发表于 2023-12-19 16:14:57 | 显示全部楼层
zzh90513 发表于 2023-12-19 16:12
谢谢分享!很快我也要试试这个芯片
(引用自8楼)

SPI熟悉的话,就很快,我都是卡在HAL的SPI里面。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-12-11 23:30

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表