在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上输出的波形不正确,接收端接受的数据也是错误的。
目前搞不清是什么原因导致的。 |