打印
[产品应用]

CW32F030 芯片 SPI DMA BULK发送问题

[复制链接]
637|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yuanruizhang|  楼主 | 2025-3-5 17:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在CW32F030芯片上用SPI DMA发送,Block模式没有问题,可以调试出来,但是因为每个字节最后一位会插入一个大约60ns的时间,这个时间会导致数据出错。看到规格书有说BULK模式,但是我将代码设置成BULK模式之后,数据传输不成功,有时能传两个字节,有时一个字节也传不了。
SPI和DMA的初始化代码如下:
void SPI_Configuration(void)
{
    SPI_InitTypeDef SPI_InitStructure;
    SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_TxOnly;         // 单工发送
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                         // 主机模式
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                     // 帧数据长度为8bit
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                            // 时钟空闲电平为低
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                          // 第一个边沿采样
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                             // 片选信号由SSI寄存器控制
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;    // 波特率为PCLK的8分频        // 64 / 4 = 8Mhz
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                    // 最高有效位 MSB 收发在前
    SPI_InitStructure.SPI_Speed = SPI_Speed_High;                         // 高速SPI
    SPI_Init(CW_SPI1, &SPI_InitStructure);
    SPI_DMACmd(CW_SPI1, SPI_DMAReq_Tx, ENABLE);
    SPI_Cmd(CW_SPI1, ENABLE);
    // SPI_NSSInternalSoftwareConfig(CW_SPI1, SPI_NSSInternalSoft_Reset);
}

DMA_InitTypeDef DMA_InitStructure;
void DMA_Configuration(void)
{
    // 初始化SPI DMA TX
    DMA_InitStructure.DMA_Mode = DMA_MODE_BULK/* DMA_MODE_BLOCK */;
    DMA_InitStructure.DMA_TransferWidth = DMA_TRANSFER_WIDTH_8BIT;
    DMA_InitStructure.DMA_SrcInc = DMA_SrcAddress_Increase;
    DMA_InitStructure.DMA_DstInc = DMA_DstAddress_Fix;
    DMA_InitStructure.TrigMode = DMA_HardTrig/* DMA_SWTrig */;
    DMA_InitStructure.HardTrigSource = DMA_HardTrig_SPI1_TXBufferE/* DMA_HardTrig_GTIM1_OVERINT */;
    DMA_InitStructure.DMA_TransferCnt = SPI_TX_SIZE;
    DMA_InitStructure.DMA_SrcAddress = (uint32_t)TxBuffer1;
    DMA_InitStructure.DMA_DstAddress = (uint32_t)&CW_SPI1->DR;
    DMA_Init(CW_DMACHANNEL2, &DMA_InitStructure);
    DMA_ClearITPendingBit(DMA_IT_ALL);
    DMA_ITConfig(CW_DMACHANNEL2, DMA_IT_TC | DMA_IT_TE, ENABLE);            // 使能DMA_CHANNEL1中断
    DMA_Cmd(CW_DMACHANNEL2, ENABLE);
}
发送过程是一个外部中断触发,定时器,在定时器中断中使能发送的:
void GTIM1_IRQHandlerCallBack(void)
{
    if (GTIM_GetITStatus(CW_GTIM1, GTIM_IT_OV)) {
        GTIM_ClearITPendingBit(CW_GTIM1, GTIM_IT_OV);
        if (HSync > SCAN_UP_POS_START && HSync < SCAN_UP_POS_END) {
            CW_DMACHANNEL2->CSR |= DMA_CHANNEL_EN;
            // CW_DMACHANNEL2->TRIG |= DMA_SOFTTRIG_EN;
        }
    }
}

void GPIOA_IRQHandlerCallback(void)
{
    if (CW_GPIOA->ISR_f.PIN0) {     // 行同步
        GPIOA_INTFLAG_CLR(bv0);

            CW_GTIM1->CR0_f.EN  = ENABLE;
            CW_GPIOA->BRR |= GPIO_PIN_7;
  
                CW_DMACHANNEL2->SRCADDR = (uint32_t)(TxBuffer1);         // 重置目的地址
                CW_DMACHANNEL2->CNT = bv16 | SPI_TX_SIZE;                // 重置CNT计数
            // CW_DMACHANNEL2->CSR |= DMA_CHANNEL_EN;

    }
}
DMA打开发送完成中断和错误中断,能看到DMA发送完成了,但是SPI的MOSI上输出的波形不正确,接收端接受的数据也是错误的。
目前搞不清是什么原因导致的。

使用特权

评论回复
沙发
小小蚂蚁举千斤| | 2025-3-13 22:20 | 只看该作者
BULK模式???

使用特权

评论回复
板凳
中国龙芯CDX| | 2025-3-19 21:20 | 只看该作者
DMA打开应该有监视模式可以确认一下

使用特权

评论回复
地板
yuanruizhang|  楼主 | 2025-3-24 15:57 | 只看该作者

是的,因为block模式会在发送一个字节之后插入一个间隙,会导致一些问题,所以想用BULK模式发送,但是BULK好像发送不了多个字节

使用特权

评论回复
5
yuanruizhang|  楼主 | 2025-3-24 15:57 | 只看该作者
中国龙芯CDX 发表于 2025-3-19 21:20
DMA打开应该有监视模式可以确认一下

怎么打开监视模式,我在手册中没有找到说明呢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

3

帖子

0

粉丝