实验板Nano130
我用PWM0的0通道模拟时钟脉冲给外部存储设备,然后用2通道捕获0通道的上升沿功能触发PDMA采集端口GPIOA的数据,
PDMA中断发生时状态字是PDMA_ISR_TABORT(PDMA Read/Write Target Abort Interrupt Status Flag),采集失败,不知道为什么?
但采集PWM捕获的数据时是正常的。PDMA不能使用这种方式采集端口的数据吗?使用PDMA怎样才能采集端口的输入数据。
代码如下:
// PWM数据
void PWMn_Init(void)
{
S_DRVPWM_TIME_DATA_T sPt;
STR_PDMA_T sPDMA;
const uint8_t u8Timer = 0;
const uint8_t nCapTimer = 2;
//static uint32_t mm = 5;
PWM_Init(0); // 使用通道0,输出波形
PWM_Init(2); // 使用通道2,捕获
GCR->PA_H_MFP = (GCR->PA_H_MFP & ~(PA12_MFP_MASK | PA14_MFP_MASK)) | PA12_MFP_PWM0_CH0 | PA14_MFP_PWM0_CH2;
// clock = 12MHz, 50% duty ratio, Freq 3MHz
// CN = clock / freq - 1 PWM 频率 = PWMxy_CLK/(prescale+1)*(clock divider)/(CN+1);
sPt.u8Mode = PWM_CTL_CHMOD_AUTO_RELOAD;
sPt.u8PreScale = 1; // actually 1 + 1
sPt.u8Div = PWM_CLKSEL_CLKSEL_DIV1;
sPt.u32Cn = 3; // 3MHz
sPt.u16Cm = 1; // 50% duty ratio
sPt.u8Inv = 0; // Disable inverter
PWM_SetClk(u8Timer, &sPt);
PWM_ConfigOutput(u8Timer, 1); // Enable ch 0 output
//PWM_Enable(u8Timer); // Enable PWM ch 0
//PWM_EnableInt(u8Timer);
// Configure capture channel
// PDMA Init
PDMA_Init(); // Use PDMA ch1 here.
PDMA_DISABLE_CH1();
PDMA_EnableChannelClock(PDMAGCR_CSR_CLK1);
PDMA_PWM0_CH2_TO_CH1();
sPDMA.SrcAddr = (uint32_t)(&GPIOA->PIN);//(uint32_t)&(PWM0->CH2PDMA);//(uint32_t)(&GPIOA->PIN);
sPDMA.DestAddr = (uint32_t)DestArray;
sPDMA.TransWidth = PDMA_CSR_APB_TWS_8BIT; // Change to 32 bit if cascade mode is enabled
sPDMA.Mode = PDMA_CSR_IP2MEM;
sPDMA.SrcCtrl = PDMA_CSR_SAD_FIX;
sPDMA.DestCtrl = PDMA_CSR_DAD_INC;
sPDMA.ByteCnt = PDMA_BUF_LENGTH;
sPDMA.IsTimeOutEnable = 0;
PDMA_Open(PDMA1, &sPDMA);
PDMA_EnableInt(PDMA1, PDMA_IER_TD); // 开启中断
//PDMA_CHEnableTransfer(PDMA1);
// PWM timer property for capture channel
sPt.u8Mode = PWM_CTL_CHMOD_AUTO_RELOAD;
sPt.u8PreScale = 1; // actually 1 + 1
sPt.u8Div = PWM_CLKSEL_CLKSEL_DIV1;
sPt.u32Cn = 0xFFFF; // Max CN in non-cascade mode
sPt.u16Cm = 0; // don't care in capture function
sPt.u8Inv = 0; // don't care in capture function
PWM_SetClk(nCapTimer, &sPt);
PWM_SetCaptureAttribute(nCapTimer, 0, 0, PWM_CAPCTL_CAPRELOADREN);// 上升沿 // PWM_CAPCTL_CAPRELOADFEN
PWM_ConfigCaptureIntput(nCapTimer, 1); // Enable PWM ch 2 input function
PWM_EnablePdma(nCapTimer, PWM_CAPCTL_CHRFORDER_R, PWM_CAPCTL_PDMACAPMOD_CRL); // Configure PDMA function
//PWM_CaptureEnable(nCapTimer); // Enable PWM ch 2
//while(pdma_done == 0); // Wait for PDMA capture complete
// STOP
//PWM_SetCounter(u8Timer, 0, 0);
//PWM_Disable(u8Timer);
//PWM_SetCounter(nCapTimer, 0, 0);
//PWM_CaptureDisable(nCapTimer);
//PDMA_DeInit();
}
void PWMn_Disable(void)
{
PWM_Disable(0);
PWM_CaptureDisable(2);
}
// DMA开始传输
void PWMn_Enable(void)
{
PDMA_CHEnableTransfer(PDMA1);
PWM_CaptureEnable(2); // Enable PWM ch 2
PWM_Enable(0); // Enable PWM ch 0
}
void PDMA_IRQHandler(void)
{
uint32_t u32ISR;
u32ISR = PDMA1->ISR;
if(u32ISR & 0x01) /* Check Target Abort INT and clear */
{
PDMA1->ISR = 0x01;
//printf("\tTransfer Target Abort !\r\n");
}
else if(u32ISR & PDMA_ISR_TD)
{ /* Transfer Done INT and clear */
PDMA1->ISR = PDMA1->ISR;
//UART_DisablePDMA(UART1);
//printf("\tTransfer Done!\r\n");
//IsTestOver = TRUE;
}
else if(u32ISR & 0x04)
{ /* Wrap around Transfer complete and clear */
PDMA1->ISR = 0x04;
//printf("\tWrap around Transfer complete!\r\n");
}
else if(u32ISR & 0x10)
{ /* Wrap around Transfer Half and clear */
PDMA1->ISR = 0x10;
//printf("\tWrap around Transfer Half!\r\n");
}
else if(u32ISR & 0x40)
{ /* Transfer Timeout INT and clear */
PDMA1->ISR = 0x40;
//printf("\tTransfer Timeout!\r\n");
}
PWMn_Disable();
}
|