[DemoCode下载] 新唐MINI51 ADC模块初始化设置及应用实例

[复制链接]
 楼主| 天灵灵地灵灵 发表于 2016-7-31 22:37 | 显示全部楼层 |阅读模式
  1. #include "Register_Bit.h"   //包含位定义文件   


  2. //ADC通道号定义  
  3. #define     ADC_Chanel0         (uint8_t)CHEN0  
  4. #define     ADC_Chanel1         (uint8_t)CHEN1  
  5. #define     ADC_Chanel2         (uint8_t)CHEN2  
  6. #define     ADC_Chanel3         (uint8_t)CHEN3  
  7. #define     ADC_Chanel4         (uint8_t)CHEN4  
  8. #define     ADC_Chanel5         (uint8_t)CHEN5  
  9. #define     ADC_Chanel6         (uint8_t)CHEN6  
  10. #define     ADC_Chanel7         (uint8_t)CHEN7  

  11. #define     ADC_IEN_ENB         ADCR |= ADIE; NVIC_ISER |= ADC_INT   
  12. #define     ADC_IEN_DIS         ADCR &= ~ADIE; NVIC_ISER &= ~ADC_INT   


  13. //*************************************  
  14. // 函数名称:Init_Adc  
  15. // 函数功能:adc初始化  
  16. // 入口参数:无  
  17. // 出口参数:无  
  18. //***************************************/  
  19. void Init_Adc(void)  
  20. {  
  21. //ADC输入时钟除频    器分频 12M/2 = 6M  ADC最大频率为6M  
  22.     uint8_t Tmp = 2 ;  

  23.     /* Reset ADC IP */      
  24.     IPRSTC2 |= ADC_RST;  
  25.     IPRSTC2 &= ~ADC_RST;  

  26.     /* ADC engine clock enable */         
  27.     APBCLK |= ADC_CLKEN;  
  28.     CLKSEL1 = CLKSEL1 & (~ADC_CLK) | ADC_12M_32K;  

  29.     /* Set ADC divisor */  
  30. //    CLKDIV |= 0x00050000;   
  31.     Tmp = Tmp - 1 ;  
  32.     CLKDIV = (CLKDIV & (~(255<<16))) | (Tmp<<16) ;   

  33.     /* ADC enable */  
  34.     ADCR |= ADEN;  

  35.     /* Set the ADC channel */  
  36. //    ADCHER |= CHEN0;  

  37.     /* Clear the A/D interrupt flags for safe */  
  38.     ADSR |= ADF;     //写1清除AD转换结束标志  

  39.     ADC_IEN_DIS ; //AD中断不使能  
  40. //  ADC_IEN_ENB ;   
  41. }  
  42. //*************************************  
  43. // 函数名称:ADC_IoInit  
  44. // 函数功能:ADC IO 初始化  
  45. // 入口参数:无  
  46. // 出口参数:无  
  47. //***************************************/  
  48. void ADC_AN0IoInit(void)  
  49. {  
  50.     /* Configure P5.3 as analog input pin */  
  51.     P5_MFP = (P5_MFP & (~P53_MFSEL)) | P53_AIN0;  
  52.     /* Disable P5.3 digital input path */  
  53.     P5_OFFD |= OFFD3;  
  54.     /* Configure P5.3 as input mode */  
  55.     P5_PMD = P5_PMD & (~Px3_PMD) | Px3_IN;   
  56. }  
  57. //=====通道1 IO ============  
  58. void ADC_AN1IoInit(void)  
  59. {  
  60.     /* Configure P1.0 as analog input pin */  
  61.     P1_MFP = (P1_MFP & (~P10_MFSEL)) | P10_AIN1;  
  62.     /* Disable P1.0 digital input path */  
  63.     P1_OFFD |= OFFD0;  
  64.     /* Configure P1.0 as input mode */  
  65.     P1_PMD = P1_PMD & (~Px0_PMD) | Px0_IN;   
  66. }  
  67. //*************************************  
  68. // 函数名称:ADC_Switch  
  69. // 函数功能:ADC 通道转换使能  
  70. // 入口参数:无  
  71. // 出口参数:无  
  72. //***************************************/  
  73. uint16_t ADC_Switch(uint8_t Chanel)  
  74. {  
  75.     uint16_t   u16Tmp = 0 ;  

  76.     ADCR &= ~ADST;    //清启动位  
  77.     /* Set the ADC channel */  
  78.     ADCHER = (ADCHER & (~(255))) | Chanel ;  
  79.     /* StartADC */  
  80.     ADCR |= ADST;   
  81. //      P00_ON ;  
  82.     while((ADSR & ADF)==0) ; //等待AD转换结束   
  83. //      P00_OFF ;  
  84.     ADSR |= ADF ;   //写1清除AD转换结束标志  

  85.     u16Tmp = (uint16_t)(ADDR0 & 0x000003FF);      

  86.     return  u16Tmp ;  
  87. }  



  88. //----实例应用-----  

  89.     Init_Adc() ; //ADC初始化设置  
  90.     ADC_AN0IoInit() ; //通道0 IO设置  
  91.     ADC_AN1IoInit() ; //通道1 IO设置  

  92. //---主程序-----  
  93. void main(void)  
  94. {  
  95.     while(1)  
  96.     {  
  97.         while(!F_10MS); //10MS跑一次主程序  
  98.         F_10MS = 0 ;  

  99.         g_u16Tmp = ADC_Switch(ADC_Chanel0) ; //转换通道0      

  100.     }  

  101. }  


玛尼玛尼哄 发表于 2016-7-31 23:00 | 显示全部楼层
好多代码都用在初始化上了,如果高度封装就爽了。
历经沧桑的老人 发表于 2016-8-1 10:46 | 显示全部楼层
这么复杂啊。。。。。。
 楼主| 天灵灵地灵灵 发表于 2016-8-1 20:07 | 显示全部楼层
历经沧桑的老人 发表于 2016-8-1 10:46
这么复杂啊。。。。。。

ARM本来就是很复杂了,复杂在哪儿?复杂在配置和初始化上,因为功能多,所以寄存器多,要用于选择不同的功能,这就是为何初始化时候那么复杂,多嘛,所以要用很多寄存器来选择不同的功能。
zhuotuzi 发表于 2016-8-3 21:52 | 显示全部楼层
代码看着简单的时候反而不好理解了。
玛尼玛尼哄 发表于 2016-8-5 22:31 | 显示全部楼层
一共提供了8个通道的采集。
 楼主| 天灵灵地灵灵 发表于 2016-8-7 08:59 | 显示全部楼层
void ADC_AN1IoInit(void)  
{  
    /* Configure P1.0 as analog input pin */  
    P1_MFP = (P1_MFP & (~P10_MFSEL)) | P10_AIN1;  
    /* Disable P1.0 digital input path */  
    P1_OFFD |= OFFD0;  
    /* Configure P1.0 as input mode */  
    P1_PMD = P1_PMD & (~Px0_PMD) | Px0_IN;   
}  
捉虫天师 发表于 2016-8-7 11:51 | 显示全部楼层
ARM的外设多,复杂在配置上,配置好了,就OK了
yiyigirl2014 发表于 2016-8-7 13:54 | 显示全部楼层
  1. /****************************************************************************
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V2.0
  4. * $Revision: 2 $
  5. * $Date: 14/12/25 10:24a $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    Perform A/D Conversion with ADC single mode.
  7. * @note
  8. * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
  9. *
  10. ******************************************************************************/
  11. #include <stdio.h>
  12. #include "M0518.h"


  13. #define PLL_CLOCK       50000000

  14. /*---------------------------------------------------------------------------------------------------------*/
  15. /* Define Function Prototypes                                                                              */
  16. /*---------------------------------------------------------------------------------------------------------*/
  17. void SYS_Init(void);
  18. void UART0_Init(void);
  19. void AdcSingleModeTest(void);


  20. /*---------------------------------------------------------------------------------------------------------*/
  21. /* Define global variables and constants                                                                   */
  22. /*---------------------------------------------------------------------------------------------------------*/
  23. volatile uint32_t g_u32AdcIntFlag;


  24. void SYS_Init(void)
  25. {
  26.     /*---------------------------------------------------------------------------------------------------------*/
  27.     /* Init System Clock                                                                                       */
  28.     /*---------------------------------------------------------------------------------------------------------*/

  29.     /* Enable Internal RC 22.1184MHz clock */
  30.     CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

  31.     /* Waiting for Internal RC clock ready */
  32.     CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

  33.     /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
  34.     CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

  35.     /* Enable external XTAL 12MHz clock */
  36.     CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

  37.     /* Waiting for external XTAL clock ready */
  38.     CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

  39.     /* Set core clock as PLL_CLOCK from PLL */
  40.     CLK_SetCoreClock(PLL_CLOCK);

  41.     /* Enable UART module clock */
  42.     CLK_EnableModuleClock(UART0_MODULE);

  43.     /* Enable ADC module clock */
  44.     CLK_EnableModuleClock(ADC_MODULE);

  45.     /* Select UART module clock source */
  46.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_PLL, CLK_CLKDIV_UART(1));

  47.     /* ADC clock source is 22.1184MHz, set divider to 7, ADC clock is 22.1184/7 MHz */
  48.     CLK_SetModuleClock(ADC_MODULE, CLK_CLKSEL1_ADC_S_HIRC, CLK_CLKDIV_ADC(7));

  49.     /*---------------------------------------------------------------------------------------------------------*/
  50.     /* Init I/O Multi-function                                                                                 */
  51.     /*---------------------------------------------------------------------------------------------------------*/

  52.     /* Set GPB multi-function pins for UART0 RXD and TXD */
  53.     SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk);
  54.     SYS->GPB_MFP |= SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;

  55.     /* Disable the GPA0 - GPA3 digital input path to avoid the leakage current. */
  56.     GPIO_DISABLE_DIGITAL_PATH(PA, 0xF);

  57.     /* Configure the GPA0 - GPA3 ADC analog input pins */
  58.     SYS->GPA_MFP &= ~(SYS_GPA_MFP_PA0_Msk | SYS_GPA_MFP_PA1_Msk | SYS_GPA_MFP_PA2_Msk | SYS_GPA_MFP_PA3_Msk) ;
  59.     SYS->GPA_MFP |= SYS_GPA_MFP_PA0_ADC0 | SYS_GPA_MFP_PA1_ADC1 | SYS_GPA_MFP_PA2_ADC2 | SYS_GPA_MFP_PA3_ADC3 ;


  60. }

  61. /*---------------------------------------------------------------------------------------------------------*/
  62. /* Init UART                                                                                               */
  63. /*---------------------------------------------------------------------------------------------------------*/
  64. void UART0_Init()
  65. {
  66.     /* Reset IP */
  67.     SYS_ResetModule(UART0_RST);

  68.     /* Configure UART0 and set UART0 Baudrate */
  69.     UART_Open(UART0, 115200);
  70. }

  71. /*---------------------------------------------------------------------------------------------------------*/
  72. /* Function: AdcSingleModeTest                                                                             */
  73. /*                                                                                                         */
  74. /* Parameters:                                                                                             */
  75. /*   None.                                                                                                 */
  76. /*                                                                                                         */
  77. /* Returns:                                                                                                */
  78. /*   None.                                                                                                 */
  79. /*                                                                                                         */
  80. /* Description:                                                                                            */
  81. /*   ADC single mode test.                                                                                 */
  82. /*---------------------------------------------------------------------------------------------------------*/
  83. void AdcSingleModeTest()
  84. {
  85.     uint8_t  u8Option;
  86.     int32_t  i32ConversionData;

  87.     printf("\n");
  88.     printf("+----------------------------------------------------------------------+\n");
  89.     printf("|                      ADC single mode sample code                     |\n");
  90.     printf("+----------------------------------------------------------------------+\n");

  91.     while(1)
  92.     {
  93.         printf("Select input mode:\n");
  94.         printf("  [1] Single end input (channel 2 only)\n");
  95.         printf("  [2] Differential input (channel pair 1 only)\n");
  96.         printf("  Other keys: exit single mode test\n");
  97.         u8Option = getchar();
  98.         if(u8Option == '1')
  99.         {

  100.             /* Set the ADC operation mode as single, input mode as single-end and enable the analog input channel 2 */
  101.             ADC_Open(ADC, ADC_ADCR_DIFFEN_SINGLE_END, ADC_ADCR_ADMD_SINGLE, 0x1 << 2);

  102.             /* Power on ADC module */
  103.             ADC_POWER_ON(ADC);

  104.             /* Clear the A/D interrupt flag for safe */
  105.             ADC_CLR_INT_FLAG(ADC, ADC_ADF_INT);

  106.             /* Enable the ADC interrupt */
  107.             ADC_EnableInt(ADC, ADC_ADF_INT);
  108.             NVIC_EnableIRQ(ADC_IRQn);

  109.             /* Reset the ADC interrupt indicator and Start A/D conversion */
  110.             g_u32AdcIntFlag = 0;

  111.             ADC_START_CONV(ADC);

  112.             /* Wait ADC interrupt (g_u32AdcIntFlag will be set at IRQ_Handler function)*/
  113.             while(g_u32AdcIntFlag == 0);

  114.             /* Disable the ADC interrupt */
  115.             ADC_DisableInt(ADC, ADC_ADF_INT);

  116.             /* Get the conversion result of the ADC channel 2 */
  117.             i32ConversionData = ADC_GET_CONVERSION_DATA(ADC, 2);
  118.             printf("Conversion result of channel 2: 0x%X (%d)\n\n", i32ConversionData, i32ConversionData);
  119.         }
  120.         else if(u8Option == '2')
  121.         {

  122.             /* Set the ADC operation mode as single, input mode as differential and
  123.                enable analog input channel 2 for differential input channel pair 1 */
  124.             ADC_Open(ADC, ADC_ADCR_DIFFEN_DIFFERENTIAL, ADC_ADCR_ADMD_SINGLE, 0x1 << 2);

  125.             /* Power on ADC module */
  126.             ADC_POWER_ON(ADC);

  127.             /* Clear the A/D interrupt flag for safe */
  128.             ADC_CLR_INT_FLAG(ADC, ADC_ADF_INT);

  129.             /* Enable the ADC interrupt */
  130.             ADC_EnableInt(ADC, ADC_ADF_INT);
  131.             NVIC_EnableIRQ(ADC_IRQn);

  132.             /* Reset the ADC interrupt indicator and Start A/D conversion */
  133.             g_u32AdcIntFlag = 0;
  134.             ADC_START_CONV(ADC);

  135.             /* Wait ADC interrupt (g_u32AdcIntFlag will be set at IRQ_Handler function)*/
  136.             while(g_u32AdcIntFlag == 0);

  137.             /* Disable the ADC interrupt */
  138.             ADC_DisableInt(ADC, ADC_ADF_INT);

  139.             /* Get the conversion result of the specified ADC channel */
  140.             i32ConversionData = ADC_GET_CONVERSION_DATA(ADC, 2);
  141.             printf("Conversion result of channel pair 1: 0x%X (%d)\n\n", i32ConversionData, i32ConversionData);
  142.         }
  143.         else
  144.             return ;

  145.     }
  146. }



  147. /*---------------------------------------------------------------------------------------------------------*/
  148. /* ADC interrupt handler                                                                                   */
  149. /*---------------------------------------------------------------------------------------------------------*/
  150. void ADC_IRQHandler(void)
  151. {
  152.     g_u32AdcIntFlag = 1;
  153.     ADC_CLR_INT_FLAG(ADC, ADC_ADF_INT); /* clear the A/D conversion flag */
  154. }

  155. /*---------------------------------------------------------------------------------------------------------*/
  156. /* MAIN function                                                                                           */
  157. /*---------------------------------------------------------------------------------------------------------*/

  158. int main(void)
  159. {

  160.     /* Unlock protected registers */
  161.     SYS_UnlockReg();

  162.     /* Init System, IP clock and multi-function I/O */
  163.     SYS_Init();

  164.     /* Lock protected registers */
  165.     SYS_LockReg();

  166.     /* Init UART0 for printf */
  167.     UART0_Init();

  168.     /*---------------------------------------------------------------------------------------------------------*/
  169.     /* SAMPLE CODE                                                                                             */
  170.     /*---------------------------------------------------------------------------------------------------------*/

  171.     printf("\nSystem clock rate: %d Hz", SystemCoreClock);

  172.     /* Single Mode test */
  173.     AdcSingleModeTest();

  174.     /* Disable ADC module */
  175.     ADC_Close(ADC);

  176.     /* Disable ADC IP clock */
  177.     CLK_DisableModuleClock(ADC_MODULE);

  178.     /* Disable External Interrupt */
  179.     NVIC_DisableIRQ(ADC_IRQn);

  180.     printf("\nExit ADC sample code\n");

  181.     while(1);

  182. }




玛尼玛尼哄 发表于 2016-8-7 15:05 | 显示全部楼层
模拟输入电压范围: 0~0~AVDD(最大5.0V).
y 12位分辨率和10位精确度保证.
y 多达 8 路单端模拟输入通道或4路差分模拟输入通道.
y 最大 ADC 时钟频率 16MHz.
y 高达600k SPS 转换速率.
y 四种操作模式
- 单次转换模式:A/D转换在指定通道完成一次转换.
- 单周期扫描模式:A/D 转换在所有指定通道完成一个周期(从低序号通道到高序号通道)转换.
- 连续扫描模式: A/D 转换器连续执行单周期扫描模式直到软件停止A/D转换.
- 突发模式: A/D 转换 采样和转换在指定单个通道进行,并将结果顺序地存入FIFO.
y A/D转换开始条件
- 软件向ADST 位写1
- 外部引脚STADC触发
y 每通道转换结果存储在相应数据寄存器内,并带有有效或超出限度的标志.
y 转换结果可和指定的值相比较, 当转换值和设定值相匹配时,用户可设定是否产生中断请求.
y 通道 7 支持 2 输入源:外部模拟电压, 内部带隙电压.
y 支持自身校正功能以减少转换的误差
heisexingqisi 发表于 2016-8-7 23:11 | 显示全部楼层
作为ARM核心的单片机,复杂度不言而喻,这就看个人能力i
quray1985 发表于 2016-8-8 16:37 | 显示全部楼层
这个adc内部的参考电压有多大?
gejigeji521 发表于 2016-8-8 23:16 | 显示全部楼层
printf("\nSystem clock rate: %d Hz", SystemCoreClock);
您需要登录后才可以回帖 登录 | 注册

本版积分规则

182

主题

3469

帖子

13

粉丝
快速回复 在线客服 返回列表 返回顶部

182

主题

3469

帖子

13

粉丝
快速回复 在线客服 返回列表 返回顶部