您好!
我尝试使用 SPI 将数据从外部 ADC 传输到 TM4C。 ADC 是从器件、每次转换后发送 24个字节。 我已经配置了 SSI0 DMA TX 和 RX。 我发送一组24个虚拟字节来从 ADC 接收实际样本。 但是、出于某种原因、连续调用 RX DMA 末尾的中断函数。 此外、我会得到大量 FIFO 溢出错误和 Rx 超时错误。 无论如何、看起来 DMA 传输的运行方式非常不正常。 因此、为了找出问题、我简化了代码。 我启用了回送模式、只发送一组24个虚拟字节。 在主函数中、我只调用
ssi0_Init();
ssi0_DmaTransferSetup();
ssi0_DmaTransferStart();
但是、我观察到相同的行为、并且接收缓冲区中没有数据被写入。 到目前为止、我还没有找到代码有什么问题。 感谢您的帮助(复制如下)。
谢谢、
SINA
extern uint32_t g_systemClockFrequency;//120MHz #define SAMPLE_buffer_size 24 uint8_t g_dummyByte = 8; uint8_t g_rxSampleBuffer[SAMPLE_Buffer_SIZE]; uint32_t g_Overlation nbBufCount = 0; uint32_t g_t g_rxSampleBuffer = 0;uint_h = 0 ;uinteg_void = 0;uintse_sum_0 (void = 0) void 设置= 0;uintsum_sample (void = 0) G_rxBufCount = 0; g_nbOverflag = 0; g_nbTimeout = 0; ssi0_HwSetup(); GPIOPinWrite (GPIO_PORTN_BASE、 GPIO_PIN_4、0); GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_5、0); } void ssi0_HwSetup (void) { SysCtlPeripheralEnable (sysctl_Periph_GPIOA); GPIOPinTypeSSI (GPIO_PORta_base、GPIO_PIN_2 | GPIO_PIN_5 );配置 GPIO0PIN_GPIO5 (GPIO_PIN_GPIO5);配置 GPIO0_GPIO5 (GPIO5) SysCtlPeripheralEnable (SYSCTL_Periph_SSI0); //等待外设就绪 (!SysCtlPeripheralReady (SYSCTL_Periph_SSI0)){} SSIClockSourceSet (SSI0_BASE、SSI_CLOCK 系统); // ADC_SPI_CLOCK = 4MClock_MASTER 、SSI0_SCON_CLUS_CLUS_CLUS_CLUS_CLUST_SSI0、SSIP_CLUST_SSIRFF (SSI0) adc_data_format_bits); SSIEnable (SSI0_BASE); g_dummyByte = 0; uint32_t dummy = 0; while (SSIDataGetNonBlocking (SSI0_BASE、&dummy))} }void ssi0_DmaTransferSetup (void) { //为 TX 和 RX 通道启用 uDMA 接口。 SSIDMAEnable (SSI0_BASE、SSI_DMA_TX|SSI_DMA_RX); //DMA TX 设置 //将 UDMA SSI0TX 通道的属性置于已知状态。 uDMAChannelAttributeDisable (UDMA_CHANGE_SSI0TX、 UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIOR| UDMA_ATTR_REQMASK); //源上没有递增,因为我们正在发送相同的虚拟字节 //由于我们要复制到同一寄存器位置,所以目的不增加 uDMAChannelControlSet (UDMA_CHANGE_SSI0TX | UDMA_PRI_SELECT、 UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_8); //DMA RX 设置 //将 UDMA SSI0RX 通道的属性置于已知状态。 这些 默认情况下、//应已禁用。 uDMAChannelAttributeDisable (UDMA_CHANGE_SSI0RX、 UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIOR| UDMA_ATTR_REQMASK); //源不递增,因为我们正在读取同一个寄存器 //在每个 DMA 传输中将目标地址增加一个字节,因为我们正在写入接收缓冲区 uDMAChannelControlSet (UDMA_CHANGE_SSI0RX | UDMA_PRI_SELECT、 UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_8); //启用用于调试的环回 HWREG (SSI0_BASE + SSI_O_CR1)|= SSI_CR1_LBM; //清除任何挂起的中断 SSIIntClear (SSI0_BASE、0xFF); SSIIntEnable (SSI0_BASE、SSI_DMARX|SSI_RXOR|SSI_RXTO); //在 NVIC 中启用中断 IntEnable (INT_SSI0); } void ssi0_DmaTransferStart (void) { uDMAChannelTransferSet (UDMA_CHANGE_SSI0TX | UDMA_PRI_SELECT、 UDMA_MODE_BASIC、 &g_dummyByte、 (void *)(SSI0_BASE + SSI_O_DR)、 sample_buffer_size); //最终代码:在此处获取新的缓冲区 uDMAChannelTransferSet (UDMA_CHANGE_SSI0RX | UDMA_PRI_SELECT、 UDMA_MODE_BASIC、 (void *)(SSI0_BASE + SSI_O_DR)、 G_rxSampleBuffer、sample_buffer_size); uDMAChannelEnable (UDMA_CHANGE_SSI0TX|UDMA_CHANGE_SSI0RX); } void ssi0_IntHandler (void) { uint32_t ui32Status; //读取中断状态 ui32Status = SSIIntStatus (SSI0_BASE、1); IF (ui32Status & SSI_RXOR) { ++g_nbOverf溢; } IF (ui32Status 和 SSI_RXTO) { ++g_nbTimeout; } //清除任何挂起状态,即使由于没有 SSI 而应该没有等待状态 //中断已启用。 SSIIntClear (SSI0_BASE、ui32Status); //如果 DMA 通道被禁用,则表示传输已完成 if (!uDMAChannelIsEnabled (UDMA_CHANGE_SSI0RX)) { G_rxBufCount++; } }