[范例教程]

【M0】 MG32F02A 学习笔记⑪ ADC转换

[复制链接]
5848|21
手机看帖
扫描二维码
随时随地手机跟帖
noctor|  楼主 | 2018-10-12 09:20 | 显示全部楼层 |阅读模式
本帖最后由 noctor 于 2018-10-12 09:20 编辑

      上回我们说到了MG32F02A的中断。帖子详情:https://bbs.21ic.com/icview-2563924-1-1.html

       这次讲讲ADC怎么用吧。另外,这次ADC我不建议使用DMA,因为这一版的M0的ADC是12位ADC,而DAT寄存器是32位,而且剩余的位并不是空白的,而是还塞了一些flag等信息在DAT寄存器里面。。所以就算你DMA把ADC抓出来,也会导致把不要的数据一起抓出来,最后你还是得自己去操作选择你的数据,所以DMA在这儿意义不大,不过据说这个问题到了下一版M0会修正,至于是啥时候,我就不知道了。
      代码放在楼下。
       烧进程序之后你看会发现,程序根本跑不动,这是为什么呢?你看数据手册:
       458365bbff4c3d5352.png
       板子上的VREF+引脚也是需要供电,而此处的供电会影响ADC转换式,此处的IVREF就是你接的供电,此处我接的是5V,因此公式我带入的是5。
672795bbff5722799b.png
      OK,这样你的ADC就能使用啦。
noctor|  楼主 | 2018-10-12 09:20 | 显示全部楼层
本帖最后由 noctor 于 2018-10-15 12:11 编辑



#include "MG32x02z_DRV.H"
#include "MG32x02z_ADC_DRV.h"
#include <stdio.h>

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;


#define URTX URT0



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_PeriphProcessClockSource_Config(CSC_ADC0_CKS, CK_APB);
        CSC_PeriphProcessClockSource_Config(CSC_UART0_CKS, CK_APB);
         CSC_PeriphOnModeClock_Config(CSC_ON_ADC0,ENABLE);
        CSC_PeriphOnModeClock_Config(CSC_ON_UART0,ENABLE);
        CSC_PeriphOnModeClock_Config(CSC_ON_PortA,ENABLE);
         CSC_PeriphOnModeClock_Config(CSC_ON_PortB,ENABLE);
        CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);

  ProtectModuleReg(CSCprotect);
   
}

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_START);

}


int main()
{
        int i;
        double y;
        PIN_InitTypeDef PINX_InitStruct;
        CSC_Init();
        PINX_InitStruct.PINX_Mode                                 = PINX_Mode_PushPull_O;          // 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 = 0;                                                 // Pin AFS = 0
  GPIO_PinMode_Config(PINE(15),&PINX_InitStruct);                                          // D6 setup at PE15
        
        PINX_InitStruct.PINX_Mode                                 = PINX_Mode_Analog_IO;          // Pin select digital input mode
        PINX_InitStruct.PINX_Alternate_Function = 0;                                                 // Pin AFS = 0
        GPIO_PinMode_Config(PINA(4),&PINX_InitStruct);                                          // D6 setup at PA4
        
        Sample_URT0_Init();
        printf("hello\n");
        ADC_Init();

        for(i=0;i<200;i++);
     
        i=0;
               
        while(1)
        {               
               
                i++;
            if(i>=500000)
            {
                        //        PE15=~PE15;
                                i=1;
ADC_SoftwareConversion_Cmd(ADC0, ENABLE);
    // ------------------------------------------------------------------------
        // 8.until E1CNVF & clear flag
    while(ADC_GetSingleFlagStatus(ADC0, ADC_E1CNVF) == DRV_UnHappened);
    ADC_ClearFlag(ADC0, ADC_E1CNVF);
               
                y=((ADC_GetDAT0Data(ADC0)*5)/4096.0); //This is the Voltage of PA4

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

使用特权

评论回复
344864311| | 2018-10-12 11:10 | 显示全部楼层
不错, 加油,一步一步就可以学完所有的功能了。我也跟着学习。

使用特权

评论回复
noctor|  楼主 | 2018-10-12 11:13 | 显示全部楼层
344864311 发表于 2018-10-12 11:10
不错, 加油,一步一步就可以学完所有的功能了。我也跟着学习。

谢谢支持哦,遇到问题也可以在论坛里面贴出来,看看能不能解决

使用特权

评论回复
four_zhg| | 2018-11-25 22:04 | 显示全部楼层
没芯片,没板子,只能干看,没法一起试啊

使用特权

评论回复
noctor|  楼主 | 2018-11-26 08:56 | 显示全部楼层
four_zhg 发表于 2018-11-25 22:04
没芯片,没板子,只能干看,没法一起试啊

哈哈没关系,我只是把方法先公布出来,给已经有板子的同伴们一起学习,没有板子有兴趣的,可以找代理商看看能不能买一套回来

使用特权

评论回复
kk5004| | 2018-11-26 11:34 | 显示全部楼层
noctor 发表于 2018-11-26 08:56
哈哈没关系,我只是把方法先公布出来,给已经有板子的同伴们一起学习,没有板子有兴趣的,可以找代理商看 ...

你好,我這邊是 希特電子(深圳)有限公司, 是中國大陸笙泉MCU的代理商  主要幫你們解決開發的技術問題可以 加我 QQ 328626444 詳細聊聊,   潘,R   很開心遇到大家 希望可以互相幫助 一起學習 共同成長

使用特权

评论回复
noctor|  楼主 | 2018-11-26 17:11 | 显示全部楼层
kk5004 发表于 2018-11-26 11:34
你好,我這邊是 希特電子(深圳)有限公司, 是中國大陸笙泉MCU的代理商  主要幫你們解決開發的技術問題 ...

你回复错人啦,我有板子,那位four_zhg才没有板子

使用特权

评论回复
杨光光光,| | 2021-9-30 10:26 | 显示全部楼层
本帖最后由 杨光光光, 于 2021-9-30 10:28 编辑
kk5004 发表于 2018-11-26 11:34
你好,我這邊是 希特電子(深圳)有限公司, 是中國大陸笙泉MCU的代理商  主要幫你們解決開發的技術問題 ...


使用特权

评论回复
kkzz| | 2021-10-2 18:04 | 显示全部楼层
MG32F02A效果怎么样  

使用特权

评论回复
hudi008| | 2021-10-2 18:04 | 显示全部楼层
MG32F02A有DMA吗   

使用特权

评论回复
lzmm| | 2021-10-2 18:04 | 显示全部楼层
MG32F02A来个教程吧   

使用特权

评论回复
minzisc| | 2021-10-2 18:04 | 显示全部楼层
多通道连续转换吗     

使用特权

评论回复
selongli| | 2021-10-2 18:05 | 显示全部楼层
参考电压芯片有什么要求   

使用特权

评论回复
fentianyou| | 2021-10-2 18:05 | 显示全部楼层
推荐使用DMA啊。        

使用特权

评论回复
xiaoyaodz| | 2021-10-2 18:05 | 显示全部楼层

这个的性能怎么样     

使用特权

评论回复
pixhw| | 2021-10-2 18:06 | 显示全部楼层

这个是哪款板子的代码?   

使用特权

评论回复
sdlls| | 2021-10-2 18:06 | 显示全部楼层
ADC转换这么复杂吗   

使用特权

评论回复
febgxu| | 2021-10-2 18:06 | 显示全部楼层
MG32F02A的中断可行。  

使用特权

评论回复
杨光光光,| | 2021-10-11 21:04 | 显示全部楼层
想问一下大佬,为什么TM00老是进不去中断服务函数啊,楼主能指点一下,发一个定时器TM00加一个中断服务函数出来,我真的是太窝火了,感谢感谢

使用特权

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

本版积分规则

26

主题

82

帖子

3

粉丝