zhuotuzi 发表于 2023-2-10 09:45

M031 操作24位模数转换器 NAU7802


示例代码用于配置Nuvoton的NAU7802,然后从中读取ADC数据。NAU7802是一款双通道、24位模数转换器(ADC),可用于音频应用、电子平衡或工业控制。本文档介绍了引脚配置、输入通道配置、PGA增益配置、ADC校准、转换启动、读取数据等示例代码。
为了测试这个示例代码,可以使用一个可调电源作为NAU7802的输入源,其电压范围在-1.55到1.55伏之间。执行程序后,输出结果如下所示。


操作过程如下所示




管脚配置


zhuotuzi 发表于 2023-2-10 09:45

完整代码如下
/******************************************************************************
* @file   main.c
* @versionV1.00
* $Revision: 5 $
* $Date: 18/07/09 7:01p $
* @brief    Show how to use I2C interface to control NAU7802.
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "NuMicro.h"

/*------------------------------------------------------------------------------------------------*/
/* Define                                                                                       */
/*------------------------------------------------------------------------------------------------*/
#define ADC_SLAVE_ADDR      0x2A

/* Register address */
#define PU_CTRL_ADDR          0x00
#define CTRL1_ADDR            0x01
#define CTRL2_ADDR            0x02
#define OCAL1_B2_ADDR         0x03
#define OCAL1_B1_ADDR         0x04
#define OCAL1_B0_ADDR         0x05
#define GCAL1_B3_ADDR         0x06
#define GCAL1_B2_ADDR         0x07
#define GCAL1_B1_ADDR         0x08
#define GCAL1_B0_ADDR         0x09
#define OCAL2_B2_ADDR         0x0A
#define OCAL2_B1_ADDR         0x0B
#define OCAL2_B0_ADDR         0x0C
#define GCAL2_B3_ADDR         0x0D
#define GCAL2_B2_ADDR         0x0E
#define GCAL2_B1_ADDR         0x0F
#define GCAL2_B0_ADDR         0x10
#define I2C_CONTROL_ADDR      0x11
#define ADCO_B2_ADDR          0x12
#define ADCO_B1_ADDR          0x13
#define ADCO_B0_ADDR          0x14
#define OTP_B1_ADDR         0x15
#define OTP_B0_ADDR         0x16
#define PGA_PWR_ADDR          0x1B
#define DEVICE_REVISION_ADDR0x1F


/* AVDD source select */
#define AVDDS_Pos(7)
#define AVDDS_Msk(1<<AVDDS_Pos)
#define AVDDS_LDO(1<<AVDDS_Pos)/* Internal LDO */
#define AVDDS_PIN(0<<AVDDS_Pos)/* AVDD pin input (default) */


/* System clock source select */
#define OSCS_Pos(6)
#define OSCS_Msk(1<<OSCS_Pos)
#define OSCS_EXT(1<<OSCS_Pos)/* External Crystal */
#define OSCS_IRC(0<<OSCS_Pos)/* Internal RC oscillator (default) */

/* Cycle ready (Read only Status) */
#define CR_Pos       (5)
#define CR_Msk       (1<<CR_Pos)
#define CR_DATA_RDY(1<<CR_Pos)/* ADC DATA is ready */

/* Cycle start */
#define CS_Pos               (4)
#define CS_Msk               (1<<CS_Pos)
#define CS_START_CONVERSION(1<<CS_Pos)/* Synchronize conversion to the rising edge of this register */

/* Power up ready (Read Only Status) */
#define PUR_Pos         (3)
#define PUR_Msk         (1<<PUR_Pos)
#define PUR_POWER_UP    (1<<PUR_Pos)    /* Power Up ready */
#define PUR_POWER_DOWN(0<<PUR_Pos)    /* Power down, not ready */

/* Power up analog circuit */
#define PUA_Pos               (2)
#define PUA_Msk               (1<<PUA_Pos)
#define PUA_POWER_UP   (1<<PUA_Pos)    /* Power up the chip analog circuits (PUD must be 1) */
#define PUA_POWER_DOWN (0<<PUA_Pos)    /* Power down (default) */

/* Power up digital circuit */
#define PUD_Pos               (1)
#define PUD_Msk               (1<<PUD_Pos)
#define PUD_POWER_UP   (1<<PUD_Pos)    /* Power up the chip digital logic */
#define PUD_POWER_DOWN   (0<<PUD_Pos)    /* power down (default) */

/* Register reset */
#define RR_Pos    (0)
#define RR_Msk    (1<<RR_Pos)
#define RR_RESET(1<<RR_Pos)/* Register Reset, reset all register except RR */
#define RR_NORMAL (0<<RR_Pos)/* Normal Operation (default) */


/* Conversion Ready Pin Polarity (16 Pin Package Only) */
#define CRP_Pos         (7)
#define CRP_Msk         (1<<CRP_Pos)
#define CRP_ACTIVE_LOW(1<<CRP_Pos)   /* CRDY pin is LOW Active (Ready when 0) */
#define CRP_ACTIVE_HIGH (0<<CRP_Pos)   /* CRDY pin is High Active(Ready when 1) (default) */

/* Select the function of DRDY pin */
#define DRDY_SEL_Pos         (6)
#define DRDY_SEL_Msk         (1<<DRDY_SEL_Pos)
#define DRDY_SEL_OUTPUT_CLOCK(1<<DRDY_SEL_Pos)       /* DRDY output the Buffered Crystal Clock if OSCS=1 */
#define DRDY_SEL_OUTPUT_CONVERSION(0<<DRDY_SEL_Pos)/* DRDY output the conversion ready (default) */

/* LDO Voltage */
#define VLDO_Pos(3)
#define VLDO_Msk(7<<VLDO_Pos)
#define VLDO_2V4(7<<VLDO_Pos)/* 2.4v */
#define VLDO_2V7(6<<VLDO_Pos)/* 2.7v */
#define VLDO_3V0(5<<VLDO_Pos)/* 3.0v */
#define VLDO_3V3(4<<VLDO_Pos)/* 3.3v */
#define VLDO_3V6(3<<VLDO_Pos)/* 3.6v */
#define VLDO_3V9(2<<VLDO_Pos)/* 3.9v */
#define VLDO_4V2(1<<VLDO_Pos)/* 4.2v */
#define VLDO_4V5(0<<VLDO_Pos)/* 4.5v (default) */

/* Gain select */
#define GAINS_Pos(0)
#define GAINS_Msk(7<<GAINS_Pos)
#define GAINS_128(7<<GAINS_Pos)/* x128 */
#define GAINS_64   (6<<GAINS_Pos)/* x64 */
#define GAINS_32   (5<<GAINS_Pos)/* x32 */
#define GAINS_16   (4<<GAINS_Pos)/* x16 */
#define GAINS_8    (3<<GAINS_Pos)/* x8 */
#define GAINS_4    (2<<GAINS_Pos)/* x4 */
#define GAINS_2    (1<<GAINS_Pos)/* x2 */
#define GAINS_1    (0<<GAINS_Pos)/* x1 (default) */

/* Analog input channel select */
#define CHS_Pos(7)
#define CHS_Msk(1<<CHS_Pos)
#define CHS_CH2(1<<CHS_Pos)/* 1 = Ch2 */
#define CHS_CH1(0<<CHS_Pos)/* 0 = Ch1 (default) */

/* Conversion rate select */
#define CRS_Pos(4)
#define CRS_Msk(7<<CRS_Pos)
#define CRS_320(7<<CRS_Pos)/* 111 = 320SPS */
#define CRS_80   (3<<CRS_Pos)/* 011 = 80SPS */
#define CRS_40   (2<<CRS_Pos)/* 010 = 40SPS */
#define CRS_20   (1<<CRS_Pos)/* 001 = 20SPS */
#define CRS_10   (0<<CRS_Pos)/* 000 = 10SPS (default) */

/* Read Only calibration result */
#define CAL_ERR_Pos      (3)
#define CAL_ERR_Msk      (1<<CAL_ERR_Pos)
#define CAL_ERR_ERROR    (1<<CAL_ERR_Pos)/* 1: there is error in this calibration */
#define CAL_ERR_NO_ERROR (0<<CAL_ERR_Pos)/* 0: there is no error */

/* Write 1 to this bit will trigger calibration based on the selection in CALMOD */
/* This is an "Action" register bit. When calibration is finished, it will reset to 0 */
#define CALS_Pos      (2)
#define CALS_Msk      (1<<CALS_Pos)
#define CALS_ACTION   (1<<CALS_Pos)
#define CALS_FINISHED (0<<CALS_Pos)

/* Calibration mode */
#define CALMOD_Pos            (0)
#define CALMOD_Msk            (3<<CALMOD_Pos)
#define CALMOD_GAIN             (3<<CALMOD_Pos)/* 11 = Gain Calibration System */
#define CALMOD_OFFSET         (2<<CALMOD_Pos)/* 10 = Offset Calibration System */
#define CALMOD_ RESERVED      (1<<CALMOD_Pos)/* 01 = Reserved */
#define CALMOD_OFFSET_INTERNAL(0<<CALMOD_Pos)/* 00 = Offset Calibration Internal (default) */

/* Enable bit for Pull SDA low when conversion complete and I2C IDLE(special non-standard I2C) 1 = enable 0 = disable (default) */
#define CRSD_Pos            (7)
#define CRSD_Msk            (1<<CRSD_Pos)
#define CRSD_PULL_SDA_LOW   (1<<CRSD_Pos)
#define CRSD_PULL_SDA_HIGH(0<<CRSD_Pos)

/* Enable bit for Fast Read ADC DATA (special non-standard I2C) 1 = enable fast read ADC Data special non-standard I2C */
#define FRD_Pos                  (6)
#define FRD_Msk                  (1<<FRD_Pos)
#define FRD_FAST_READ_ENABLE   (1<<FRD_Pos)
#define FRD_FAST_READ_DISENABLE(0<<FRD_Pos) /* Disable fast read ADC Data feature(default) */

/* Enable bit for Strong Pull Up for I2C SCLK and SDA */
#define SPE_Pos                  (5)
#define SPE_Msk                  (1<<SPE_Pos)
#define SPE_STRONG_PULL_ENABLE   (1<<SPE_Pos)/* enable strong pull up (nominal 1.6 k ohm) */
#define SPE_STRONG_PULL_DISABLE(0<<SPE_Pos)/* disable strong pull up (default) */

/* Disable bit for Weak Pull Up for I2C SCLK and SDA */
#define WPD_Pos                (4)
#define WPD_Msk                (1<<WPD_Pos)
#define WPD_WEAK_PULL_DISABLE(1<<WPD_Pos)/* disable weak pull up */
#define WPD_WEAK_PULL_ENABLE(0<<WPD_Pos)   /* enable weak pull up (default nominal 50 k ohm) */

/* Short the input together, measure offset */
#define SI_Pos          (3)
#define SI_Msk          (1<<SI_Pos)
#define SI_SHORT_INPUT(1<<SI_Pos)
#define SI_OPEN_INPUT   (0<<SI_Pos)

/* Enables the 2.5uA burnout current source to the PGA positive input when set to 1. */
#define BOPGA_Pos          (2)
#define BOPGA_Msk          (1<<BOPGA_Pos)
#define BOPGA_CURRENT_EN   (1<<BOPGA_Pos)
#define BOPGA_CURRENT_DIS(0<<BOPGA_Pos)   /* 0: Disables the current source.(default) */

/* Switches PGA input to temperature sensor when set to 1. */
#define TS_Pos             (1)
#define TS_Msk             (1<<TS_Pos)
#define TS_TEMP_TO_PGA   (1<<TS_Pos)
#define TS_TEMP_NO_TO_PGA(0<<TS_Pos)   /* 0: Uses VINx as PGA input (default)*/

/* Disables bandgap chopper when set to 1. */
#define BGPCP_Pos                      (0)
#define BGPCP_Msk                      (1<<BGPCP_Pos)
#define BGPCP_BANDGAP_CHOPPER_DISABLE(1<<BGPCP_Pos)/* Disables bandgap chopper */
#define BGPCP_BANDGAP_CHOPPER_ENABLE   (0<<BGPCP_Pos)/* Enables the bandgap chopper.(default) */

/* Read REG0x15 output select */
#define RD_OTP_SEL_Pos(7)
#define RD_OTP_SEL_Msk(1<<RD_OTP_SEL_Pos)
#define RD_OTP_SEL_OTP(1<<RD_OTP_SEL_Pos)/* Read REG0x15 will read OTP */
#define RD_OTP_SEL_ADC(0<<RD_OTP_SEL_Pos)/* Read REG0x15 will read ADC Registers */

/* LDOMODE */
#define LDOMODE_Pos(6)
#define LDOMODE_Msk(1<<LDOMODE_Pos)
#define LDOMODE_LOW_DC(1<<LDOMODE_Pos)   /* Improved stability and lower DC gain */
#define LDOMODE_HIGH_DC(0<<LDOMODE_Pos)/* Improved accuracy and higher DC gain */

/* PGA output buffer enable */
#define PGA_OUTPUT_BUFFER_Pos(5)
#define PGA_OUTPUT_BUFFER_Msk(1<<PGA_OUTPUT_BUFFER_Pos)
#define PGA_OUTPUT_BUFFER_ENABLE(1<<PGA_OUTPUT_BUFFER_Pos)   /* 1: PGA output buffer enable */
#define PGA_OUTPUT_BUFFER_DISABLE(0<<PGA_OUTPUT_BUFFER_Pos)/* 0: PGA output buffer disable */

/* PGA bypass enable */
#define PGA_BYPASS_Pos(4)
#define PGA_BYPASS_Msk(1<<PGA_BYPASS_Pos)
#define PGA_BYPASS_ENABLE(1<<PGA_BYPASS_Pos)   /* 1: PGA bypass enable */
#define PGA_BYPASS_DISABLE(0<<PGA_BYPASS_Pos)/* 0: PGA bypass disable */
/* 3 */
/* PGAINV */
#define PGAINV_Pos(3)
#define PGAINV_Msk(1<<PGAINV_Pos)
#define PGAINV_INVERT(1<<PGAINV_Pos)/* 1: invert PGA input phase */
#define PGAINV_NORMAL(0<<PGAINV_Pos)/* 0: default */

/* PGACHPDIS */
#define PGACHPDIS_Pos(0)
#define PGACHPDIS_Msk(1<<PGACHPDIS_Pos)
#define PGACHPDIS_DISABLE(1<<PGACHPDIS_Pos)/* 1: Chopper disabled */
#define PGACHPDIS_ENABLE(0<<PGACHPDIS_Pos)   /* 0: default */

/* Enables PGA output bypass capacitor connected across pins Vin2P Vin2N */
#define PGA_CAP_EN_Pos (7)
#define PGA_CAP_EN_Msk (1<<PGA_CAP_EN_Pos)
#define PGA_CAP_EN_SET (1<<PGA_CAP_EN_Pos)
#define PGA_CAP_EN_CLR(0<<PGA_CAP_EN_Pos)

/* Master bias Current */
#define MASTER_BIAS_CURR_Pos(4)
#define MASTER_BIAS_CURR_Msk(7<<MASTER_BIAS_CURR_Pos)
#define MASTER_BIAS_CURR_100 (0<<MASTER_BIAS_CURR_Pos)/* 100% (default) */
#define MASTER_BIAS_CURR_90(1<<MASTER_BIAS_CURR_Pos)/* 90% (lower power & accuracy) */
#define MASTER_BIAS_CURR_80(2<<MASTER_BIAS_CURR_Pos)/* 0 1 0 80% */
#define MASTER_BIAS_CURR_73(3<<MASTER_BIAS_CURR_Pos)/* 0 1 1 73% */
#define MASTER_BIAS_CURR_67(4<<MASTER_BIAS_CURR_Pos)/* 1 0 0 67% */
#define MASTER_BIAS_CURR_62(5<<MASTER_BIAS_CURR_Pos)/* 1 0 1 62% */
#define MASTER_BIAS_CURR_58(6<<MASTER_BIAS_CURR_Pos)/* 1 1 0 58% */
#define MASTER_BIAS_CURR_54(7<<MASTER_BIAS_CURR_Pos)/* 1 1 1 54% */

/* ADC Current */
#define ADC_CURR_Pos(2)
#define ADC_CURR_Msk(3<<ADC_CURR_Pos)
#define ADC_CURR_100(0<<ADC_CURR_Pos)   /* 0 0 100% of master bias */
#define ADC_CURR_75(1<<ADC_CURR_Pos)      /* 0 1 75%of master bias */
#define ADC_CURR_50(2<<ADC_CURR_Pos)      /* 1 0 50%of master bias */
#define ADC_CURR_25(3<<ADC_CURR_Pos)      /* 1 1 25%of master bias */

/* PGA Current */
#define PGA_CURR_Pos(0)
#define PGA_CURR_Msk(3<<PGA_CURR_Pos)
#define PGA_CURR_100(0<<PGA_CURR_Pos)/* 0 0 100% of master bias (default) */
#define PGA_CURR_95(1<<PGA_CURR_Pos)   /* 0 1 95% of master bias (lower power & accuracy) */
#define PGA_CURR_86(2<<PGA_CURR_Pos)   /* 1 0 86% of master bias */
#define PGA_CURR_70(3<<PGA_CURR_Pos)   /* 1 1 70% of master bias */
/*------------------------------------------------------------------------------------------------*/
/* Global variables                                                                               */
/*------------------------------------------------------------------------------------------------*/
volatile uint8_t g_au8TxData;
volatile uint8_t g_u8RxData;
volatile uint8_t g_u8DataLen;
volatile uint8_t g_u8EndFlag = 0;

typedef void (*I2C_FUNC)(uint32_t u32Status);

volatile static I2C_FUNC s_I2C0HandlerFn = NULL;

/* ADC chip register read and write */
uint8_t ADC_ReadReg(uint8_t u8RegAddr)
{

    uint8_t rdata = 0U;
    rdata = I2C_ReadByteOneReg(I2C1, ADC_SLAVE_ADDR, u8RegAddr);
    return rdata;
}

uint8_t ADC_WriteReg(uint8_t u8RegAddr, uint8_t data)
{
    uint8_t u8Err;
    u8Err = I2C_WriteByteOneReg(I2C1, ADC_SLAVE_ADDR, u8RegAddr, data);
    return u8Err;
}

/**
* @brief      ADC_Config
*
* @paramch      CHS_CH1 ch1
*                     CHS_CH2 ch2
* @paramrate    Conversion rate select
*                                  CRS_320 = 320SPS
*                                  CRS_80 = 80SPS
*                                  CRS_40 = 40SPS
*                                  CRS_20 = 20SPS
*                                  CRS_10 = 10SPS (default)
* @paramgain    Gain select
*                                  GAINS_128 = x128
*                                  GAINS_64 = x64
*                                  GAINS_32 = x32
*                                  GAINS_16 = x16
*                                  GAINS_8 = x8
*                                  GAINS_4 = x4
*                                  GAINS_2 = x2
*                                  GAINS_1 = x1 (default)
*
*
* @details
*
*/
void ADC_Config(uint8_t ch, uint8_t rate, uint8_t gain)
{
    uint8_t reg = 0;
    /* Set channel and Conversion rate */
    reg = ADC_ReadReg(CTRL2_ADDR);
    reg &= ~(CHS_Msk | CRS_Msk);
    reg |= (ch |   /* CHS: 0 = ch1,1 = ch2 */
            rate); /* CRS: Sample rate can be set to 10, 20, 40, 80, or 320Hz */
    ADC_WriteReg(CTRL2_ADDR, reg);

    /* Set gain */
    reg = ADC_ReadReg(CTRL1_ADDR);
    reg &= ~(GAINS_Msk);
    reg |= gain;/* Gain can be set to 1, 2, 4, 8, 16, 32, 64, or 128. */

    ADC_WriteReg(CTRL1_ADDR, reg);
}

void ADC_Calibration(void)
{
    uint8_t reg = 0;

    while (1)
    {

      reg = ADC_ReadReg(CTRL2_ADDR);
      reg &= ~(CALMOD_Msk | CALS_Msk);

      /* Set Calibration mode */
      reg |= CALMOD_OFFSET_INTERNAL;   /* Calibration mode = Internal Offset Calibration */
      ADC_WriteReg(CTRL2_ADDR, reg);

      /* Start calibration */
      reg |= CALS_ACTION;            /* Start calibration */
      ADC_WriteReg(CTRL2_ADDR, reg);

      while (1)
      {
            /* Wait for calibration finish */
            TIMER_Delay(TIMER0, 50000); /* Wait 50ms */

            /* Read calibration result */
            reg = ADC_ReadReg(CTRL2_ADDR);

            if ((reg & CALS_Msk) == CALS_FINISHED)
                break;
      }

      reg &= CAL_ERR_Msk;

      if ((reg & CAL_ERR_Msk) == 0) /* There is no error */
            break;
    }

    TIMER_Delay(TIMER0, 1000);    /* Wait 1 ms */
}

voidADCchip_Init(void)
{
    uint8_t reg = 0;

    /* Reset */
    reg =RR_RESET;                   /* Enter reset mode */
    ADC_WriteReg(PU_CTRL_ADDR, reg);

    TIMER_Delay(TIMER0, 1000);         /* Wait 1 ms */
    reg =RR_NORMAL;                  /* Enter Noraml mode */
    ADC_WriteReg(PU_CTRL_ADDR, reg);
    TIMER_Delay(TIMER0, 1000);         /* Wait 1 ms */

    /* Setting */
    reg = (AVDDS_PIN | /* AVDD = external pin input */
         OSCS_IRC);/* Clock = Internal RC oscillator */
    ADC_WriteReg(PU_CTRL_ADDR, reg);

    reg = (CRP_ACTIVE_LOW |             /* DRDY = LOW Active */
         DRDY_SEL_OUTPUT_CONVERSION | /* DRDY output = conversion ready */
         VLDO_3V3 |                   /* LDO = 3.3V(no use) */
         GAINS_1);                  /* PGA = x1 */
    ADC_WriteReg(CTRL1_ADDR, reg);

    reg = (CHS_CH1 |   /* Input channel = CH1 */
         CRS_10); /* Sample rate = 10SPS */
    ADC_WriteReg(CTRL2_ADDR, reg);

    reg = 0x30;
    ADC_WriteReg(OTP_B1_ADDR, reg);


    /* Power on */
    reg = PUA_POWER_UP;/* Power on analog circuits */
    ADC_WriteReg(PU_CTRL_ADDR, reg);
    TIMER_Delay(TIMER0, 1000);/* Wait 1 ms */

    reg |= PUD_POWER_UP; /* Power on digital circuits */
    ADC_WriteReg(PU_CTRL_ADDR, reg);
    TIMER_Delay(TIMER0, 500000);/* Wait 500ms */

    /* Calibration */
    ADC_Calibration();
}
/**
* @brief      ADC_StartConversion
*
* @paramnone
* @details
*
*/
void ADC_StartConversion(void)
{
    uint8_t reg = 0;
    /* Start conversion */
    reg = ADC_ReadReg(PU_CTRL_ADDR);
    reg |= CS_START_CONVERSION; /* CS=1 */
    ADC_WriteReg(PU_CTRL_ADDR, reg);
}

uint32_t ADC_Read_Conversion_Data(void)
{
    uint8_t rdata;
    uint32_t result;

    I2C_ReadMultiBytesOneReg(I2C1, ADC_SLAVE_ADDR, ADCO_B2_ADDR, &rdata, 3);
    result = ((rdata << 16) | (rdata << 8) | rdata);
    return result;
}

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Enable HIRC clock (Internal RC 48MHz) */
    CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

    /* Wait for HIRC clock ready */
    CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

    /* Select HCLK clock source as HIRC and HCLK source divider as 1 */
    CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));

    /* Enable UART0 clock */
    CLK_EnableModuleClock(UART0_MODULE);

    /* Switch UART0 clock source to HIRC */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));

    /* Enable I2C1 clock */
    CLK_EnableModuleClock(I2C1_MODULE);

    /* Enable IP clock */
    CLK_EnableModuleClock(TMR0_MODULE);

    /* Select IP clock source */
    CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HIRC, 0);

    /* Update System Core Clock */
    /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock and cyclesPerUs automatically. */
    SystemCoreClockUpdate();

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set PB multi-function pins for UART0 RXD=PB.12 and TXD=PB.13 */
    SYS->GPB_MFPH = (SYS->GPB_MFPH & ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk)) |
                  (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);

    /* Set I2C1 multi-function pins */
    SYS->GPB_MFPL = (SYS->GPB_MFPL & ~(SYS_GPB_MFPL_PB0MFP_Msk | SYS_GPB_MFPL_PB0MFP_Msk)) |
                  (SYS_GPB_MFPL_PB0MFP_I2C1_SDA | SYS_GPB_MFPL_PB1MFP_I2C1_SCL);

    /* Lock protected registers */
    SYS_LockReg();
}

void I2C1_Close(void)
{
    /* Disable I2C1 interrupt and clear corresponding NVIC bit */
    I2C_DisableInt(I2C1);
    NVIC_DisableIRQ(I2C1_IRQn);

    /* Disable I2C1 and close I2C1 clock */
    I2C_Close(I2C1);
    CLK_DisableModuleClock(I2C1_MODULE);
}

void I2C1_Init(void)
{
    /* Open I2C module and set bus clock */
    I2C_Open(I2C1, 100000);

    /* Get I2C1 Bus Clock */
    printf("I2C clock %d Hz\n", I2C_GetBusClockFreq(I2C1));
}

int main()
{
    uint32_t i;
    uint32_t u32i32ConversionData;
    int i32ConversionData;
    SYS_Init();

    /* Init UART0 to 115200-8n1 for print message */
    UART_Open(UART0, 115200);

    /*
      This sample code sets I2C bus clock to 100kHz. Then, Set NAU7802, control NAU7802 to
      complete ADC conversion, and read ADC conversion value.
    */
    printf("+-------------------------------------------------+\n");
    printf("|    I2C Driver Sample Code with ADC NAU7802      |\n");
    printf("+-------------------------------------------------+\n");
    printf("I/O connection:\n");
    printf("M031         NAU7802\n");
    printf("PB.0 <--------> SDIO\n");
    printf("PB.1 <--------> SCLK\n");
    printf("ADC chip configuration:\n");
    printf("Clock source    = IRC\n");
    printf("AVDD source   = AVDD pin\n");
    printf("Input channel   = CH1\n");
    printf("VIN1P-VIN1N   = +/-0.5*(REFP-REFN)/PGA_Gain\n");
    printf("PGA Gain      = 1\n");
    printf("Conversion Rate = 10 SPS\n");
    printf("+-------------------------------------------------+\n");

    /* Init I2C1 to access ADC chip(NAU7802) */
    I2C1_Init();

    /* Init NAU7802 chip */
    ADCchip_Init();

    /* Start adc Conversion */
    ADC_StartConversion();

    while (1)
    {
      /* Wait ADC conversion done */
      while ((ADC_ReadReg(PU_CTRL_ADDR)&CR_Msk) != CR_DATA_RDY);

      /* Read Conversion data */
      u32i32ConversionData = ADC_Read_Conversion_Data();

      i32ConversionData = (int)(u32i32ConversionData << 8);
      /* Shift the number back right to recover its intended magnitude */
      i32ConversionData = (i32ConversionData >> 8);

      /* REFP - REFN measured value = 3.14 v */
      printf("input vol = VIN1P - VIN1N = %.2f\n", ((float)i32ConversionData / 16777216) * (float)(3.14));

      for (i = 0; i < 0x5fffff; i++);
    }
}

/*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/

tpgf 发表于 2023-3-1 15:46

这颗芯片是不是专门用于ad采集的芯片呢24位够高的啊

nawu 发表于 2023-3-1 16:06

我觉得在使用这个芯片的时候还得注意外部电路的走线

aoyi 发表于 2023-3-1 16:16

随着采集位数的提高 相应的转换速度会降低吗

zljiu 发表于 2023-3-1 16:33

楼主有没有自己实测数据采集精度能达到多少啊

gwsan 发表于 2023-3-1 16:45

看楼主代码 毛事使用的是循环等待方式 而不是中断方式是吗

tfqi 发表于 2023-3-1 16:57

转换数据上传使用的是iic的通讯方式吗?

AloneKaven 发表于 2023-3-1 19:27

位数增加了速度应该会降低吧
页: [1]
查看完整版本: M031 操作24位模数转换器 NAU7802