CDBUS调试过程总结
第一使用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 sysclk75/(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);
}
发送数据函数:
uint8_t CdBusSendData(uint8_t src_addr,uint8_t des_addr,uint8_t *buf,uint8_t length)
{
CD_BUS_CS_L;
uint8_t txbuf={0};
txbuf=TX+0x80;
txbuf=src_addr;
txbuf=des_addr;
txbuf=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;
} 接收数据函数:
void CdBusReadChunk(uint8_t *buf,uint8_t length)
{
uint8_t txbuf={0};
txbuf=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);
CdBusWriteReg(RX_CTRL, 0x03);
bRecvData=1;
DataProcess();
//printinfo("recv data");
CdBusSendData(0x0c,0x00,&rxbuf,rxbuf);
}
} 如果不使用类似版主的CDCTL01A这种软件的实现,有没有可能通过搭电路来检测485芯片前后的电平是否对应,来实现相同的功能呢? 芯片很便宜,{:lol:} 其实可以考虑移植我现有的代码:
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_bridge/blob/master/fw_bridge/usr/cdctl_fast.c 多谢版主的汤圆。 谢谢分享!很快我也要试试这个芯片 下午用电脑通过bridge以25M的速度每隔1MS发10字节数据给我的板子,板子收到后回传收的数据,测试500W+数据没有丢失. zzh90513 发表于 2023-12-19 16:12
谢谢分享!很快我也要试试这个芯片
(引用自8楼)
SPI熟悉的话,就很快,我都是卡在HAL的SPI里面。
页:
[1]