打印
[范例教程]

【M0】 MG32F02A 学习笔记⑯ PWM触发ADC

[复制链接]
1063|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
noctor|  楼主 | 2018-10-23 09:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
     上回我们说到了MG32F02A的BOD唤醒的使用。帖子详情:https://bbs.21ic.com/icview-2571922-1-1.html

      想了一下,我已经讲过了PWM,ADC,那么,那我可以尝试一下PWM触发ADC采样呀,好像这东西可以用来驱动直流无刷电机,虽然具体怎么驱动我也不是很了解。
      代码比较长,我放在二楼
沙发
noctor|  楼主 | 2018-10-23 09:45 | 只看该作者



#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_PrescalerCounter_Range 120
#define TM36_MainCounter_Range      1000
#define URTX URT0

uint8_t RcvBuf[20] __attribute__((at(0x20003800)));


//if user wants to delay 1ms and CK_TM00_PR is 12MHz.
//The Total clocks is 12M*1ms = 12000.
//User can set "clock prescaler"=100 and "pulse width"=120 .   


void Sample_TM36_PWM(void)
{  
    TM_TimeBaseInitTypeDef TM_TimeBase_InitStruct;
   
                //        The period = (prescaler*main counter)/12MHz (CK_TM36_PR=12MHz) (s)
    //  User can update duty cycle by replace CCxB register.
         
    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 = TM36_MainCounter_Range-1;
    TM_TimeBase_InitStruct.TM_Prescaler = TM36_PrescalerCounter_Range-1;
    TM_TimeBase_InitStruct.TM_CounterMode =Cascade;
   
    TM_TimeBase_Init(TM36, &TM_TimeBase_InitStruct);
   
    // ----------------------------------------------------
    // 2.config TM36 channel 1 function
    TM_CH1Function_Config(TM36, TM_16bitPWM);

   
    // ----------------------------------------------------
    // 3.Enable TM36 channel 1 Output (just output TM36_OC10)
    TM_OC10Output_Cmd(TM36,ENABLE);   
    TM_InverseOC1z_Cmd(TM36, DISABLE);
    TM_OC1zOutputState_Init(TM36, CLR);
   
                TM_OC1NOutput_Cmd(TM36, ENABLE);
    TM_InverseOC1N_Cmd(TM36, DISABLE);
               
    // ----------------------------------------------------
                // 4.set trigger output source
                TM_TRGO_Select(TM36, TRGO_OS1);
               
    // ----------------------------------------------------
    // 5.set match point (Duty cycle %) for PWM channel0.Less value of CCnA/CCnB,more lighten (1~65536)
               
    TM_SetCC1A(TM36,500);        
    TM_SetCC1B(TM36,500);                // reload value when overflow

    // ----------------------------------------------------
    // 6.select Edge Align
    TM_AlignmentMode_Select(TM36, TM_CenterAlign);
   
    // ----------------------------------------------------
    // 7.clear flag
    TM_ClearFlag(TM36, TMx_CF0A | TMx_CF1A | TMx_CF2A);
   
    // ----------------------------------------------------
    // 8.Timer enable
    TM_Timer_Cmd(TM36,ENABLE);
}

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_RX_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 ADC_Init(void)
{
        ADC_InitTypeDef ADC_Base;
   
   
    // 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->ADC = Enable
    //Configure Peripheral On Mode Clock->Port A = Enable
       
    //==Set GPIO init
    //MG32x02z_GPIO_Init.h(Configuration Wizard)->Use GPIOA->Pin4
    //GPIO port initial is 0xFFFF
    //Pin4 mode is AIO
    //Pin4 function GPA4

    ADC_DeInit(ADC0);
    // ------------------------------------------------------------------------
    // 1.Config ADC base parameter   
    ADC_BaseStructure_Init(&ADC_Base);
       // modify parameter
    ADC_Base.ADCMainClockSelect = ADC_CKADC;
    ADC_Base.ADC_IntCK_Div = ADC_IntDIV16;   // for internal clock divider
   
        // ADC data alignment mode (Right or Left)
    ADC_Base.ADC_DataAlign = ADC_RightJustified;
        
        // ADC conversion resolution 8, 10 or 12 bit
    ADC_Base.ADC_ResolutionSel = ADC_12BitData;
        
        // ADC overwritten data or keep data
    ADC_Base.ADC_DataOverrunEvent = ADC_DataOverWritten;
        
   
    ADC_Base_Init(ADC0, &ADC_Base);
   
    // ------------------------------------------------------------------------
        // 2.Enable ADC
    ADC_Cmd(ADC0, ENABLE);
   
    // ------------------------------------------------------------------------
    // 3.Config ADC Mode
    ADC_ConversionMode_Select(ADC0, ADCMode);   // one-shot
    ADC_PGA_Cmd(ADC0, DISABLE);                 // Disable PGA
    ADC_SingleDifferentMode_Select(ADC0, ADC_SingleMode);  // Single Mode  
   
    // ------------------------------------------------------------------------
    // 4.Clear all flag
    ADC_ClearFlag(ADC0, 0xFFFFFFFF);

    // ------------------------------------------------------------------------
    // 5.Start Calibration
   
                ADC_StartCalibration(ADC0, ENABLE);
                // 6.Select Exnternal Channel (PA4)
    ADC_ExternalChannel_Select(ADC0, ADC_ExtAIN4);
        //        ADC_InternalChannel_Select(ADC0, ADC_INT_IVREF);
        //        ADC_ExternalChannel_Select(ADC0, ADC_ExtAIN4);

    // ------------------------------------------------------------------------
        // 7.Trigger Source select and Start conversion
    ADC_TriggerSource_Select(ADC0, ADC_TM36_TRGO);
                ADC_TriggerEdge_Select(ADC0, ADC_AcceptFallingEdge);
               
               
}

void CSC_Init (void)
{
        CSC_PLL_TyprDef CSC_PLL_CFG;
       
  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
       
        /* PLL */
        /**********************************************************/
        CSC_PLL_CFG.InputDivider=PLLI_DIV_2;        // 12M/2=6M
        CSC_PLL_CFG.Multiplication=PLLIx16;                // 6M*16=96M
        CSC_PLL_CFG.OutputDivider=PLLO_DIV_2;        // PLLO=96M/2=48M
        CSC_PLL_Config(&CSC_PLL_CFG);
        CSC_PLL_Cmd(ENABLE);
        while(CSC_GetSingleFlagStatus(CSC_PLLF) == DRV_Normal);
        CSC_ClearFlag(CSC_PLLF);
        /**********************************************************/

       
        /* CK_MAIN */
        CSC_CK_MAIN_Select(MAIN_CK_HS);       


        /* Configure ICKO function */
               
        /* Configure peripheral clock */
        CSC_PeriphOnModeClock_Config(CSC_ON_PortA,ENABLE);                                          // Enable Port A clock
        CSC_PeriphOnModeClock_Config(CSC_ON_PortB,ENABLE);                                          // Enable Port B clock
        CSC_PeriphOnModeClock_Config(CSC_ON_PortC,ENABLE);                                          // Enable Port C clock
        CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);                                          // Enable Port D clock
       
        CSC_PeriphProcessClockSource_Config(CSC_TM36_CKS, CK_APB);
        CSC_PeriphOnModeClock_Config(CSC_ON_TM36, ENABLE);                                          // Enable TIM36 module clock
       
        CSC_PeriphProcessClockSource_Config(CSC_UART0_CKS, CK_APB);
        CSC_PeriphOnModeClock_Config(CSC_ON_UART0, ENABLE);                                          // Enable UART0 module clock
       
        CSC_PeriphProcessClockSource_Config(CSC_ADC0_CKS, CK_APB);
        CSC_PeriphOnModeClock_Config(CSC_ON_ADC0, ENABLE);                                          // Enable ADC0 module clock       
       
        CSC_PeriphOnModeClock_Config(CSC_ON_DMA,ENABLE);

  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_ADC0_IN;
        
        // DMA destination peripheral config
        DMATestPattern.DestSymSel = DMA_MEM_Wrtie;
        
        // DMA Burst size config
        DMATestPattern.BurstDataSize = DMA_BurstSize_1Byte;
        
        // DMA transfer data count initial number
        DMATestPattern.DMATransferNUM = 20;
   
        // source/destination config
                                DMATestPattern.DMASourceAddr = &ADC0->DAT0;
        DMATestPattern.DMADestinationAddr = (uint32_t *)&RcvBuf;
                               
                                                 // Setting M2M simple parameter
                                                 
                                ADC_DMA_Cmd(ADC0, ENABLE);
                                DMA_Channel_Cmd(DMAChannel0, ENABLE);
        DMA_Base_Init(&DMATestPattern);
               
       
}


int main()
{
        int i;
        double x;
        PIN_InitTypeDef PINX_InitStruct;
       
        CSC_Init();
        Sample_URT0_Init();
        Sample_TM36_PWM();
        ADC_Init();

       
        //==Set GPIO init
        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  = 6;                                                                                                                // Pin AFS = TIM36 OC10
        GPIO_PinMode_Config(PINC(2),&PINX_InitStruct);                                                                                                   // Set PC6 function
       
        PINX_InitStruct.PINX_Alternate_Function  = 6;                                                                                                                // Pin AFS =TIM36 trigger output
        GPIO_PinMode_Config(PINC(7),&PINX_InitStruct);                                                                                                   // Set PC2 function
       
        PINX_InitStruct.PINX_Mode                                 = PINX_Mode_Analog_IO;                                                                 // Pin select Analog Input/Output mode
        PINX_InitStruct.PINX_Alternate_Function  = 0;                                                                                                                // Pin AFS = GPA
        GPIO_PinMode_Config(PINA(4),&PINX_InitStruct);                                                                                            // Set PA4 function

        printf("hello\n");
        i=0;

        while(1)
        {               
               
                i++;
            if(i>=500000)
            {
                                i=1;
                while(ADC_GetSingleFlagStatus(ADC0, ADC_E1CNVF) == DRV_UnHappened);
    ADC_ClearFlag(ADC0, ADC_E1CNVF);
               
                x=((ADC_GetDAT0Data(ADC0)*5)/4096.0);    //This is the Voltage of Verf.

                printf("%lf\n",x);
                   }
               
        }       

}




















使用特权

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

本版积分规则

26

主题

82

帖子

3

粉丝