上回我们说到了MG32F02A的PWM互补输出 带死区的使用。
这次,我们讲一下输入捕获带DMA的做法。
首先,根据User Guide得知,MG32F02A只有TM36的IC3支持DMA功能,因此我们只能用TM36
代码附上:
- #include "MG32x02z_DRV.H"
- #include
- typedef uint8_t u8;
- typedef uint16_t u16;
- typedef uint32_t u32;
- typedef uint64_t u64;
- #define TM36_IC3_TriggerSrc 1
- #define URTX URT0
- uint16_t RcvBuf[10]={0};
- void Sample_URT0_Init(void)
- {
- URT_BRG_TypeDef URT_BRG;
- URT_Data_TypeDef DataDef;
- PIN_InitTypeDef PINX_InitStruct;
- //==Set CSC init
- //MG32x02z_CSC_Init.h(Configuration Wizard)
- //Select CK_HS source = CK_IHRCO
- //Select IHRCO = 11.0592M
- //Select CK_MAIN Source = CK_HS
- //Configure PLL->Select APB Prescaler = CK_MAIN/1
- //Configure Peripheral On Mode Clock->Port B/URT0 = Enable
- //Configure Peripheral On Mode Clock->URT0->Select URT0_PR Source = CK_APB(11.0592)
- //==Set GPIO init
- //MG32x02z_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin8/9
- //GPIO port initial is 0xFFFF
- //Pin8 mode is PPO/Pin9 mode is ODO
- //Pin8/9 pull-up resister Enable
- //Pin8/9 function URT0_TX/RX
- PINX_InitStruct.PINX_Mode = PINX_Mode_PushPull_O; // Pin select Push Pull mode
- PINX_InitStruct.PINX_PUResistant = PINX_PUResistant_Enable; // Enable pull up resistor
- PINX_InitStruct.PINX_Speed = PINX_Speed_Low;
- PINX_InitStruct.PINX_OUTDrive = PINX_OUTDrive_Level0; // Pin output driver full strength.
- PINX_InitStruct.PINX_FilterDivider = PINX_FilterDivider_Bypass; // Pin input deglitch filter clock divider bypass
- PINX_InitStruct.PINX_Inverse = PINX_Inverse_Disable; // Pin input data not inverse
- PINX_InitStruct.PINX_Alternate_Function = 3; // Pin AFS = URT0_TX
- GPIO_PinMode_Config(PINB(8),&PINX_InitStruct); // TXD at PB8
- PINX_InitStruct.PINX_Mode = PINX_Mode_OpenDrain_O; // Pin select Open Drain mode
- PINX_InitStruct.PINX_Alternate_Function = 3; // Pin AFS = URT0_RX
- GPIO_PinMode_Config(PINB(9),&PINX_InitStruct); // RXD at PB9
- //=====Set Clock=====//
- //---Set BaudRate---//
- URT_BRG.URT_InteranlClockSource = URT_BDClock_PROC;
- URT_BRG.URT_BaudRateMode = URT_BDMode_Separated;
- URT_BRG.URT_PrescalerCounterReload = 0; //Set PSR
- URT_BRG.URT_BaudRateCounterReload = 3; //Set RLR
- URT_BaudRateGenerator_Config(URTX, &URT_BRG); //BR115200 = f(CK_URTx)/(PSR+1)/(RLR+1)/(OS_NUM+1)
- URT_BaudRateGenerator_Cmd(URTX, ENABLE); //Enable BaudRateGenerator
- //---TX/RX Clock---//
- URT_TXClockSource_Select(URTX, URT_TXClock_Internal); //URT_TX use BaudRateGenerator
- URT_RXClockSource_Select(URTX, URT_RXClock_Internal); //URT_RX use BaudRateGenerator
- URT_TXOverSamplingSampleNumber_Select(URTX, 25); //Set TX OS_NUM
- URT_RXOverSamplingSampleNumber_Select(URTX, 25); //Set RX OS_NUM
- URT_RXOverSamplingMode_Select(URTX, URT_RXSMP_3TIME);
- URT_TX_Cmd(URTX, ENABLE); //Enable TX
- URT_RX_Cmd(URTX, ENABLE); //Enable RX
- //=====Set Mode=====//
- //---Set Data character config---//
- DataDef.URT_TX_DataLength = URT_DataLength_8;
- DataDef.URT_RX_DataLength = URT_DataLength_8;
- DataDef.URT_TX_DataOrder = URT_DataTyped_LSB;
- DataDef.URT_RX_DataOrder = URT_DataTyped_LSB;
- DataDef.URT_TX_Parity = URT_Parity_No;
- DataDef.URT_RX_Parity = URT_Parity_No;
- DataDef.URT_TX_StopBits = URT_StopBits_1_0;
- DataDef.URT_RX_StopBits = URT_StopBits_1_0;
- DataDef.URT_TX_DataInverse = DISABLE;
- DataDef.URT_RX_DataInverse = DISABLE;
- URT_DataCharacter_Config(URTX, &DataDef);
- //---Set Mode Select---//
- URT_Mode_Select(URTX, URT_URT_mode);
- //---Set DataLine Select---//
- URT_DataLine_Select(URTX, URT_DataLine_2);
- //=====Set Error Control=====//
- // to do...
- //=====Set Bus Status Detect Control=====//
- // to do...
- //=====Set Data Control=====//
- URT_RXShadowBufferThreshold_Select(URTX, URT_RXTH_1BYTE);
- URT_IdlehandleMode_Select(URTX, URT_IDLEMode_No);
- URT_TXGaudTime_Select(URTX, 0);
- //=====Enable URT Interrupt=====//
- // URT_IT_Cmd(URTX, URT_IT_RX, ENABLE);
- // URT_ITEA_Cmd(URTX, ENABLE);
- // NVIC_EnableIRQ(URT0_IRQn);
- //=====Enable URT=====//
- URT_Cmd(URTX, ENABLE);
- //==See MG32x02z_URT0_IRQ.c when interrupt in
- }
- int fputc(int ch,FILE *f)
- {
- URT_SetTXData(URTX,1,ch);
- while(URT_GetITSingleFlagStatus(URTX,URT_IT_TC)==DRV_UnHappened);
- URT_ClearITFlag(URTX,URT_IT_TC);
- return ch;
- }
- void UartSendByte(int ch)
- {
- URT_SetTXData(URTX,1,ch);
- while(URT_GetITSingleFlagStatus(URTX,URT_IT_TC)==DRV_UnHappened);
- URT_ClearITFlag(URTX,URT_IT_TC);
- }
- void TM36_Capture_Init(void)
- {
- TM_TimeBaseInitTypeDef TM_TimeBase_InitStruct;
- // make sure :
- //===Set CSC init====
- //MG32x02z_CSC_Init.h(Configuration Wizard)
- //Select CK_HS source = CK_IHRCO
- //Select IHRCO = 12M
- //Select CK_MAIN Source = CK_HS
- //Configure PLL->Select APB Prescaler = CK_MAIN/1
- //Configure Peripheral On Mode Clock->TM20 = Enable
- //Configure Peripheral On Mode Clock->Port B = Enable
- //==Set GPIO init
- //TM20_IC0 pin config:
- //MG32x02z_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin4
- //GPIO port initial is 0xFFFF
- //PB4 mode is ODO
- //PB4 function TM20_IC0
- TM_DeInit(TM36);
- // ----------------------------------------------------
- // 1.TimeBase structure initial
- TM_TimeBaseStruct_Init(&TM_TimeBase_InitStruct);
- // modify parameter
- TM_TimeBase_InitStruct.TM_MainClockDirection =TM_UpCount;
- TM_TimeBase_InitStruct.TM_Period = 65535;
- TM_TimeBase_InitStruct.TM_Prescaler = 0;
- TM_TimeBase_InitStruct.TM_MainClockSource = TM_CK_INT;
- TM_TimeBase_InitStruct.TM_2ndClockSource = TM_CK_INT;
- TM_TimeBase_InitStruct.TM_CounterMode = Separate;
- TM_TimeBase_Init(TM36, &TM_TimeBase_InitStruct);
- // ----------------------------------------------------
- // 2.config overwrite mode (keep data)
- TM_IC3OverWritten_Cmd(TM36, TM_Keep);
- // ----------------------------------------------------
- // 3.config TM20 channel 0 function
- TM_CH3Function_Config(TM36, TM_InputCapture);
- TM_IN3Source_Select(TM36, IC0); // TM36_IN3 from IC0 (PB7)
- // ----------------------------------------------------
- #if (TM36_IC3_TriggerSrc == 1) // Rising to Rising edge
- // TM_TRGICounter_Select(TM36,TRGI_StartupRising); //TM36²»¿É¼ÓÕâÐÐ
- // TM_TRGIPrescaler_Select(TM36,TRGI_StartupRising); //TM36²»¿É¼ÓÕâÐÐ
- TM_IN3TriggerEvent_Select(TM36, IC_RisingEdge);
- TM_Counter_Cmd(TM36, ENABLE);
- TM_Prescaler_Cmd(TM36, ENABLE);
- #elif (TM20_IC0_TriggerSrc == 2) // Rising to Falling edge
- TM_TRGICounter_Select(TM20,TRGI_StartupRising);
- TM_TRGIPrescaler_Select(TM20,TRGI_StartupRising);
- TM_IN0TriggerEvent_Select(TM20, IC_FallingEdge);
- #elif (TM20_IC0_TriggerSrc == 3) // Falling to Falling edge
- TM_TRGICounter_Select(TM20,TRGI_StartupFalling);
- TM_TRGIPrescaler_Select(TM20,TRGI_StartupFalling);
- TM_IN0TriggerEvent_Select(TM20, IC_FallingEdge);
- #elif (TM20_IC0_TriggerSrc == 4) // Falling to Rising edge
- TM_TRGICounter_Select(TM20,TRGI_StartupFalling);
- TM_TRGIPrescaler_Select(TM20,TRGI_StartupFalling);
- TM_IN0TriggerEvent_Select(TM20, IC_RisingEdge);
- #elif (TM20_IC0_TriggerSrc == 5) // Rising to Dual edge
- TM_TRGICounter_Select(TM20,TRGI_StartupRising);
- TM_TRGIPrescaler_Select(TM20,TRGI_StartupRising);
- TM_IN0TriggerEvent_Select(TM20, IC_DualEdge);
- #endif
- // ----------------------------------------------------
- // 5.clear all flag
- TM_ClearFlag(TM36, TMx_CF3A | TMx_CF3B);
- // ----------------------------------------------------
- // 6.enable Timer
- TM_Timer_Cmd(TM36,ENABLE);
- }
- void CSC_Init (void)
- {
- UnProtectModuleReg(MEMprotect); // Setting flash wait state
- MEM_SetFlashWaitState(MEM_FWAIT_ONE); // 50MHz> Sysclk >=25MHz
- ProtectModuleReg(MEMprotect);
- UnProtectModuleReg(CSCprotect);
- CSC_CK_APB_Divider_Select(APB_DIV_1); // Modify CK_APB divider APB=CK_MAIN/1
- CSC_CK_AHB_Divider_Select(AHB_DIV_1); // Modify CK_AHB divider AHB=APB/1
- /* CK_HS selection */
- CSC_IHRCO_Select(IHRCO_12MHz); // IHRCO Sel 12MHz
- CSC_IHRCO_Cmd(ENABLE);
- while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
- CSC_ClearFlag(CSC_IHRCOF);
- CSC_CK_HS_Select(HS_CK_IHRCO); // CK_HS select IHRCO
- /* CK_MAIN */
- CSC_CK_MAIN_Select(MAIN_CK_HS);
- /* Configure ICKO function */
- /* Configure peripheral clock */
- CSC_PeriphProcessClockSource_Config(CSC_TM36_CKS, CK_APB); // Enable TIM36 module clock
- CSC_PeriphProcessClockSource_Config(CSC_UART0_CKS, CK_APB); // Enable UART0 module clock
- CSC_PeriphOnModeClock_Config(CSC_ON_UART0, ENABLE); // Enable UART0 module clock
- CSC_PeriphOnModeClock_Config(CSC_ON_TM36, ENABLE); // Enable TIM36 module clock
- CSC_PeriphOnModeClock_Config(CSC_ON_DMA,ENABLE); // Enable DMA module clock
- CSC_PeriphOnModeClock_Config(CSC_ON_PortB,ENABLE); // Enable Port B clock
- ProtectModuleReg(CSCprotect);
- }
- void DMA_Init(void)
- {
- DMA_BaseInitTypeDef DMATestPattern;
- // ------------------------------------------------------------------------
- // 1.Enable DMA
- DMA_Cmd(ENABLE);
- // ------------------------------------------------------------------------
- // 2.Enable Channel0
- DMA_Channel_Cmd(DMAChannel0, ENABLE);
- // ------------------------------------------------------------------------
- DMA_BaseInitStructure_Init(&DMATestPattern);
- // 3.initial & modify parameter
- // DMA channel select
- DMATestPattern.DMAChx = DMAChannel0;
- // channel x source/destination auto increase address
- DMATestPattern.SrcSINCSel = DISABLE;
- DMATestPattern.DestDINCSel = ENABLE;
- // DMA source peripheral config
- DMATestPattern.SrcSymSel = DMA_TM36_IC3;
- // DMA destination peripheral config
- DMATestPattern.DestSymSel = DMA_MEM_Write;
- // DMA Burst size config
- DMATestPattern.BurstDataSize = DMA_BurstSize_2Byte; //ÊäÈ벶»ñÊÇ16bit
- // DMA transfer data count initial number
- DMATestPattern.DMATransferNUM = 20;
- // source/destination config
- DMATestPattern.DMADestinationAddr = RcvBuf;
- DMA_Channel_Cmd(DMAChannel0, ENABLE);
- DMA_Base_Init(&DMATestPattern);
- }
- int main()
- {
- uint32_t j=0;
- PIN_InitTypeDef PINX_InitStruct;
- CSC_Init();
- Sample_URT0_Init();
- //==Set GPIO init
- PINX_InitStruct.PINX_Mode = PINX_Mode_Digital_I; // Pin select Digital input mode
- PINX_InitStruct.PINX_PUResistant = PINX_PUResistant_Enable; // Enable pull up resistor
- PINX_InitStruct.PINX_Speed = PINX_Speed_Low;
- PINX_InitStruct.PINX_OUTDrive = PINX_OUTDrive_Level0; // Pin output driver full strength.
- PINX_InitStruct.PINX_FilterDivider = PINX_FilterDivider_Bypass; // Pin input deglitch filter clock divider bypass
- PINX_InitStruct.PINX_Inverse = PINX_Inverse_Disable; // Pin input data not inverse
- PINX_InitStruct.PINX_Alternate_Function = 6; // Pin AFS = TIM36 IC
- GPIO_PinMode_Config(PINB(7),&PINX_InitStruct); // Set PB7 to TIM36 IC
- TM36_Capture_Init();
- DMA_Init();
- printf("hello!n");
- TM_DMAChannel_Cmd(TM36, TMx_DMA_IC3, ENABLE);
- DMA_ClearFlag(DMA, DMA_FLAG_CH0_TCF);
- DMA_StartRequest(DMAChannel0);
- while (DMA_GetSingleFlagStatus(DMA, DMA_FLAG_CH0_TCF) == DRV_UnHappened);
- DMA_ClearFlag(DMA, DMA_FLAG_CH0_TCF);
- for(j=0;j<10;j++)
- {
- printf("%d ",RcvBuf[j]);
- }
- TM_Timer_Cmd(TM36,DISABLE);
- return 0;
- }
这样,DMA就会自动采集10个数据了,如果要更多的数据,就从DMA中设置更多的传输量即可。
|