ADC应用示例
来源: 芯艺


/***********************************
功能:adc测试程序
MCU:dsPIC30F4011
TOOLS:MPLAB X IDE V3.15 + XC16 V1.25
震荡器:外部4M晶振

芯艺设计室 http://www.chipart.cn
2015-12-08
***********************************/

#include "xc.h" 
#include <stdint.h>
#include <stdio.h>

#define XTFREQ                 4000000  // xtal = 4Mhz; 
#define PLLMODE                     16  // PLLx16 
#define FCY           XTFREQ*PLLMODE/4  // Instruction Cycle Frequency 
#include <libpic30.h>

#define UART_BAUD 9600

#define LED_PORT_INIT TRISBbits.TRISB6=0  
#define LED_ON  LATBbits.LATB6=1
#define LED_OFF LATBbits.LATB6=0
#define LED_FLASH LATBbits.LATB6^=1

_FOSC(CSW_FSCM_OFF & XT_PLL16);
_FWDT(WDT_OFF);

#define  DelayMs __delay_ms
#define APP 1 //1:扫描,手动转换  2:中断,自动转换

volatile unsigned int * adcPtr;//ADC缓冲区读取指针

void Uart1Init(void)
{
    U1MODE=0x0400; //格式:N,8,1,无校验  使用备用引脚RC13,RC14

  U1BRG = ((FCY/16)/UART_BAUD)-1;   //波特率设置

  U1STAbits.UTXISEL = 1;           //发送过程中发送缓冲器空时产生中断                               
  U1STAbits.URXISEL = 0;          //接收一个字节后中断
  
  //IEC0bits.U1RXIE = 1;             //接收中断允许
  //IEC0bits.U1TXIE = 1;             //发送中断允许
  
  U1MODEbits.UARTEN = 1;           //发送允许
  U1STAbits.UTXEN   = 1;           //使能
}

#if APP == 1

void AdcInit(void)
{
    ADCON1bits.FORM = 0; //格式为无符号整数
    ADCON1bits.SSRC = 0;//通过清SAMP位开始转换
    ADCON1bits.ASAM = 1; //采样在上一次转换结束后自动开始

    ADCON2bits.SMPI = 0;//15; //采样16次


    ADCON3bits.ADCS = 63; //tcy=1/16M=62.5ns Tad=Tcy*(ADCS+1)/2= 2us Fad=500kHz
    ADCON3bits.SAMC= 31;  //采样时间 31Tad=62us

    ADCHS = 0x0003; //选择通道A输入AN3
    ADCSSL = 0x0000; //禁止扫描

    ADPCFG = 0xFFFF;
    ADPCFGbits.PCFG3 = 0; //IO设置为模拟输入

    //Clear the A/D interrupt flag bit
    //IFS0bits.ADIF = 0; //清中断标志

    //Set the A/D interrupt enable bit
    //IEC0bits.ADIE = 1;//中断允许

    ADCON1bits.ADON = 1; //ADC使能
}
int main( void ) 
{
    uint16_t j;
    uint32_t ad;
    
    LED_PORT_INIT;
    LED_ON;
    Uart1Init();
    AdcInit();
    while(1)
    {            
        j=0;
        
        {
           DelayMs(10); //等待采样
           ADCON1bits.SAMP = 0; //转换
        //   DelayMs(10);
          j++;
        }
        while(!ADCON1bits.DONE);//等待转换完成
        /*
        ad=0;
        adcPtr = &ADCBUF0 ;
        for(i=0;i<16;i++)
            ad+= *adcPtr++;     //读取AD转换值
        ad/=16; //取平均
        */
                ad=ADCBUF0;
        DelayMs(1000);
        LED_FLASH;
        printf("ad:%d -- %d\r\n",(uint16_t)ad,j);
    } 
    return 0; 


#else 

void AdcInit(void)
{
    ADCON1bits.FORM = 0; //格式为无符号整数
    ADCON1bits.SSRC = 7;//自动采样并转换
    ADCON1bits.ASAM = 1; //采样在上一次转换结束后自动开始

    ADCON2bits.SMPI = 15; //采样16次

    ADCON3bits.ADCS = 63; //tcy=1/16M=62.5ns Tad=Tcy*(ADCS+1)/2= 2us Fad=500kHz
    ADCON3bits.SAMC= 31;  //采样时间 31Tad=62us

    ADCHS = 0x0003; //选择通道A输入AN3
    ADCSSL = 0x0000; //禁止扫描

    ADPCFG = 0xFFFF;
    ADPCFGbits.PCFG3 = 0; //IO设置为模拟输入

    IFS0bits.ADIF = 0; //清中断标志

    IEC0bits.ADIE = 1;//中断允许

    ADCON1bits.ADON = 1; //ADC使能
}

volatile uint8_t g_Flag=0; //转换完成标记
uint16_t g_AdValue[16];//转换值缓冲区

void __attribute__((interrupt, no_auto_psv)) _ADCInterrupt(void)
{
    int i = 0;
    IFS0bits.ADIF = 0;

    adcPtr = &ADCBUF0 ;
    for (i=0;i<16;i++)
       g_AdValue[i] = *adcPtr++;

    g_Flag=1;
}

int main( void ) 
{
    uint16_t i=0;
    uint32_t ad;
    
    LED_PORT_INIT;
    Uart1Init();
    AdcInit();
    while(1)
    { 
        while(g_Flag==0); //等待转换完成 
        
        ad=0;
        for(i=0;i<16;i++)
            ad+= g_AdValue[i];     //读取AD转换值
        ad/=16; //取平均 
        DelayMs(1000);
        LED_FLASH;
        printf("ad:%d \r\n",(uint16_t)ad);
        g_Flag=0;
    } 
    return 0; 


#endif 




声明:芯艺工作室(http://www.chipart.cn)保留所有权力,转载请注明出处!

芯艺工作室    蒙ICP备06005492号

Copyright© 2004-2018 ChipArt Studio All Rights Reserved