/***********************************
功能: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
|
|