在线时间13 小时
UID3850783
注册时间2024-9-20
NXP金币62
该用户从未签到
注册会员

- 积分
- 177
- 最后登录
- 2024-11-13
|
大佬们麻烦帮忙看一下,卡了好几天了,用的MKV30F128VFM,我对编码器的A,B相进行了16位adc采集,用dma通道0和通道1将A,B相adc采集结果传输到了内存后再从串口发出,但从上位机上观察到的图像只有一路adc的采集图像是完好的正弦波,另一个图像出现周期性缺失
int main(void)
{
uart_transfer_t xfer;
uart_transfer_t sendXfer;
uart_transfer_t receiveXfer;
uint8_t ch;
edma_config_t config;
float32_t atanPos = 0;
float32_t atanPosL = 0;
BOARD_InitBootPins();
BOARD_InitBootClocks();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
/* Init FSL debug console. */
BOARD_InitDebugConsole();
#endif
// BOARD_InitBootPeripherals();
UART_SetBaudRate(UART0, 2500000UL, UART0_CLOCK_SOURCE);
UART_Init(UART0_PERIPHERAL, &UART0_config, UART0_CLOCK_SOURCE);
DMAMUX_Init(DMA_DMAMUX_BASEADDR);
EDMA_Init(DMA_DMA_BASEADDR, &DMA_config);
DMAMUX_SetSource(DMA_DMAMUX_BASEADDR, DMA_CH0_DMA_CHANNEL, DMA_CH0_DMA_REQUEST);
DMAMUX_SetSource(DMA_DMAMUX_BASEADDR, DMA_CH1_DMA_CHANNEL, DMA_CH1_DMA_REQUEST);
DMAMUX_SetSource(UART0_RX_DMAMUX_BASEADDR, UART0_RX_DMA_CHANNEL, UART0_RX_DMA_REQUEST);
DMAMUX_EnableChannel(DMA_DMAMUX_BASEADDR, DMA_CH1_DMA_CHANNEL);
DMAMUX_EnableChannel(UART0_RX_DMAMUX_BASEADDR, UART0_RX_DMA_CHANNEL);
DMAMUX_EnableChannel(UART0_TX_DMAMUX_BASEADDR, UART0_TX_DMA_CHANNEL);
EDMA_CreateHandle(&DMA_CH0_Handle, DMA_DMA_BASEADDR, DMA_CH0_DMA_CHANNEL);
EDMA_CreateHandle(&DMA_CH1_Handle, DMA_DMA_BASEADDR, DMA_CH1_DMA_CHANNEL);
ADC16_Init(ADC0_PERIPHERAL, &ADC0_config); //adc0初始化
ADC16_EnableHardwareTrigger(ADC0_PERIPHERAL, false);
ADC16_SetChannelMuxMode(ADC0_PERIPHERAL, ADC0_muxMode); /
ADC16_Init(ADC1_PERIPHERAL, &ADC1_config);
ADC16_EnableHardwareTrigger(ADC1_PERIPHERAL, false);
ADC16_SetChannelMuxMode(ADC1_PERIPHERAL, ADC1_muxMode);
ADC16_EnableDMA(ADC0, true);
ADC16_EnableDMA(ADC1, true);
ADC16_SetChannelConfig(ADC0, ADC0_CH0_CONTROL_GROUP, &ADC0_channelsConfig[1]); //设置adc0通道
ADC16_SetChannelConfig(ADC1, ADC1_CH2_CONTROL_GROUP, &ADC1_channelsConfig[0]); //设置adc1通道
EnableIRQ(BOARD_Z_IRQ);
EDMA_SetCallback(&DMA_CH0_Handle, EDMA_Callback_0, NULL);
EDMA_PrepareTransfer(&g_transferConfig0, (uint16_t*) (ADC0->R), sizeof(uint16_t), //传输准备(传输结构,源地址,源地址数值大小
(void *)g_adc16SampleDataArray0, sizeof(uint16_t), sizeof(uint16_t), //目标地址,目标地址大小,传输单位大小
sizeof(g_adc16SampleDataArray0), kEDMA_PeripheralToMemory); //传输总数据大小,输出模式(外设到内存))
EDMA_SubmitTransfer(&DMA_CH0_Handle, &g_transferConfig0); //设置传输
// EDMA_SetChannelLink(DMA0, DMA_CH1_DMA_CHANNEL, kEDMA_MajorLink,DMA_CH0_DMA_CHANNEL); //连接通道
// DMA0->TCD[0].CITER_ELINKYES= sizeof(g_adc16SampleDataArray1) / sizeof(uint16_t);
DMA0->TCD[0].DLAST_SGA = -1 * sizeof(g_adc16SampleDataArray0); //tcd[0],dma通道0,目标地址偏移
DMA0->TCD[0].ATTR |= DMA_ATTR_SMOD_MASK;
/* 发送结束中断触发. */
EDMA_EnableChannelInterrupts(DMA_DMA_BASEADDR, DEMO_DMA_CHANNEL, kEDMA_MajorInterruptEnable);
#if defined(FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT) && FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT
/* Enable async DMA request. */
EDMA_EnableAsyncRequest(DMA_DMA_BASEADDR, DEMO_DMA_CHANNEL, true); //启用dma异步传输
#endif /* FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT */
EDMA_SetCallback(&DMA_CH1_Handle,EDMA_Callback_1, NULL);
EDMA_PrepareTransfer(&g_transferConfig1, (uint16_t*) (ADC1->R), sizeof(uint16_t),
(void *)g_adc16SampleDataArray1, sizeof(uint16_t), sizeof(uint16_t),
sizeof(g_adc16SampleDataArray1), kEDMA_PeripheralToMemory);
EDMA_SubmitTransfer(&DMA_CH1_Handle, &g_transferConfig1);
EDMA_SetChannelLink(DMA0, DMA_CH1_DMA_CHANNEL, kEDMA_MajorLink,DMA_CH0_DMA_CHANNEL);
DMA0->TCD[1].DLAST_SGA = -1 * sizeof(g_adc16SampleDataArray1);
// DMA0->TCD[1].CITER_ELINKYES= sizeof(g_adc16SampleDataArray1) / sizeof(uint16_t);
DMA0->TCD[1].ATTR |= DMA_ATTR_SMOD_MASK;
EDMA_StartTransfer(&DMA_CH1_Handle);
txFAdeal(g_adc16SampleDataArray0[0],g_adc16SampleDataArray1[0],0,0,0);
sendXfer.data = txFAbuff;
sendXfer.dataSize = 10;
receiveXfer.data = g_rxBuffer;
receiveXfer.dataSize = 10;
txOnGoing = true;
GPIO_PinWrite(GPIOD,BOARD_INITPINS_RS485EN_PIN,1);
while (1)
{
// if(g_Transfer_Done_ch0||g_Transfer_Done_ch1)
// {
g_Transfer_Done_ch0 = false;
g_Transfer_Done_ch1 = false;
while(!g_Transfer_Done_ch0&&!g_Transfer_Done_ch1){};
int normalized_value1 = g_adc16SampleDataArray0[0] - sinoffset; //adc值范围归化
int normalized_value2 = g_adc16SampleDataArray1[0] - cosoffset;
atanPos = atan2f(normalized_value2, normalized_value1);
if(atanPos<0) atanPos = 2 * pi + atanPos;
arctan = atanPos * 10000 ;
if(count_0>count_1 )count_Z = count_0 - count_1;
else count_Z = count_1 - count_0;
txFAdeal(g_adc16SampleDataArray0[0],g_adc16SampleDataArray1[0],count_Z,0,arctan);
if(txOnGoing == false)
{
txFAdeal(g_adc16SampleDataArray0[0],g_adc16SampleDataArray1[0],count_Z,0,arctan);
sendXfer.data = txFAbuff;
txOnGoing = true;
}
UART_WriteBlocking(UART0,txFAbuff,sizeof(txFAbuff));
}
}
//CHA adc0 dma回调
static void EDMA_Callback_0(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
{
if (transferDone)
{
g_Transfer_Done_ch0 = true;
// EDMA_StartTransfer(&DMA_CH0_Handle);
}
}
//CHB adc1 dma回调
static void EDMA_Callback_1(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
{
//EDMA_StartTransfer(&DMA_CH1_Handle);
handle->base->SERQ = DMA_SERQ_SERQ(handle->channel);
if (transferDone)
{
g_Transfer_Done_ch1 = true;
}
}
红色的正弦波图线是采集到的A路信号,蓝色正弦波图线是采集到的B路信号,两个图像相差四分之个周期的相位,黑色图像是A路和B路的反正切数值,紫色那条有尖峰的图线是编码器单位时间内的位移量是根据两次反正切的差值求的,且我将edma重启的代码更换到dma0的回调函数中并改SetChannelLink为dma通道0链接通道1后这个缺失的现象从A路信号图线转移到了B路信号图线,而A路信号又变得玩好了,这是什么原因?
|
|