完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
M451系列,ADC如何设置50HZ一次多通道采集一次?
/**************************************************************************//** * @file main.c * @version V3.00 * $Revision: 5 $ * $Date: 15/09/02 10:04a $ * @brief Show how to trigger ADC by timer. * @note * Copyright (C) 2013~2015 Nuvoton Technology Corp. All rights reserved. * ******************************************************************************/ #include "stdio.h" #include "M451Series.h" #define PLLCTL_SETTING CLK_PLLCTL_72MHz_HXT #define PLL_CLOCK 72000000 /*---------------------------------------------------------------------------------------------------------*/ /* Define global variables and constants */ /*---------------------------------------------------------------------------------------------------------*/ volatile uint32_t g_u32AdcIntFlag, g_u32COVNUMFlag = 0; /*---------------------------------------------------------------------------------------------------------*/ /* Define functions prototype */ /*---------------------------------------------------------------------------------------------------------*/ int32_t main(void); void EADC_FunctionTest(void); void SYS_Init(void) { /*---------------------------------------------------------------------------------------------------------*/ /* Init System Clock */ /*---------------------------------------------------------------------------------------------------------*/ /* Enable HIRC clock (Internal RC 22.1184MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk); /* Wait for HIRC clock ready */ CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); /* Select HCLK clock source as HIRC and and HCLK source divider as 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1)); /* Set PLL to Power-down mode and PLLSTB bit in CLK_STATUS register will be cleared by hardware.*/ CLK_DisablePLL(); /* Enable HXT clock (external XTAL 12MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk); /* Wait for HXT clock ready */ CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk); /* Set core clock as PLL_CLOCK from PLL */ CLK_SetCoreClock(PLL_CLOCK); /* Enable UART module clock */ CLK_EnableModuleClock(UART0_MODULE); /* Select UART module clock source as HXT and UART module clock divider as 1 */ CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HXT, CLK_CLKDIV0_UART(1)); /* Enable EADC module clock */ CLK_EnableModuleClock(EADC_MODULE); /* EADC clock source is 72MHz, set divider to 8, ADC clock is 72/8 MHz */ CLK_SetModuleClock(EADC_MODULE, 0, CLK_CLKDIV0_EADC(8)); /* Enable Timer 0 module clock */ CLK_EnableModuleClock(TMR0_MODULE); /* Select timer 0 module clock source as HXT */ CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0); /*---------------------------------------------------------------------------------------------------------*/ /* Init I/O Multi-function */ /*---------------------------------------------------------------------------------------------------------*/ /* Set PD multi-function pins for UART0 RXD and TXD */ SYS->GPD_MFPL &= ~(SYS_GPD_MFPL_PD0MFP_Msk | SYS_GPD_MFPL_PD1MFP_Msk); SYS->GPD_MFPL |= (SYS_GPD_MFPL_PD0MFP_UART0_RXD | SYS_GPD_MFPL_PD1MFP_UART0_TXD); /* Configure the GPB0 - GPB3 ADC analog input pins. */ SYS->GPB_MFPL &= ~(SYS_GPB_MFPL_PB0MFP_Msk | SYS_GPB_MFPL_PB1MFP_Msk | SYS_GPB_MFPL_PB2MFP_Msk | SYS_GPB_MFPL_PB3MFP_Msk); SYS->GPB_MFPL |= (SYS_GPB_MFPL_PB0MFP_EADC_CH0 | SYS_GPB_MFPL_PB1MFP_EADC_CH1 | SYS_GPB_MFPL_PB2MFP_EADC_CH2 | SYS_GPB_MFPL_PB3MFP_EADC_CH3); /* Disable the GPB0 - GPB3 digital input path to avoid the leakage current. */ GPIO_DISABLE_DIGITAL_PATH(PB, 0xF); } void UART0_Init() { /*---------------------------------------------------------------------------------------------------------*/ /* Init UART */ /*---------------------------------------------------------------------------------------------------------*/ /* Reset UART module */ SYS_ResetModule(UART0_RST); /* Configure UART0 and set UART0 baud rate */ UART_Open(UART0, 115200); } void TIMER0_Init() { /*---------------------------------------------------------------------------------------------------------*/ /* Init TIMER0 */ /*---------------------------------------------------------------------------------------------------------*/ /* Set timer0 periodic time-out period is 3us if timer clock is 12 MHz */ TIMER_SET_CMP_VALUE(TIMER0, 36);//TIMER0->CMP = 36; /* Start timer counter in periodic mode and enable timer interrupt trigger EADC */ TIMER0->CTL = TIMER_PERIODIC_MODE | TIMER_CTL_TRGEADC_Msk; } /*---------------------------------------------------------------------------------------------------------*/ /* EADC function test */ /*---------------------------------------------------------------------------------------------------------*/ void EADC_FunctionTest() { uint8_t u8Option; int32_t i32ConversionData[6] = {0}; printf("\n"); printf("+----------------------------------------------------------------------+\n"); printf("| Timer trigger mode test |\n"); printf("+----------------------------------------------------------------------+\n"); printf("\nIn this test, software will get 6 conversion result from the specified channel.\n"); while(1) { printf("Select input mode:\n"); printf(" [1] Single end input (channel 2 only)\n"); printf(" [2] Differential input (channel pair 1 only)\n"); printf(" Other keys: exit single mode test\n"); u8Option = getchar(); if(u8Option == '1') { /* Set the ADC internal sampling time, input mode as single-end and enable the A/D converter */ EADC_Open(EADC, EADC_CTL_DIFFEN_SINGLE_END); EADC_SetInternalSampleTime(EADC, 6); /* Configure the sample module 0 for analog input channel 2 and enable Timer0 trigger source */ EADC_ConfigSampleModule(EADC, 0, EADC_TIMER0_TRIGGER, 2); /* Clear the A/D ADINT0 interrupt flag for safe */ EADC_CLR_INT_FLAG(EADC, 0x1); /* Enable the sample module 0 interrupt. */ EADC_ENABLE_INT(EADC, 0x1);//Enable sample module A/D ADINT0 interrupt. EADC_ENABLE_SAMPLE_MODULE_INT(EADC, 0, 0x1);//Enable sample module 0 interrupt. NVIC_EnableIRQ(ADC00_IRQn); printf("Conversion result of channel 2:\n"); /* Reset the ADC indicator and enable Timer0 counter */ g_u32AdcIntFlag = 0; g_u32COVNUMFlag = 0; TIMER_Start(TIMER0); while(1) { /* Wait ADC interrupt (g_u32AdcIntFlag will be set at IRQ_Handler function) */ while(g_u32AdcIntFlag == 0); /* Reset the EADC interrupt indicator */ g_u32AdcIntFlag = 0; /* Get the conversion result of the sample module 0 */ i32ConversionData[g_u32COVNUMFlag - 1] = EADC_GET_CONV_DATA(EADC, 0); if(g_u32COVNUMFlag > 6) break; } /* Disable Timer0 counter */ TIMER_Stop(TIMER0); /* Disable the ADINT0 interrupt */ EADC_DISABLE_INT(EADC, 0x1); for(g_u32COVNUMFlag = 0; (g_u32COVNUMFlag) < 6; g_u32COVNUMFlag++) printf(" 0x%X (%d)\n", i32ConversionData[g_u32COVNUMFlag], i32ConversionData[g_u32COVNUMFlag]); } else if(u8Option == '2') { /* Set the ADC internal sampling time, input mode as differential and enable the A/D converter */ EADC_Open(EADC, EADC_CTL_DIFFEN_DIFFERENTIAL); EADC_SetInternalSampleTime(EADC, 6); /* Configure the sample module 0 for analog input channel 2 and enable Timer0 trigger source */ EADC_ConfigSampleModule(EADC, 0, EADC_TIMER0_TRIGGER, 2); /* Clear the A/D ADINT0 interrupt flag for safe */ EADC_CLR_INT_FLAG(EADC, 0x1); /* Enable the sample module 0 interrupt. */ EADC_ENABLE_INT(EADC, 0x1);//Enable sample module A/D ADINT0 interrupt. EADC_ENABLE_SAMPLE_MODULE_INT(EADC, 0, 0x1);//Enable sample module 0 interrupt. NVIC_EnableIRQ(ADC00_IRQn); printf("Conversion result of channel pair 1:\n"); /* Reset the EADC indicator and enable Timer0 counter */ g_u32AdcIntFlag = 0; g_u32COVNUMFlag = 0; TIMER_Start(TIMER0); while(1) { /* Wait ADC interrupt (g_u32AdcIntFlag will be set at IRQ_Handler function) */ while(g_u32AdcIntFlag == 0); /* Reset the ADC interrupt indicator */ g_u32AdcIntFlag = 0; /* Get the conversion result of the sample module 0 */ i32ConversionData[g_u32COVNUMFlag - 1] = EADC_GET_CONV_DATA(EADC, 0); if(g_u32COVNUMFlag > 6) break; } /* Disable Timer0 counter */ TIMER_Stop(TIMER0); /* Disable the ADINT0 interrupt */ EADC_DISABLE_INT(EADC, 0x1); for(g_u32COVNUMFlag = 0; (g_u32COVNUMFlag) < 6; g_u32COVNUMFlag++) printf(" 0x%X (%d)\n", i32ConversionData[g_u32COVNUMFlag], i32ConversionData[g_u32COVNUMFlag]); } else return ; } } /*---------------------------------------------------------------------------------------------------------*/ /* EADC interrupt handler */ /*---------------------------------------------------------------------------------------------------------*/ void ADC00_IRQHandler(void) { g_u32AdcIntFlag = 1; g_u32COVNUMFlag++; EADC_CLR_INT_FLAG(EADC, 0x1);/* Clear the A/D ADINT0 interrupt flag */ } /*---------------------------------------------------------------------------------------------------------*/ /* Main Function */ /*---------------------------------------------------------------------------------------------------------*/ int32_t main(void) { /* Unlock protected registers */ SYS_UnlockReg(); /* Init System, IP clock and multi-function I/O */ SYS_Init(); /* Lock protected registers */ SYS_LockReg(); /* Init UART0 for printf */ UART0_Init(); /* Init TIMER0 for EADC */ TIMER0_Init(); /*---------------------------------------------------------------------------------------------------------*/ /* SAMPLE CODE */ /*---------------------------------------------------------------------------------------------------------*/ printf("\nSystem clock rate: %d Hz", SystemCoreClock); /* EADC function test */ EADC_FunctionTest(); /* Reset Timer0 module */ SYS_ResetModule(TMR0_RST); /* Reset EADC module */ SYS_ResetModule(EADC_RST); /* Disable Timer0 IP clock */ CLK_DisableModuleClock(TMR0_MODULE); /* Disable EADC IP clock */ CLK_DisableModuleClock(EADC_MODULE); /* Disable External Interrupt */ NVIC_DisableIRQ(ADC00_IRQn); printf("Exit EADC sample code\n"); while(1); } |
|
相关推荐
1个回答
|
|
首先,需要打开 ADC 转换周期控制模块(ADCCNT),将 ADC 转换的时间间隔设置为所需的采样率,比如本例中的 50Hz,可以计算出时间间隔为:
转换周期(秒)= 1 / 50 = 0.02 秒 转换周期(时钟周期)= 转换周期(秒)× ADC 时钟频率 其中,ADC时钟频率为系统时钟频率的 1/2,计算可得: 转换周期(时钟周期)= 0.02 × 系统时钟频率 / 2 另外,还需要配置 ADC 多通道扫描控制模块(ADCMPSCTL)以及 ADC 中断控制模块(ADCRISCTL)。 以下是示例代码: // 打开 ADCCNT 控制模块 ADCCNT |= ADCCNT_ADCEN_Msk; // 设置 ADC 时钟频率 CLK_SetModuleClock(ADC_MODULE, CLK_CLKSEL2_ADCSEL_HIRC, 0); CLK_EnableModuleClock(ADC_MODULE); // 设置转换间隔为 0.02 秒(假设系统时钟频率为 48MHz) ADCCNT &= ~ADCCNT_ADCTMOD_Msk; ADCCNT |= (48000000 / 2 * 0.02); // 配置 ADC 多通道扫描控制模块,假设需要采集的通道为 CH0、CH1、CH2 ADCMPSCTL &= ~ADCMPSCTL_CHSEL_Msk; ADCMPSCTL |= 0x000003; // 配置 ADC 中断控制模块,使能 ADC 转换完成中断 ADCRISCTL |= ADCRISCTL_ADCIF_Msk; ADCRISCTL |= ADCRISCTL_ADCIEN_Msk; |
|
|
|
只有小组成员才能发言,加入小组>>
759 浏览 0 评论
1142 浏览 1 评论
2522 浏览 5 评论
2854 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2701 浏览 6 评论
keil5中manage run-time environment怎么是灰色,不可以操作吗?
1033浏览 3评论
183浏览 2评论
450浏览 2评论
362浏览 2评论
M0518 PWM的电压输出只有2V左右,没有3.3V是怎么回事?
447浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-13 20:50 , Processed in 1.116256 second(s), Total 50, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号