上回我们说到了MG32F02A的中断。
这次讲讲ADC怎么用吧。另外,这次ADC我不建议使用DMA,因为这一版的M0的ADC是12位ADC,而DAT寄存器是32位,而且剩余的位并不是空白的,而是还塞了一些flag等信息在DAT寄存器里面。。所以就算你DMA把ADC抓出来,也会导致把不要的数据一起抓出来,最后你还是得自己去操作选择你的数据,所以DMA在这儿意义不大,不过据说这个问题到了下一版M0会修正,至于是啥时候,我就不知道了。
代码放在楼下。
烧进程序之后你看会发现,程序根本跑不动,这是为什么呢?你看数据手册:
板子上的VREF+引脚也是需要供电,而此处的供电会影响ADC转换式,此处的IVREF就是你接的供电,此处我接的是5V,因此公式我带入的是5。
OK,这样你的ADC就能使用啦。
- #include "MG32x02z_DRV.H"
- #include "MG32x02z_ADC_DRV.h"
- #include
- 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("hellon");
- 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("%lfn",y);
- }
- }
- }
|