[技术贴] 【M0】 MG32F02A 学习笔记⑱ TM36 输入捕获DMA

[复制链接]
152|2
 楼主 | 2018-11-15 10:50 | 显示全部楼层 |阅读模式
     上回我们说到了MG32F02A的PWM互补输出 带死区的使用。帖子详情:http://bbs.21ic.com/icview-2583766-1-1.html

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

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

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

  3. typedef uint8_t u8;
  4. typedef uint16_t u16;
  5. typedef uint32_t u32;
  6. typedef uint64_t u64;

  7. #define TM36_IC3_TriggerSrc       1
  8. #define URTX URT0
  9. uint16_t RcvBuf[10]={0};

  10. void Sample_URT0_Init(void)
  11. {
  12.     URT_BRG_TypeDef  URT_BRG;
  13.     URT_Data_TypeDef DataDef;
  14.     PIN_InitTypeDef PINX_InitStruct;
  15.     //==Set CSC init
  16.     //MG32x02z_CSC_Init.h(Configuration Wizard)
  17.     //Select CK_HS source = CK_IHRCO
  18.     //Select IHRCO = 11.0592M
  19.     //Select CK_MAIN Source = CK_HS
  20.     //Configure PLL->Select APB Prescaler = CK_MAIN/1
  21.     //Configure Peripheral On Mode Clock->Port B/URT0 = Enable
  22.     //Configure Peripheral On Mode Clock->URT0->Select URT0_PR Source = CK_APB(11.0592)
  23.    
  24.     //==Set GPIO init
  25.     //MG32x02z_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin8/9
  26.     //GPIO port initial is 0xFFFF
  27.     //Pin8 mode is PPO/Pin9 mode is ODO
  28.     //Pin8/9 pull-up resister Enable
  29.     //Pin8/9 function URT0_TX/RX
  30.   PINX_InitStruct.PINX_Mode                                 = PINX_Mode_PushPull_O;                  // Pin select Push Pull mode
  31.         PINX_InitStruct.PINX_PUResistant                 = PINX_PUResistant_Enable;          // Enable pull up resistor
  32.         PINX_InitStruct.PINX_Speed                                   = PINX_Speed_Low;                        
  33.         PINX_InitStruct.PINX_OUTDrive                         = PINX_OUTDrive_Level0;                 // Pin output driver full strength.
  34.         PINX_InitStruct.PINX_FilterDivider                   = PINX_FilterDivider_Bypass;        // Pin input deglitch filter clock divider bypass
  35.         PINX_InitStruct.PINX_Inverse                         = PINX_Inverse_Disable;                 // Pin input data not inverse
  36.         PINX_InitStruct.PINX_Alternate_Function  = 3;                                // Pin AFS = URT0_TX
  37.         GPIO_PinMode_Config(PINB(8),&PINX_InitStruct);                                                          // TXD at PB8

  38.         PINX_InitStruct.PINX_Mode                                 = PINX_Mode_OpenDrain_O;                 // Pin select Open Drain mode
  39.         PINX_InitStruct.PINX_Alternate_Function  = 3;                                // Pin AFS = URT0_RX
  40.         GPIO_PinMode_Config(PINB(9),&PINX_InitStruct);                                                          // RXD at PB9  
  41.         
  42.         
  43.    
  44.     //=====Set Clock=====//
  45.     //---Set BaudRate---//
  46.     URT_BRG.URT_InteranlClockSource = URT_BDClock_PROC;
  47.     URT_BRG.URT_BaudRateMode = URT_BDMode_Separated;
  48.     URT_BRG.URT_PrescalerCounterReload = 0;                        //Set PSR
  49.     URT_BRG.URT_BaudRateCounterReload = 3;                        //Set RLR
  50.     URT_BaudRateGenerator_Config(URTX, &URT_BRG);                    //BR115200 = f(CK_URTx)/(PSR+1)/(RLR+1)/(OS_NUM+1)
  51.     URT_BaudRateGenerator_Cmd(URTX, ENABLE);                    //Enable BaudRateGenerator
  52.     //---TX/RX Clock---//
  53.     URT_TXClockSource_Select(URTX, URT_TXClock_Internal);        //URT_TX use BaudRateGenerator
  54.     URT_RXClockSource_Select(URTX, URT_RXClock_Internal);        //URT_RX use BaudRateGenerator
  55.     URT_TXOverSamplingSampleNumber_Select(URTX, 25);                //Set TX OS_NUM
  56.     URT_RXOverSamplingSampleNumber_Select(URTX, 25);                //Set RX OS_NUM
  57.     URT_RXOverSamplingMode_Select(URTX, URT_RXSMP_3TIME);
  58.     URT_TX_Cmd(URTX, ENABLE);                                    //Enable TX
  59.     URT_RX_Cmd(URTX, ENABLE);                                    //Enable RX
  60.    
  61.    

  62.     //=====Set Mode=====//
  63.     //---Set Data character config---//
  64.     DataDef.URT_TX_DataLength  = URT_DataLength_8;
  65.     DataDef.URT_RX_DataLength  = URT_DataLength_8;
  66.     DataDef.URT_TX_DataOrder   = URT_DataTyped_LSB;
  67.     DataDef.URT_RX_DataOrder   = URT_DataTyped_LSB;
  68.     DataDef.URT_TX_Parity      = URT_Parity_No;
  69.     DataDef.URT_RX_Parity      = URT_Parity_No;
  70.     DataDef.URT_TX_StopBits    = URT_StopBits_1_0;
  71.     DataDef.URT_RX_StopBits    = URT_StopBits_1_0;
  72.     DataDef.URT_TX_DataInverse = DISABLE;
  73.     DataDef.URT_RX_DataInverse = DISABLE;
  74.     URT_DataCharacter_Config(URTX, &DataDef);
  75.     //---Set Mode Select---//
  76.     URT_Mode_Select(URTX, URT_URT_mode);
  77.     //---Set DataLine Select---//
  78.     URT_DataLine_Select(URTX, URT_DataLine_2);
  79.    
  80.     //=====Set Error Control=====//
  81.     // to do...
  82.    
  83.     //=====Set Bus Status Detect Control=====//
  84.     // to do...
  85.    
  86.     //=====Set Data Control=====//
  87.     URT_RXShadowBufferThreshold_Select(URTX, URT_RXTH_1BYTE);
  88.     URT_IdlehandleMode_Select(URTX, URT_IDLEMode_No);
  89.     URT_TXGaudTime_Select(URTX, 0);
  90.    
  91.     //=====Enable URT Interrupt=====//
  92. //   URT_IT_Cmd(URTX, URT_IT_RX, ENABLE);
  93.   //  URT_ITEA_Cmd(URTX, ENABLE);
  94.   //  NVIC_EnableIRQ(URT0_IRQn);
  95.                
  96.     //=====Enable URT=====//
  97.     URT_Cmd(URTX, ENABLE);
  98.                
  99.         //==See MG32x02z_URT0_IRQ.c when interrupt in
  100. }

  101. int fputc(int ch,FILE *f)
  102. {
  103.         
  104.         URT_SetTXData(URTX,1,ch);
  105.         while(URT_GetITSingleFlagStatus(URTX,URT_IT_TC)==DRV_UnHappened);
  106.         URT_ClearITFlag(URTX,URT_IT_TC);
  107.         
  108.         return ch;
  109. }

  110. void UartSendByte(int ch)
  111. {
  112.         
  113.         URT_SetTXData(URTX,1,ch);
  114.         while(URT_GetITSingleFlagStatus(URTX,URT_IT_TC)==DRV_UnHappened);
  115.         URT_ClearITFlag(URTX,URT_IT_TC);
  116.         
  117. }

  118. void TM36_Capture_Init(void)
  119. {  
  120. TM_TimeBaseInitTypeDef TM_TimeBase_InitStruct;
  121.      

  122.     // make sure :
  123.         
  124.     //===Set CSC init====
  125.     //MG32x02z_CSC_Init.h(Configuration Wizard)
  126.     //Select CK_HS source = CK_IHRCO
  127.     //Select IHRCO = 12M
  128.     //Select CK_MAIN Source = CK_HS
  129.     //Configure PLL->Select APB Prescaler = CK_MAIN/1
  130.     //Configure Peripheral On Mode Clock->TM20 = Enable
  131.     //Configure Peripheral On Mode Clock->Port B = Enable
  132.         
  133.     //==Set GPIO init
  134.     //TM20_IC0 pin config:
  135.     //MG32x02z_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin4
  136.     //GPIO port initial is 0xFFFF
  137.     //PB4 mode is ODO
  138.     //PB4 function TM20_IC0
  139.         

  140.          
  141.     TM_DeInit(TM36);
  142.    
  143.     // ----------------------------------------------------
  144.     // 1.TimeBase structure initial
  145.     TM_TimeBaseStruct_Init(&TM_TimeBase_InitStruct);
  146.    
  147.     // modify parameter
  148.     TM_TimeBase_InitStruct.TM_MainClockDirection =TM_UpCount;
  149.     TM_TimeBase_InitStruct.TM_Period = 65535;
  150.     TM_TimeBase_InitStruct.TM_Prescaler = 0;
  151.                 TM_TimeBase_InitStruct.TM_MainClockSource = TM_CK_INT;                                
  152.     TM_TimeBase_InitStruct.TM_2ndClockSource = TM_CK_INT;                                       
  153.     TM_TimeBase_InitStruct.TM_CounterMode = Separate;
  154.    
  155.     TM_TimeBase_Init(TM36, &TM_TimeBase_InitStruct);
  156.    
  157.     // ----------------------------------------------------
  158.     // 2.config overwrite mode (keep data)
  159.     TM_IC3OverWritten_Cmd(TM36, TM_Keep);
  160.    
  161.     // ----------------------------------------------------
  162.     // 3.config TM20 channel 0 function
  163.     TM_CH3Function_Config(TM36, TM_InputCapture);
  164.     TM_IN3Source_Select(TM36, IC0);      // TM36_IN3 from IC0 (PB7)            
  165.    
  166.     // ----------------------------------------------------
  167.    
  168.                
  169.                 #if (TM36_IC3_TriggerSrc == 1)      // Rising to Rising edge
  170. //    TM_TRGICounter_Select(TM36,TRGI_StartupRising);      //TM36²»¿É¼ÓÕâÐÐ
  171. //    TM_TRGIPrescaler_Select(TM36,TRGI_StartupRising);      //TM36²»¿É¼ÓÕâÐÐ
  172.     TM_IN3TriggerEvent_Select(TM36, IC_RisingEdge);
  173.                 TM_Counter_Cmd(TM36, ENABLE);
  174.           TM_Prescaler_Cmd(TM36, ENABLE);

  175. #elif (TM20_IC0_TriggerSrc == 2)    // Rising to Falling edge
  176.     TM_TRGICounter_Select(TM20,TRGI_StartupRising);
  177.     TM_TRGIPrescaler_Select(TM20,TRGI_StartupRising);
  178.     TM_IN0TriggerEvent_Select(TM20, IC_FallingEdge);
  179.    
  180. #elif (TM20_IC0_TriggerSrc == 3)    // Falling to Falling edge
  181.     TM_TRGICounter_Select(TM20,TRGI_StartupFalling);
  182.     TM_TRGIPrescaler_Select(TM20,TRGI_StartupFalling);
  183.     TM_IN0TriggerEvent_Select(TM20, IC_FallingEdge);
  184.    
  185. #elif (TM20_IC0_TriggerSrc == 4)    // Falling to Rising edge
  186.     TM_TRGICounter_Select(TM20,TRGI_StartupFalling);
  187.     TM_TRGIPrescaler_Select(TM20,TRGI_StartupFalling);
  188.     TM_IN0TriggerEvent_Select(TM20, IC_RisingEdge);
  189.                
  190. #elif (TM20_IC0_TriggerSrc == 5)    // Rising to Dual edge
  191.     TM_TRGICounter_Select(TM20,TRGI_StartupRising);
  192.     TM_TRGIPrescaler_Select(TM20,TRGI_StartupRising);
  193.     TM_IN0TriggerEvent_Select(TM20, IC_DualEdge);
  194.                                 
  195. #endif   
  196.    
  197.     // ----------------------------------------------------
  198.     // 5.clear all flag
  199.     TM_ClearFlag(TM36, TMx_CF3A | TMx_CF3B);
  200.    
  201.     // ----------------------------------------------------
  202.     // 6.enable Timer
  203.     TM_Timer_Cmd(TM36,ENABLE);
  204.    
  205. }


  206. void CSC_Init (void)
  207. {

  208.   UnProtectModuleReg(MEMprotect);             // Setting flash wait state
  209.   MEM_SetFlashWaitState(MEM_FWAIT_ONE);        // 50MHz> Sysclk >=25MHz
  210.   ProtectModuleReg(MEMprotect);

  211.   UnProtectModuleReg(CSCprotect);
  212.         CSC_CK_APB_Divider_Select(APB_DIV_1);        // Modify CK_APB divider        APB=CK_MAIN/1
  213.         CSC_CK_AHB_Divider_Select(AHB_DIV_1);        // Modify CK_AHB divider        AHB=APB/1

  214.         
  215.         /* CK_HS selection */
  216.         CSC_IHRCO_Select(IHRCO_12MHz);                        // IHRCO Sel 12MHz
  217.         CSC_IHRCO_Cmd(ENABLE);
  218.         while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
  219.         CSC_ClearFlag(CSC_IHRCOF);
  220.         CSC_CK_HS_Select(HS_CK_IHRCO);                        // CK_HS select IHRCO
  221.         
  222.         /* CK_MAIN */
  223.         CSC_CK_MAIN_Select(MAIN_CK_HS);        


  224.         /* Configure ICKO function */
  225.                
  226.         /* Configure peripheral clock */
  227.         CSC_PeriphProcessClockSource_Config(CSC_TM36_CKS, CK_APB);    // Enable TIM36 module clock
  228.         CSC_PeriphProcessClockSource_Config(CSC_UART0_CKS, CK_APB);   // Enable UART0 module clock
  229.         CSC_PeriphOnModeClock_Config(CSC_ON_UART0, ENABLE);                                          // Enable UART0 module clock
  230.         CSC_PeriphOnModeClock_Config(CSC_ON_TM36, ENABLE);                                          // Enable TIM36 module clock
  231.         CSC_PeriphOnModeClock_Config(CSC_ON_DMA,ENABLE);                                            // Enable DMA module clock
  232.         CSC_PeriphOnModeClock_Config(CSC_ON_PortB,ENABLE);                                          // Enable Port B clock
  233.         
  234.   ProtectModuleReg(CSCprotect);
  235.    
  236. }

  237. void DMA_Init(void)
  238. {
  239.          DMA_BaseInitTypeDef DMATestPattern;

  240.     // ------------------------------------------------------------------------
  241.     // 1.Enable DMA
  242.     DMA_Cmd(ENABLE);
  243.    
  244.     // ------------------------------------------------------------------------
  245.     // 2.Enable Channel0
  246.     DMA_Channel_Cmd(DMAChannel0, ENABLE);
  247.    
  248.     // ------------------------------------------------------------------------
  249.     DMA_BaseInitStructure_Init(&DMATestPattern);
  250.    
  251.     // 3.initial & modify parameter
  252.       
  253.         // DMA channel select
  254.         DMATestPattern.DMAChx = DMAChannel0;
  255.         
  256.         // channel x source/destination auto increase address
  257.         DMATestPattern.SrcSINCSel = DISABLE;
  258.         DMATestPattern.DestDINCSel = ENABLE;
  259.         
  260.         // DMA source peripheral config
  261.         DMATestPattern.SrcSymSel = DMA_TM36_IC3;
  262.         
  263.         // DMA destination peripheral config
  264.         DMATestPattern.DestSymSel = DMA_MEM_Write;
  265.         
  266.         // DMA Burst size config
  267.         DMATestPattern.BurstDataSize = DMA_BurstSize_2Byte;           //ÊäÈ벶»ñÊÇ16bit
  268.         
  269.         // DMA transfer data count initial number
  270.         DMATestPattern.DMATransferNUM = 20;
  271.    
  272.         // source/destination config
  273.         DMATestPattern.DMADestinationAddr = RcvBuf;
  274.                                 
  275.                                 DMA_Channel_Cmd(DMAChannel0, ENABLE);
  276.                                 DMA_Base_Init(&DMATestPattern);
  277. }


  278. int main()
  279. {
  280.         uint32_t j=0;
  281.         PIN_InitTypeDef PINX_InitStruct;
  282.         CSC_Init();
  283.         Sample_URT0_Init();
  284.                 //==Set GPIO init
  285.         PINX_InitStruct.PINX_Mode                                 = PINX_Mode_Digital_I;                                                                 // Pin select Digital input mode
  286.         PINX_InitStruct.PINX_PUResistant                 = PINX_PUResistant_Enable;                                  // Enable pull up resistor
  287.         PINX_InitStruct.PINX_Speed                                   = PINX_Speed_Low;                        
  288.         PINX_InitStruct.PINX_OUTDrive                         = PINX_OUTDrive_Level0;                                                         // Pin output driver full strength.
  289.         PINX_InitStruct.PINX_FilterDivider                   = PINX_FilterDivider_Bypass;                        // Pin input deglitch filter clock divider bypass
  290.         PINX_InitStruct.PINX_Inverse                         = PINX_Inverse_Disable;                                                         // Pin input data not inverse
  291.         PINX_InitStruct.PINX_Alternate_Function  = 6;                                                                                                                // Pin AFS = TIM36 IC
  292.         GPIO_PinMode_Config(PINB(7),&PINX_InitStruct);                                                                                                   // Set PB7 to TIM36 IC
  293.   
  294.         TM36_Capture_Init();
  295.         DMA_Init();
  296.         
  297.         printf("hello!\n");
  298.         
  299.         TM_DMAChannel_Cmd(TM36, TMx_DMA_IC3, ENABLE);
  300.         DMA_ClearFlag(DMA, DMA_FLAG_CH0_TCF);
  301.         
  302.         DMA_StartRequest(DMAChannel0);
  303.         while (DMA_GetSingleFlagStatus(DMA, DMA_FLAG_CH0_TCF) == DRV_UnHappened);
  304.         DMA_ClearFlag(DMA, DMA_FLAG_CH0_TCF);
  305.                
  306.         for(j=0;j<10;j++)
  307.         {
  308.                 printf("%d ",RcvBuf[j]);
  309.         }
  310.         TM_Timer_Cmd(TM36,DISABLE);
  311.         return 0;        
  312.                         
  313. }
复制代码

      这样,DMA就会自动采集10个数据了,如果要更多的数据,就从DMA中设置更多的传输量即可。
| 2018-11-16 10:04 | 显示全部楼层
| 2018-11-17 08:47 | 显示全部楼层
谢谢分享
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

快速回复 返回顶部 返回列表