打印
[技术问答]

N79E715的ADC问题

[复制链接]
1274|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
henxiano|  楼主 | 2019-8-16 17:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 henxiano 于 2019-8-17 16:35 编辑

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

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

if(u16ADC<24){
        P14 = 1;
}
else if(u16ADC>24){
        P14 = 0;
}

这个代码,如果去掉
Set_ADC_Input_Mode(E_CHANNEL4);                     // Set ADC4 (P0.5 default) is input only mode
ADC_Channel_Sel(E_CHANNEL4);                        // ADC Channel Select (P0.5 default)                                                                          
u16ADCL_4 = ADCCON0;
u16ADCL_4 = u16ADCL_4 >> 6;                         // ADC[1:0]
u16ADCH_4 = ADCH;
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转化器,你这么配置就更不对了,你要配置好一个,就读取一个的结果输出,然后配置第二个读取第二个。可以把每一路的设置和读取放到一个函数里,直接调用。

使用特权

评论回复
5
小明的同学| | 2019-8-17 23:01 | 只看该作者
没用过这个,仅仅猜测,我用过003的,N76E003应该跟这个差不多 吧,例子里已经说明了,启动一个ADC的通道时候就只读取这一个,读取完了,你想读取另外一个,再关闭这个,启动那个。
void main (void) 
{
                InitialUART0_Timer1(115200);

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

使用特权

评论回复
6
小明的同学| | 2019-8-18 00:10 | 只看该作者
/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright(c) 2015 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/

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

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

#define Uart_Port_Sel   0x00

#include "N79E715.h"
#include "Typedef.h"
#include "Define.h"
#include "Common.h"
#include "Delay.h"
#include "ADC.h"
#include "Version.h"
#include <intrins.h>
#include <stdio.h>
#include <string.h>

//-----------------------------------------------------------------------------------------------------------
void Enable_ADC_Interrupt(void)
{
    EADC = 1;
    EA = 1;
}
//-----------------------------------------------------------------------------------------------------------
void ADC_Channel_Sel(E_ADCCNL_SEL channel)
{
    switch (channel)
    {
        case E_CHANNEL0:                                // P0.1 (default)
            clr_AADR2;
            clr_AADR1;
            clr_AADR0;
            break;
        case E_CHANNEL1:                                // P0.2
            clr_AADR2;
            clr_AADR1;
            set_AADR0;
            break;
        case E_CHANNEL2:                                // P0.3
            clr_AADR2;
            set_AADR1;
            clr_AADR0;
            break;
        case E_CHANNEL3:                                // P0.4
            clr_AADR2;
            set_AADR1;
            set_AADR0;
            break;
        case E_CHANNEL4:                                // P0.5
            set_AADR2;
            clr_AADR1;
            clr_AADR0;
            break;
        case E_CHANNEL5:                                // P0.6
            set_AADR2;
            clr_AADR1;
            set_AADR0;
            break;
        case E_CHANNEL6:                                // P0.7
            set_AADR2;
            set_AADR1;
            clr_AADR0;
            break;
        case E_CHANNEL7:                                // P2.6
            set_AADR2;
            set_AADR1;
            set_AADR0;
            break;
    }
}
//-----------------------------------------------------------------------------------------------------------
void Set_ADC_Input_Mode(E_ADCCNL_SEL channel)
{
    switch (channel)
    {
        case E_CHANNEL0:                                // ADC0(P0.1) is input-only mode
            P0DIDS |= SET_BIT1;                         // Disable digital function for P0.1
            P0M1 |= SET_BIT1;
            P0M2 &= CLR_BIT1;
            break;
        case E_CHANNEL1:                                // ADC1(P0.2) is input-only mode
            P0DIDS |= SET_BIT2;                         // Disable digital function for P0.2
            P0M1 |= SET_BIT2;
            P0M2 &= CLR_BIT2;
            break;
        case E_CHANNEL2:                                // ADC2(P0.3) is input-only mode
            P0DIDS |= SET_BIT3;                         // Disable digital function for P0.3
            P0M1 |= SET_BIT3;
            P0M2 &= CLR_BIT3;
            break;
        case E_CHANNEL3:                                // ADC3(P0.4) is input-only mode
            P0DIDS |= SET_BIT4;                         // Disable digital function for P0.4
            P0M1 |= SET_BIT4;
            P0M2 &= CLR_BIT4;
            break;
        case E_CHANNEL4:                                // ADC4(P0.5) is input-only mode
            P0DIDS |= SET_BIT5;                         // Disable digital function for P0.5
            P0M1 |= SET_BIT5;
            P0M2 &= CLR_BIT5;
            break;
        case E_CHANNEL5:                                // ADC5(P0.6) is input-only mode
            P0DIDS |= SET_BIT6;                         // Disable digital function for P0.6
            P0M1 |= SET_BIT6;
            P0M2 &= CLR_BIT6;
            break;
        case E_CHANNEL6:                                // ADC6(P0.7) is input-only mode
            P0DIDS |= SET_BIT7;                         // Disable digital function for P0.7
            P0M1 |= SET_BIT7;
            P0M2 &= CLR_BIT7;
            break;
        case E_CHANNEL7:                                // ADC7(P2.6) is input-only mode(28 pin only)
            AUXR1 |= SET_BIT3;                          // Disable digital function for P2.6
            P2M1 |= SET_BIT6;
            P2M2 &= CLR_BIT6;
            break;
    }
}
//-----------------------------------------------------------------------------------------------------------
void Trigger_ADC_Convertion(void)
{
    clr_ADCI;                                           // Clear ADC flag (ADCI=0)
    set_ADCS;                                           // ADC run (ADCS = 1)
    PCON |= SET_BIT0;                                   // Enter idle mode
}
//-----------------------------------------------------------------------------------------------------------
void ADC_Init(void)
{
    Set_ADC_Input_Mode(E_CHANNEL0);                     // Set ADC0 (P0.1 default) is input only mode

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

    Enable_ADC_Interrupt();

    set_ADCEN;                                          // Enable ADC Function
}
//-----------------------------------------------------------------------------------------------------------
void main(void)
{
    UINT16 u16ADCL;
    UINT16 u16ADC;

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

    ADC_Init();
    while(1)
    {
        Trigger_ADC_Convertion();

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

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

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

        Delay1ms(500);
    }
}
//-----------------------------------------------------------------------------------------------------------
void ADC_ISR(void) interrupt 11                         // Vector @  0x5B
{
    clr_ADCI;                                           // Clear ADC flag (ADCI = 0)
    clr_ADCS;                                           // ADC stop (ADCS = 0)
}
//-----------------------------------------------------------------------------------------------------------






使用特权

评论回复
7
小明的同学| | 2019-8-18 00:11 | 只看该作者
上面的例子是官方提供的, 你仔细看,这个例子表名了所有的通道共用了一个ADC转化器,你使用哪个时候,ADC读取的就是哪个通道的。直接你用这个例子提供的那些函数做就行了。

使用特权

评论回复
8
小明的同学| | 2019-8-18 00:14 | 只看该作者
你在一次转化结束后要进行清零。
    clr_ADCI;                                           // Clear ADC flag (ADCI = 0)
    clr_ADCS;                                           // ADC stop (ADCS = 0)
这个,你注意了没,你之前调用的        Trigger_ADC_Convertion();
实际上就是坐了这个工作,你可以在第二个通道初始化后调用这个

使用特权

评论回复
9
小明的同学| | 2019-8-18 00:15 | 只看该作者
这样你第二个启动的通道就开始转化了。

使用特权

评论回复
10
yiyigirl2014| | 2019-8-18 11:43 | 只看该作者
楼主要仔细看手册,了解这个ADC的结构。

使用特权

评论回复
11
寒夜钟秋| | 2019-8-19 00:48 | 只看该作者

使用特权

评论回复
12
henxiano|  楼主 | 2019-8-21 12:02 | 只看该作者
小明的同学 发表于 2019-8-18 00:14
你在一次转化结束后要进行清零。
    clr_ADCI;                                           // Clear ADC  ...

                Trigger_ADC_Convertion();
                Set_ADC_Input_Mode(E_CHANNEL0);                     // Set ADC0 (P0.1 default) is input only mode
                ADC_Channel_Sel(E_CHANNEL0);                        // ADC Channel Select (P0.1 default)
                u16ADCL = ADCCON0;
                u16ADCL = u16ADCL >> 6;                         // ADC[1:0]
                u16ADC = ADCH;
                u16ADC = (u16ADC << 2 ) + u16ADCL;              // ADC[9:2] + ADC[1:0]       
                                                               
                Trigger_ADC_Convertion();       
                Set_ADC_Input_Mode(E_CHANNEL4);        
                ADC_Channel_Sel(E_CHANNEL4);           
                u16ADCL_4 = ADCCON0;
                u16ADCL_4 = u16ADCL_4 >> 6;                        
                u16ADCH_4 = ADCH;
                u16ADC_4 = (u16ADCH_4 << 2) + u16ADCL_4;   
               
                if(u16ADC<500){
                P14 = 0;
                }         
               
                else if(u16ADC_4<500){                       
                        P14 = 1;
                }       

这样写的话,烧录进去就是u16ADC>500无论u16ADC_4是怎样的P14 都是 0;
而u16ADC<500,u16ADC_4<500 的时候P14 = 1
u16ADC<500,u16ADC_4>500 的时候P14 = 0
读出来的数值是错误的

使用特权

评论回复
13
henxiano|  楼主 | 2019-8-21 13:51 | 只看该作者
小明的同学 发表于 2019-8-18 00:14
你在一次转化结束后要进行清零。
    clr_ADCI;                                           // Clear ADC  ...
Trigger_ADC_Convertion();
Set_ADC_Input_Mode(E_CHANNEL0);
ADC_Channel_Sel(E_CHANNEL0);                       
Enable_ADC_Interrupt();
set_ADCEN;      
u16ADCL = ADCCON0;
u16ADCL = u16ADCL >> 6;               
u16ADC = ADCH;
u16ADC = (u16ADC << 2 ) + u16ADCL;
      
Trigger_ADC_Convertion();       
Set_ADC_Input_Mode(E_CHANNEL4);        
ADC_Channel_Sel(E_CHANNEL4);
Enable_ADC_Interrupt();
set_ADCEN;                 
u16ADCL_4 = ADCCON0;
u16ADCL_4 = u16ADCL_4 >> 6;                        
u16ADCH_4 = ADCH;
u16ADC_4 = (u16ADCH_4 << 2) + u16ADCL_4;   

if(u16ADC_4>500){
        P14 = 0;
}         

if(u16ADC_4<500){                       
        P14 = 1;
}       

我又试了一下,这样写的话变成读取通道0的数值,去掉通道0的配置就能正常读通道4

使用特权

评论回复
14
henxiano|  楼主 | 2019-8-21 14:05 | 只看该作者
yiyigirl2014 发表于 2019-8-18 11:43
楼主要仔细看手册,了解这个ADC的结构。

emmm你知道怎么配置吗

使用特权

评论回复
15
henxiano|  楼主 | 2019-8-21 14:05 | 只看该作者
yiyigirl2014 发表于 2019-8-18 11:43
楼主要仔细看手册,了解这个ADC的结构。

emmm你知道怎么配置吗

使用特权

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

本版积分规则

1

主题

7

帖子

0

粉丝