搜索
bottom↓
回复: 12

dspic33EP32MC202 进入不了ADC中断大家帮忙看下

[复制链接]

出0入0汤圆

发表于 2016-9-7 08:37:49 | 显示全部楼层 |阅读模式
ADC没法进入中断,大家帮忙看下程序
#include "P33ep32mc202.h"
/** CONFIGURATION **************************************************/
_FGS(0xff);//写保护关闭
_FOSCSEL(0xfb);//双速振荡器启动使能 PWM锁定 带PLL的主振荡器
_FOSC(0xdd);//禁止时钟切换 外设引脚多次配置 SOC2数字IO XT晶振模式
_FWDT(0x7f);//看门狗禁止
_FPOR(0xff);//I2C1被映射到SAD1/SCL1引脚 欠压复位_
_FICD(0x03);//禁止JTAG 通过PGEC1 PGED1通讯
void initAdc1(void);
void Delayus(unsigned int);
int  i, j;
int ADCValues[8] = {0, 0, 0, 0, 0, 0, 0, 0};
void __attribute__((__interrupt__, auto_psv)) _ADC1Interrupt(void);
void System_Init(void)
{
   TRISB &= ~0xfc00;//RB10-RB15 清零
   IOCON1 = 0x0000;//GPIO 模块控制 PWMxH PWMxL引脚
}
int main(void)
{
    int ADC_Dat1,ADC_Dat2;
// Configure the device PLL to obtain 40 MIPS operation.The crystal frequency is 8 MHz.
// Divide 8 MHz by 2, multiply by 40 and divide by 2. This results in Fosc of 80 MHz.
// The CPU clock frequency is Fcy = Fosc/2 = 40 MHz.

PLLFBD = 41; /* M = 43 */
CLKDIVbits.PLLPOST = 0; /* N1 = 2 */
CLKDIVbits.PLLPRE = 0; /* N2 = 2 */
OSCTUN = 0;
/* Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0x3) */
__builtin_write_OSCCONH(0x03);
__builtin_write_OSCCONL(0x01);
while (OSCCONbits.COSC != 0x3);
while (_LOCK == 0); /* Wait for PLL lock at 40 MIPS */

System_Init();
Timer3_Timing_Init();
initAdc1();

while(1)
{  

}
}
void initAdc1(void)
{
    /* ADC端口配置 */
ANSELA = ANSELB = 0x0000;
ANSELAbits.ANSA0 = 1; // Ensure AN0/RA0 is analog
ANSELAbits.ANSA1 = 1; // Ensure AN1/RA1 is analog
ANSELBbits.ANSB0 = 1; // Ensure AN2/RB0 is analog
ANSELBbits.ANSB3 = 1; // Ensure AN5/RB3 is analog
/* Initialize and enable ADC module */
AD1CON1bits.FORM=0b00;//AD结果为整数
AD1CON1bits.SIMSAM=1;  //同时采样
AD1CON1bits.ASAM=1;    //上次采样结束立即开始采样
AD1CON1bits.SSRCG=0;
AD1CON1bits.SSRC=0b110; //定时器3比较结束立即开始采样
AD1CON2bits.VCFG=0b000; //参考电压为VCC电压
AD1CON2bits.CHPS=0b11; //同时采样4个通道
AD1CON2bits.SMPI=0b00000;//每完成一次采样产生ADC中断
AD1CON3 = 0x000F;
AD1CON4 = 0x0000;
AD1CSSH = 0x0000;
AD1CSSL = 0x0000;
AD1CHS0bits.CH0SA = 5; // Select AN5 for CH0 +ve input
AD1CHS0bits.CH0NA = 0; // Select Vref- for CH0 -ve input
AD1CHS123bits.CH123SA = 0; // Select AN0 for CH1 +ve input
AD1CHS123bits.CH123NA = 0; // Select Vref- for CH1/CH2/CH3 -ve inputs
/*ADC中断设置*/
IFS0bits.AD1IF = 0;             // Clear the A/D interrupt flag bit
IEC0bits.AD1IE = 1;             // Do Not Enable A/D interrupt
_AD1IP=6;
  AD1CON1bits.ADON = 1;           // Turn on the A/D converter
}
void Timer3_Timing_Init(void)//定时器模式
{
    T3CON=0x0000;
    TMR3 =0;//初始值*/
    PR3 =2000;//周期值
    _T3IP = 0x01; // 优先级1
    IFS0bits.T3IF = 0; // Timer3中断标志状态位 清零
    IEC0bits.T3IE = 0; // Timer3中断允许位 禁止
    T3CONbits.TON = 1;//启动使能16位Timer3
}
void Delayus(unsigned int delay)
{
for (i = 0; i < delay; i++)
{
asm  volatile ("repeat #39");
asm volatile ("nop");
}
}
/* ADC1中断*/
void __attribute__((__interrupt__, auto_psv)) _ADC1Interrupt(void)
{
    IFS0bits.AD1IF = 0;             // Clear the ADC1 Interrupt Flag

    ADCValues[0] = ADC1BUF0; // Read the AN5 conversion result
    ADCValues[1] = ADC1BUF1; // Read the AN0 conversion result
    ADCValues[2] = ADC1BUF2; // Read the AN1 conversion result
    ADCValues[3] = ADC1BUF3; // Read the AN2 conversion result

    if(ADCValues[2]>=500) PORTBbits.RB11=1;
    else PORTBbits.RB11=0;
     if(ADCValues[3]>=300) PORTBbits.RB12=1;
    else PORTBbits.RB12=0;
    if(ADCValues[0]>=1023) PORTBbits.RB13=1;
    else PORTBbits.RB13=0;
     if(ADCValues[1]>=300) PORTBbits.RB14=1;
    else PORTBbits.RB14=0;



}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出20入12汤圆

发表于 2016-9-7 08:53:59 | 显示全部楼层
        INTCON2bits.GIE = 1;// Enabled System Interrupt

出0入0汤圆

 楼主| 发表于 2016-9-7 10:14:21 | 显示全部楼层
gaolf_2012 发表于 2016-9-7 08:53
INTCON2bits.GIE = 1;// Enabled System Interrupt

你好,试了不行哦,

出20入12汤圆

发表于 2016-9-7 10:47:44 | 显示全部楼层
本帖最后由 gaolf_2012 于 2016-9-7 10:51 编辑

t3中断能进不?
不好意思,看错了.这句话不算.

出20入12汤圆

发表于 2016-9-7 11:03:30 | 显示全部楼层
PR3 =2000;//周期值
先把这个数调大,比如200000,看看是不是触发太快了导致还没转换完又重新采样转换了

出0入0汤圆

 楼主| 发表于 2016-9-7 11:34:06 | 显示全部楼层
gaolf_2012 发表于 2016-9-7 11:03
PR3 =2000;//周期值
先把这个数调大,比如200000,看看是不是触发太快了导致还没转换完又重新采样转换了 ...

你好,我在ADC1中断程序加了一个中断标志位来判定是否进入中断,结果是ADC没有中断,就是就Timer3没有触发ADC进入中断,Timer3 我都测试过了是没有问题的,这个ADC中断都搞了好久了

出20入12汤圆

发表于 2016-9-7 12:30:25 | 显示全部楼层
1注意中断服务程序的名字
void __attribute__((interrupt, no_auto_psv))  __AD1Interrupt(void)
2要仔细看手册
如果SSRCG = 0:
111 = 由内部计数器结束采样并启动转换(自动转换)
110 = 保留
101 = 由PWM 辅助特殊事件触发结束采样并启动转换(2)
100 = 由Timer5 比较结束采样并启动转换
011 = 由PWM 主特殊事件触发结束采样并启动转换(2)
010 = 由Timer3 比较结束采样并启动转换
001 = 由INT0 引脚上的有效电平跳变结束采样并启动转换
000 = 由清零采样位(SAMP)结束采样并启动转换(手动模式)

下面是可以进中断的程序
//--------------------------------------------------------------------------
#include "P33ep32mc202.h"
_FGS(0xff);//写保护关闭
_FOSCSEL(0xfb);//双速振荡器启动使能 PWM锁定 带PLL的主振荡器
_FOSC(0xdd);//禁止时钟切换 外设引脚多次配置 SOC2数字IO XT晶振模式
_FWDT(0x7f);//看门狗禁止
_FPOR(0xff);//I2C1被映射到SAD1/SCL1引脚 欠压复位_
_FICD(0x03);//禁止JTAG 通过PGEC1 PGED1通讯
void initAdc1(void);
int  i, j;

int ADCValues[8] = {0, 0, 0, 0, 0, 0, 0, 0};


//void __attribute__((__interrupt__, auto_psv)) _ADC1Interrupt(void)
void __attribute__((interrupt, no_auto_psv))  _AD1Interrupt(void)
{
        IFS0bits.AD1IF = 0;             // Clear the ADC1 Interrupt Flag

        ADCValues[0] = ADC1BUF0; // Read the AN5 conversion result
        ADCValues[1] = ADC1BUF1; // Read the AN0 conversion result
        ADCValues[2] = ADC1BUF2; // Read the AN1 conversion result
        ADCValues[3] = ADC1BUF3; // Read the AN2 conversion result

        if(ADCValues[2]>=500) PORTBbits.RB11=1;
        else PORTBbits.RB11=0;
        if(ADCValues[3]>=300) PORTBbits.RB12=1;
        else PORTBbits.RB12=0;
        if(ADCValues[0]>=1023) PORTBbits.RB13=1;
        else PORTBbits.RB13=0;
        if(ADCValues[1]>=300) PORTBbits.RB14=1;
        else PORTBbits.RB14=0;
}

void initAdc1(void)
{
        /* ADC端口配置 */
        ANSELA = ANSELB = 0x0000;
        ANSELAbits.ANSA0 = 1; // Ensure AN0/RA0 is analog
        ANSELAbits.ANSA1 = 1; // Ensure AN1/RA1 is analog
        ANSELBbits.ANSB0 = 1; // Ensure AN2/RB0 is analog
        ANSELBbits.ANSB3 = 1; // Ensure AN5/RB3 is analog
        /* Initialize and enable ADC module */
        AD1CON1bits.FORM=0b00;//AD结果为整数
        AD1CON1bits.SIMSAM=1;  //同时采样
        AD1CON1bits.ASAM=1;    //上次采样结束立即开始采样
        AD1CON1bits.SSRCG=0;
        //AD1CON1bits.SSRC=0b110; //定时器3比较结束立即开始采样
        AD1CON1bits.SSRC=0b010; //定时器3比较结束立即开始采样
        AD1CON2bits.VCFG=0b000; //参考电压为VCC电压
        AD1CON2bits.CHPS=0b11; //同时采样4个通道
        AD1CON2bits.SMPI=0b00000;//每完成一次采样产生ADC中断
        AD1CON3 = 0x000F;
        AD1CON4 = 0x0000;
        AD1CSSH = 0x0000;
        AD1CSSL = 0x0000;
        AD1CHS0bits.CH0SA = 5; // Select AN5 for CH0 +ve input
        AD1CHS0bits.CH0NA = 0; // Select Vref- for CH0 -ve input
        AD1CHS123bits.CH123SA = 0; // Select AN0 for CH1 +ve input
        AD1CHS123bits.CH123NA = 0; // Select Vref- for CH1/CH2/CH3 -ve inputs
        /*ADC中断设置*/
        IFS0bits.AD1IF = 0;             // Clear the A/D interrupt flag bit
        IEC0bits.AD1IE = 1;             // Do Not Enable A/D interrupt
        _AD1IP=6;
        AD1CON1bits.ADON = 1;           // Turn on the A/D converter
}

void Timer3_Timing_Init(void)//定时器模式
{
        T3CON=0x0000;
        TMR3 =0;//初始值*/
        PR3 =2000;//周期值
        _T3IP = 0x01; // 优先级1
        IFS0bits.T3IF = 0; // Timer3中断标志状态位 清零
        IEC0bits.T3IE = 0; // Timer3中断允许位 禁止
        T3CONbits.TON = 1;//启动使能16位Timer3
}
int main(void)
{
        int ADC_Dat1,ADC_Dat2;

        PLLFBD = 41; /* M = 43 */
        CLKDIVbits.PLLPOST = 0; /* N1 = 2 */
        CLKDIVbits.PLLPRE = 0; /* N2 = 2 */
        OSCTUN = 0;
        /* Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0x3) */
        __builtin_write_OSCCONH(0x03);
        __builtin_write_OSCCONL(0x01);
        while (OSCCONbits.COSC != 0x3);
        while (_LOCK == 0); /* Wait for PLL lock at 40 MIPS */

        //TRISB &= ~0xfc00;//RB10-RB15 清零
        IOCON1 = 0x0000;//GPIO 模块控制 PWMxH PWMxL引脚

        Timer3_Timing_Init();
        initAdc1();
        INTCON2bits.GIE = 1;// Enabled System Interrupt

        while(1);
}

出0入0汤圆

 楼主| 发表于 2016-9-7 13:46:28 | 显示全部楼层
gaolf_2012 发表于 2016-9-7 12:30
1注意中断服务程序的名字
void __attribute__((interrupt, no_auto_psv))  __AD1Interrupt(void)
2要仔细看 ...

太感谢你了,可以了,SSRC那个位确实是我搞错了,但AD中断服程序名我真不知道错,真有很感谢你

出0入0汤圆

 楼主| 发表于 2016-9-7 13:53:20 | 显示全部楼层
gaolf_2012 发表于 2016-9-7 12:30
1注意中断服务程序的名字
void __attribute__((interrupt, no_auto_psv))  __AD1Interrupt(void)
2要仔细看 ...

还有个事请教你一下,关于中断服务程序名称那里有这些资料可以了解呀,我用的是X6编译器

出20入12汤圆

发表于 2016-9-7 15:05:33 | 显示全部楼层
我用的是xc16编译器,在这个文件夹下找你使用的芯片对应的gld文件
C:\Program Files\Microchip\xc16\v1.23\support\dsPIC33E\gld

出0入0汤圆

 楼主| 发表于 2016-9-7 15:25:25 | 显示全部楼层
gaolf_2012 发表于 2016-9-7 15:05
我用的是xc16编译器,在这个文件夹下找你使用的芯片对应的gld文件
C:\Program Files\Microchip\xc16\v1.23\s ...

我用的也是XC16编译器,我用记事本打开,很乱,没法看

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出20入12汤圆

发表于 2016-9-7 15:29:00 | 显示全部楼层
用mplab打开是正常的

出0入0汤圆

 楼主| 发表于 2016-9-7 16:35:04 | 显示全部楼层
gaolf_2012 发表于 2016-9-7 15:29
用mplab打开是正常的

看了,了解不了中断服务程序名称哦,里边也没有,只有中断向量表  寄存器的定义
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 20:42

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表