[技术问答] N79E715的ADC问题

[复制链接]
1460|14
 楼主| henxiano 发表于 2019-8-16 17:17 | 显示全部楼层 |阅读模式
本帖最后由 henxiano 于 2019-8-17 16:35 编辑

这个IC 的ADC只能一次使用一个吗,每次配置第二个ADC之后读取会出错。
  1. Trigger_ADC_Convertion();
  2. Set_ADC_Input_Mode(E_CHANNEL0);                     // Set ADC0 (P0.1 default) is input only mode
  3. ADC_Channel_Sel(E_CHANNEL0);                        // ADC Channel Select (P0.1 default)
  4. u16ADCL = ADCCON0;
  5. u16ADCL = u16ADCL >> 6;                         // ADC[1:0]
  6. u16ADC = ADCH;
  7. u16ADC = (u16ADC << 2 ) + u16ADCL;              // ADC[9:2] + ADC[1:0]        

  8. Set_ADC_Input_Mode(E_CHANNEL4);                     // Set ADC4 (P0.5 default) is input only mode
  9. ADC_Channel_Sel(E_CHANNEL4);                        // ADC Channel Select (P0.5 default)                                                                          
  10. u16ADCL_4 = ADCCON0;
  11. u16ADCL_4 = u16ADCL_4 >> 6;                         // ADC[1:0]
  12. u16ADCH_4 = ADCH;
  13. u16ADC_4 = (u16ADCH_4 << 2) + u16ADCL_4;              // ADC[9:2] + ADC[1:0]         

  14. if(u16ADC<24){
  15.         P14 = 1;
  16. }
  17. else if(u16ADC>24){
  18.         P14 = 0;
  19. }

这个代码,如果去掉
  1. Set_ADC_Input_Mode(E_CHANNEL4);                     // Set ADC4 (P0.5 default) is input only mode
  2. ADC_Channel_Sel(E_CHANNEL4);                        // ADC Channel Select (P0.5 default)                                                                          
  3. u16ADCL_4 = ADCCON0;
  4. u16ADCL_4 = u16ADCL_4 >> 6;                         // ADC[1:0]
  5. u16ADCH_4 = ADCH;
  6. u16ADC_4 = (u16ADCH_4 << 2) + u16ADCL_4;              // ADC[9:2] + ADC[1:0]

就可以正常,否则P14一直都是1
598330983 发表于 2019-8-16 23:18 | 显示全部楼层
是两个同时用?当然不能这么配置,要逻辑或一下,一次性配置。
 楼主| henxiano 发表于 2019-8-17 16:34 | 显示全部楼层
598330983 发表于 2019-8-16 23:18
是两个同时用?当然不能这么配置,要逻辑或一下,一次性配置。

但是N79E715是通过AADR2,AADR1,AADR0这三个寄存器的状态来选择ADC通道的,能同时配置吗
小明的同学 发表于 2019-8-17 22:59 | 显示全部楼层
henxiano 发表于 2019-8-17 16:34
但是N79E715是通过AADR2,AADR1,AADR0这三个寄存器的状态来选择ADC通道的,能同时配置吗 ...

如果是这样,那就是只有一个ADC转化器,你这么配置就更不对了,你要配置好一个,就读取一个的结果输出,然后配置第二个读取第二个。可以把每一路的设置和读取放到一个函数里,直接调用。
小明的同学 发表于 2019-8-17 23:01 | 显示全部楼层
没用过这个,仅仅猜测,我用过003的,N76E003应该跟这个差不多 吧,例子里已经说明了,启动一个ADC的通道时候就只读取这一个,读取完了,你想读取另外一个,再关闭这个,启动那个。
  1. void main (void)
  2. {
  3.                 InitialUART0_Timer1(115200);

  4.                 Enable_ADC_AIN3;                                                // Enable AIN0 P1.7 as ADC input, Find in "Function_define.h" - "ADC INIT"
  5.                 while(1)
  6.     {
  7.                         clr_ADCF;
  8.                         set_ADCS;                                                                        // ADC start trig signal
  9.       while(ADCF == 0);
  10.                         printf ("\n Value = 0x%bx",ADCRH);
  11.                         printf ("\n Value = 0x%bx",ADCRL);
  12.                         Timer0_Delay1ms(100);
  13.     }
  14. }

小明的同学 发表于 2019-8-18 00:10 | 显示全部楼层
  1. /*---------------------------------------------------------------------------------------------------------*/
  2. /*                                                                                                         */
  3. /* Copyright(c) 2015 Nuvoton Technology Corp. All rights reserved.                                         */
  4. /*                                                                                                         */
  5. /*---------------------------------------------------------------------------------------------------------*/

  6. //***********************************************************************************************************
  7. //  Nuvoton Technology Corp.
  8. //  E-mail: MicroC-8bit@nuvoton.com
  9. //***********************************************************************************************************
  10. //  Application: ADC Function
  11. //  ADC Channel 0(P0.1 default) as ADC input
  12. //
  13. //  Output : UART show ADC output result on hyper-terminal
  14. //***********************************************************************************************************

  15. //------------------------- <<< Use Configuration Wizard in Context Menu >>> --------------------------------
  16. //     <o0.6> UART pin Select
  17. //          <0=> Select P1.0, P1.1 as UART pin(default)
  18. //          <1=> Select P2.6, P2.7 as UART pin(28 pin only)
  19. //-------------------------------- <<< end of configuration section >>> -------------------------------------

  20. #define Uart_Port_Sel   0x00

  21. #include "N79E715.h"
  22. #include "Typedef.h"
  23. #include "Define.h"
  24. #include "Common.h"
  25. #include "Delay.h"
  26. #include "ADC.h"
  27. #include "Version.h"
  28. #include <intrins.h>
  29. #include <stdio.h>
  30. #include <string.h>

  31. //-----------------------------------------------------------------------------------------------------------
  32. void Enable_ADC_Interrupt(void)
  33. {
  34.     EADC = 1;
  35.     EA = 1;
  36. }
  37. //-----------------------------------------------------------------------------------------------------------
  38. void ADC_Channel_Sel(E_ADCCNL_SEL channel)
  39. {
  40.     switch (channel)
  41.     {
  42.         case E_CHANNEL0:                                // P0.1 (default)
  43.             clr_AADR2;
  44.             clr_AADR1;
  45.             clr_AADR0;
  46.             break;
  47.         case E_CHANNEL1:                                // P0.2
  48.             clr_AADR2;
  49.             clr_AADR1;
  50.             set_AADR0;
  51.             break;
  52.         case E_CHANNEL2:                                // P0.3
  53.             clr_AADR2;
  54.             set_AADR1;
  55.             clr_AADR0;
  56.             break;
  57.         case E_CHANNEL3:                                // P0.4
  58.             clr_AADR2;
  59.             set_AADR1;
  60.             set_AADR0;
  61.             break;
  62.         case E_CHANNEL4:                                // P0.5
  63.             set_AADR2;
  64.             clr_AADR1;
  65.             clr_AADR0;
  66.             break;
  67.         case E_CHANNEL5:                                // P0.6
  68.             set_AADR2;
  69.             clr_AADR1;
  70.             set_AADR0;
  71.             break;
  72.         case E_CHANNEL6:                                // P0.7
  73.             set_AADR2;
  74.             set_AADR1;
  75.             clr_AADR0;
  76.             break;
  77.         case E_CHANNEL7:                                // P2.6
  78.             set_AADR2;
  79.             set_AADR1;
  80.             set_AADR0;
  81.             break;
  82.     }
  83. }
  84. //-----------------------------------------------------------------------------------------------------------
  85. void Set_ADC_Input_Mode(E_ADCCNL_SEL channel)
  86. {
  87.     switch (channel)
  88.     {
  89.         case E_CHANNEL0:                                // ADC0(P0.1) is input-only mode
  90.             P0DIDS |= SET_BIT1;                         // Disable digital function for P0.1
  91.             P0M1 |= SET_BIT1;
  92.             P0M2 &= CLR_BIT1;
  93.             break;
  94.         case E_CHANNEL1:                                // ADC1(P0.2) is input-only mode
  95.             P0DIDS |= SET_BIT2;                         // Disable digital function for P0.2
  96.             P0M1 |= SET_BIT2;
  97.             P0M2 &= CLR_BIT2;
  98.             break;
  99.         case E_CHANNEL2:                                // ADC2(P0.3) is input-only mode
  100.             P0DIDS |= SET_BIT3;                         // Disable digital function for P0.3
  101.             P0M1 |= SET_BIT3;
  102.             P0M2 &= CLR_BIT3;
  103.             break;
  104.         case E_CHANNEL3:                                // ADC3(P0.4) is input-only mode
  105.             P0DIDS |= SET_BIT4;                         // Disable digital function for P0.4
  106.             P0M1 |= SET_BIT4;
  107.             P0M2 &= CLR_BIT4;
  108.             break;
  109.         case E_CHANNEL4:                                // ADC4(P0.5) is input-only mode
  110.             P0DIDS |= SET_BIT5;                         // Disable digital function for P0.5
  111.             P0M1 |= SET_BIT5;
  112.             P0M2 &= CLR_BIT5;
  113.             break;
  114.         case E_CHANNEL5:                                // ADC5(P0.6) is input-only mode
  115.             P0DIDS |= SET_BIT6;                         // Disable digital function for P0.6
  116.             P0M1 |= SET_BIT6;
  117.             P0M2 &= CLR_BIT6;
  118.             break;
  119.         case E_CHANNEL6:                                // ADC6(P0.7) is input-only mode
  120.             P0DIDS |= SET_BIT7;                         // Disable digital function for P0.7
  121.             P0M1 |= SET_BIT7;
  122.             P0M2 &= CLR_BIT7;
  123.             break;
  124.         case E_CHANNEL7:                                // ADC7(P2.6) is input-only mode(28 pin only)
  125.             AUXR1 |= SET_BIT3;                          // Disable digital function for P2.6
  126.             P2M1 |= SET_BIT6;
  127.             P2M2 &= CLR_BIT6;
  128.             break;
  129.     }
  130. }
  131. //-----------------------------------------------------------------------------------------------------------
  132. void Trigger_ADC_Convertion(void)
  133. {
  134.     clr_ADCI;                                           // Clear ADC flag (ADCI=0)
  135.     set_ADCS;                                           // ADC run (ADCS = 1)
  136.     PCON |= SET_BIT0;                                   // Enter idle mode
  137. }
  138. //-----------------------------------------------------------------------------------------------------------
  139. void ADC_Init(void)
  140. {
  141.     Set_ADC_Input_Mode(E_CHANNEL0);                     // Set ADC0 (P0.1 default) is input only mode

  142.     ADC_Channel_Sel(E_CHANNEL0);                        // ADC Channel Select (P0.1 default)

  143.     Enable_ADC_Interrupt();

  144.     set_ADCEN;                                          // Enable ADC Function
  145. }
  146. //-----------------------------------------------------------------------------------------------------------
  147. void main(void)
  148. {
  149.     UINT16 u16ADCL;
  150.     UINT16 u16ADC;

  151.     AUXR1 |= Uart_Port_Sel;                             // Select P10/P11 as UART pin(default)
  152.     InitialUART0_Timer1(9600);                          // 9600 Baud Rate [url=home.php?mod=space&uid=72445]@[/url] 11.0592MHz
  153.     Show_Version_Number_To_PC();
  154.     printf ("\n*===================================================================");
  155.     printf ("\n*  Name: N79E715 Series ADC Sample Code.");
  156.     printf ("\n*===================================================================");

  157.     ADC_Init();
  158.     while(1)
  159.     {
  160.         Trigger_ADC_Convertion();

  161.         u16ADCL = ADCCON0;
  162.         u16ADCL = u16ADCL >> 6;                         // ADC[1:0]

  163.         u16ADC = ADCH;
  164.         u16ADC = (u16ADC << 2 ) + u16ADCL;              // ADC[9:2] + ADC[1:0]

  165.         printf ("\nADC Value = %d",u16ADC);             // Show 10 bit ADC

  166.         Delay1ms(500);
  167.     }
  168. }
  169. //-----------------------------------------------------------------------------------------------------------
  170. void ADC_ISR(void) interrupt 11                         // Vector @  0x5B
  171. {
  172.     clr_ADCI;                                           // Clear ADC flag (ADCI = 0)
  173.     clr_ADCS;                                           // ADC stop (ADCS = 0)
  174. }
  175. //-----------------------------------------------------------------------------------------------------------






小明的同学 发表于 2019-8-18 00:11 | 显示全部楼层
上面的例子是官方提供的, 你仔细看,这个例子表名了所有的通道共用了一个ADC转化器,你使用哪个时候,ADC读取的就是哪个通道的。直接你用这个例子提供的那些函数做就行了。
小明的同学 发表于 2019-8-18 00:14 | 显示全部楼层
你在一次转化结束后要进行清零。
    clr_ADCI;                                           // Clear ADC flag (ADCI = 0)
    clr_ADCS;                                           // ADC stop (ADCS = 0)
这个,你注意了没,你之前调用的        Trigger_ADC_Convertion();
实际上就是坐了这个工作,你可以在第二个通道初始化后调用这个
小明的同学 发表于 2019-8-18 00:15 | 显示全部楼层
这样你第二个启动的通道就开始转化了。
yiyigirl2014 发表于 2019-8-18 11:43 | 显示全部楼层
楼主要仔细看手册,了解这个ADC的结构。
寒夜钟秋 发表于 2019-8-19 00:48 | 显示全部楼层
 楼主| henxiano 发表于 2019-8-21 12:02 | 显示全部楼层
小明的同学 发表于 2019-8-18 00:14
你在一次转化结束后要进行清零。
    clr_ADCI;                                           // Clear ADC  ...

  1.                 Trigger_ADC_Convertion();
  2.                 Set_ADC_Input_Mode(E_CHANNEL0);                     // Set ADC0 (P0.1 default) is input only mode
  3.                 ADC_Channel_Sel(E_CHANNEL0);                        // ADC Channel Select (P0.1 default)
  4.                 u16ADCL = ADCCON0;
  5.                 u16ADCL = u16ADCL >> 6;                         // ADC[1:0]
  6.                 u16ADC = ADCH;
  7.                 u16ADC = (u16ADC << 2 ) + u16ADCL;              // ADC[9:2] + ADC[1:0]       
  8.                                                                
  9.                 Trigger_ADC_Convertion();       
  10.                 Set_ADC_Input_Mode(E_CHANNEL4);        
  11.                 ADC_Channel_Sel(E_CHANNEL4);           
  12.                 u16ADCL_4 = ADCCON0;
  13.                 u16ADCL_4 = u16ADCL_4 >> 6;                        
  14.                 u16ADCH_4 = ADCH;
  15.                 u16ADC_4 = (u16ADCH_4 << 2) + u16ADCL_4;   
  16.                
  17.                 if(u16ADC<500){
  18.                 P14 = 0;
  19.                 }         
  20.                
  21.                 else if(u16ADC_4<500){                       
  22.                         P14 = 1;
  23.                 }       

这样写的话,烧录进去就是u16ADC>500无论u16ADC_4是怎样的P14 都是 0;
而u16ADC<500,u16ADC_4<500 的时候P14 = 1
u16ADC<500,u16ADC_4>500 的时候P14 = 0
读出来的数值是错误的
 楼主| henxiano 发表于 2019-8-21 13:51 | 显示全部楼层
小明的同学 发表于 2019-8-18 00:14
你在一次转化结束后要进行清零。
    clr_ADCI;                                           // Clear ADC  ...
  1. Trigger_ADC_Convertion();
  2. Set_ADC_Input_Mode(E_CHANNEL0);
  3. ADC_Channel_Sel(E_CHANNEL0);                       
  4. Enable_ADC_Interrupt();
  5. set_ADCEN;      
  6. u16ADCL = ADCCON0;
  7. u16ADCL = u16ADCL >> 6;               
  8. u16ADC = ADCH;
  9. u16ADC = (u16ADC << 2 ) + u16ADCL;
  10.       
  11. Trigger_ADC_Convertion();       
  12. Set_ADC_Input_Mode(E_CHANNEL4);        
  13. ADC_Channel_Sel(E_CHANNEL4);
  14. Enable_ADC_Interrupt();
  15. set_ADCEN;                 
  16. u16ADCL_4 = ADCCON0;
  17. u16ADCL_4 = u16ADCL_4 >> 6;                        
  18. u16ADCH_4 = ADCH;
  19. u16ADC_4 = (u16ADCH_4 << 2) + u16ADCL_4;   

  20. if(u16ADC_4>500){
  21.         P14 = 0;
  22. }         

  23. if(u16ADC_4<500){                       
  24.         P14 = 1;
  25. }       

我又试了一下,这样写的话变成读取通道0的数值,去掉通道0的配置就能正常读通道4
 楼主| henxiano 发表于 2019-8-21 14:05 | 显示全部楼层
yiyigirl2014 发表于 2019-8-18 11:43
楼主要仔细看手册,了解这个ADC的结构。

emmm你知道怎么配置吗
 楼主| henxiano 发表于 2019-8-21 14:05 | 显示全部楼层
yiyigirl2014 发表于 2019-8-18 11:43
楼主要仔细看手册,了解这个ADC的结构。

emmm你知道怎么配置吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

7

帖子

0

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