[范例教程]

【M0】 MG32F02A 学习笔记⑱ TM36 输入捕获DMA

[复制链接]
1009|2
手机看帖
扫描二维码
随时随地手机跟帖
noctor|  楼主 | 2018-11-15 10:50 | 显示全部楼层 |阅读模式
     上回我们说到了MG32F02A的PWM互补输出 带死区的使用。帖子详情:https://bbs.21ic.com/icview-2583766-1-1.html

      这次,我们讲一下输入捕获带DMA的做法。

      首先,根据User Guide得知,MG32F02A只有TM36的IC3支持DMA功能,因此我们只能用TM36

代码附上:
#include "MG32x02z_DRV.H"
#include <stdio.h>

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中设置更多的传输量即可。
344864311| | 2018-11-16 10:04 | 显示全部楼层

使用特权

评论回复
344864311| | 2018-11-17 08:47 | 显示全部楼层
谢谢分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

82

帖子

3

粉丝