打印

芯片是dsPIC33CK32MP105, 我的ADC轉換結果永遠是0? 請問哪裡錯了?

[复制链接]
3362|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
edison吴|  楼主 | 2023-10-7 20:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Dear Supporter,
如提, 芯片是dsPIC33CK32MP105, 這個芯片我第一次使用ADC, 好複雜, 我看了Datashet一周了, 還是搞不定.請求協助.
我的基本設定: 使用ADC中斷, 使用腳位AN0腳(如附圖), 代碼是MCC產生的.已經執行了ADC相關的代碼了。
我在方案中加入了一個AD 0_ENABLE()的測試代碼(如下方的while(1)中, 我在DEBUG模式中等待中斷發生,然後在中斷中發現ADC的結果都是0,
請問哪裡錯了? 因為無法附上我的方案, 所以我只能提問.
    SYSTEM_Initialize();
    ADC1_Initialize();
    ADC1_Core0PowerEnable ( );
    ADC1_SharedCorePowerEnable ( );
    IO_Iintialize();                            /* Initial set I/O    */
    //======================================================================
    INTERRUPT_Initialize ();
    INTCON1bits.NSTDIS = 0;             /* Interrupt nesting enabled here */
    INTCON2bits.GIE = 1;                    /*INTERRUPT_GlobalEnable();=INTCON2bits.GIE = 1;*/

  while(1)
    {
      DISC=1;//放電
      d_ms(10);
      DISC=0;//充電到3.3v, 已經電阻1k焊接到3.3v
      ADC1_ChannelSelect(channel_AN0);//選擇ADC的輸入腳位
      ADC0_ENABLE();//開啟ADC
      d_ms(1000); //在這裡等待ADC中斷產生, 並且已經在中斷設置了暫停點, 也有成功產生了中斷, 但是讀值永遠是0。
    }     


adc1.c代碼
void __attribute__ ( ( __interrupt__ , auto_psv, weak ) ) _ADCAN0Interrupt ( void )
{
    uint16_t valchannel_AN0;
    //Read the ADC value from the ADCBUF
    valchannel_AN0 = ADCBUF0;
    if(ADC1_channel_AN0DefaultInterruptHandler)
    {
        ADC1_channel_AN0DefaultInterruptHandler(valchannel_AN0);
    }
   V_AN0=valchannel_AN0;  //中斷服務程序, 在這裡暫停檢查轉換的結果
    //clear the channel_AN0 interrupt flag
    IFS5bits.ADCAN0IF = 0;
}




//ADC的中斷服務程式
//================================================
void __attribute__ ( ( __interrupt__ , auto_psv, weak ) ) _ADCAN0Interrupt ( void )
{
    uint16_t valchannel_AN0;
    //Read the ADC value from the ADCBUF
    valchannel_AN0 = ADCBUF0;
    valchannel_AN0 = ADCBUF2;
    valchannel_AN0 = ADCBUF3;
    valchannel_AN0 = ADCBUF19;
    valchannel_AN0 = ADCBUF20;
    if(ADC1_channel_AN0DefaultInterruptHandler)
    {
        ADC1_channel_AN0DefaultInterruptHandler(valchannel_AN0);
    }
   V_AN0=valchannel_AN0;
    //clear the channel_AN0 interrupt flag
    IFS5bits.ADCAN0IF = 0;
}


使用特权

评论回复
评论
佯烊陽 2023-10-7 21:04 回复TA
你这个过程也有充放电过程,是也在做时间电压转换吗? 
沙发
ynwa| | 2023-10-8 10:12 | 只看该作者
你在While(1)里面调用的ADC0_ENABLE();是什么?不应该是ADC1_ENABLE();吗?

你是选择用什么触发源来启动ADC采样转换的?如果是软件触发,没有看到你软件设置触发位的语句。如果是其他外设触发,请确认作为触发源的外设是否产生触发条件来触发ADC。

按你说的情况,个人判断应该不会产生ADC中断。你说能进ADC中断,但读结果都是0,这点从逻辑上解释不通。

一般用软件触发ACD的操作流程如下,你可以先用简单的查询法测试一下。
        ADC1_Initialize();
        ADC1_Enable();
        ADC1_ChannelSelect(channel);
        ADC1_SoftwareTriggerEnable();
        while(!ADC1_IsConversionComplete(channel));
        conversion = ADC1_ConversionResultGet(channel);

使用特权

评论回复
板凳
edison吴|  楼主 | 2023-10-8 11:50 | 只看该作者
你的代碼我上周已經試過了, 是MCC產生的代碼, 結果也是0, 就是因為這個結果不對, 所以我改成了使用中斷的方式.ADC0_ENABLE()是打開ADC中斷
void    ADC0_ENABLE(void)
{
    IEC5bits.ADCAN0IE = 1;              
    IFS5bits.ADCAN0IF = 1;     
}

使用特权

评论回复
地板
edison吴|  楼主 | 2023-10-8 11:53 | 只看该作者
另外, ADC1_ENABLE是在 ADC1_Initialize ()中已經開啟了, 所以不需要再重新開啟吧? 是嗎?

void ADC1_Initialize (void)
{
    // ADSIDL disabled; CVDEN disabled; ADON enabled;
    ADCON1L = (0x8000 & 0x7FFF); //Disabling ADON bit
    // FORM Integer; SHRRES 12-bit resolution;
    ADCON1H = 0x60;
    // SHRADCS 2; REFCIE disabled; SHREISEL Early interrupt is generated 1 TADCORE clock prior to data being ready; REFERCIE disabled; EIEN disabled;
    ADCON2L = 0x00;
    // CVDCAP enabled; SHRSAMC 0;
    ADCON2H = 0x1C00;
    // SWCTRG disabled; SHRSAMP enabled; SUSPEND disabled; SWLCTRG disabled; SUSPCIE disabled; CNVCHSEL AN0; REFSEL enabled;
    ADCON3L = 0xE200;
    // SHREN enabled; C1EN disabled; C0EN enabled; CLKDIV 2; CLKSEL FOSC/2;
    ADCON3H = (0x181 & 0xFF00); //Disabling C0EN, C1EN, C2EN, C3EN and SHREN bits
    // SAMC0EN disabled; SAMC1EN disabled;
    ADCON4L = 0x00;
    // C0CHS AN0; C1CHS AN1;
    ADCON4H = 0x00;
    // SIGN0 disabled; SIGN4 disabled; SIGN3 disabled; SIGN2 disabled; SIGN1 disabled; SIGN7 disabled; SIGN6 disabled; DIFF0 disabled; SIGN5 disabled; DIFF1 disabled; DIFF2 disabled; DIFF3 disabled; DIFF4 disabled; DIFF5 disabled; DIFF6 disabled; DIFF7 disabled;
    ADMOD0L = 0x00;
    // DIFF15 disabled; DIFF14 disabled; SIGN8 disabled; DIFF13 disabled; SIGN14 disabled; DIFF12 disabled; SIGN15 disabled; DIFF11 disabled; DIFF10 disabled; SIGN9 disabled; DIFF8 disabled; DIFF9 disabled; SIGN10 disabled; SIGN11 disabled; SIGN12 disabled; SIGN13 disabled;
    ADMOD0H = 0x00;
    // DIFF19 disabled; DIFF18 disabled; SIGN20 disabled; DIFF17 disabled; DIFF16 disabled; SIGN16 disabled; SIGN17 disabled; SIGN18 disabled; DIFF20 disabled; SIGN19 disabled;
    ADMOD1L = 0x00;
    // IE15 disabled; IE1 disabled; IE0 enabled; IE3 disabled; IE2 disabled; IE5 disabled; IE4 disabled; IE10 disabled; IE7 disabled; IE6 disabled; IE9 disabled; IE13 disabled; IE8 disabled; IE14 disabled; IE11 disabled; IE12 disabled;
    ADIEL = 0x01;
    // IE17 disabled; IE18 disabled; IE16 disabled; IE19 enabled; IE20 enabled;
    ADIEH = 0x18;
    // CMPEN10 disabled; CMPEN11 disabled; CMPEN6 disabled; CMPEN5 disabled; CMPEN4 disabled; CMPEN3 disabled; CMPEN2 disabled; CMPEN1 disabled; CMPEN0 disabled; CMPEN14 disabled; CMPEN9 disabled; CMPEN15 disabled; CMPEN8 disabled; CMPEN12 disabled; CMPEN7 disabled; CMPEN13 disabled;
    ADCMP0ENL = 0x00;
    // CMPEN10 disabled; CMPEN11 disabled; CMPEN6 disabled; CMPEN5 disabled; CMPEN4 disabled; CMPEN3 disabled; CMPEN2 disabled; CMPEN1 disabled; CMPEN0 disabled; CMPEN14 disabled; CMPEN9 disabled; CMPEN15 disabled; CMPEN8 disabled; CMPEN12 disabled; CMPEN7 disabled; CMPEN13 disabled;
    ADCMP1ENL = 0x00;
    // CMPEN10 disabled; CMPEN11 disabled; CMPEN6 disabled; CMPEN5 disabled; CMPEN4 disabled; CMPEN3 disabled; CMPEN2 disabled; CMPEN1 disabled; CMPEN0 disabled; CMPEN14 disabled; CMPEN9 disabled; CMPEN15 disabled; CMPEN8 disabled; CMPEN12 disabled; CMPEN7 disabled; CMPEN13 disabled;
    ADCMP2ENL = 0x00;
    // CMPEN10 disabled; CMPEN11 disabled; CMPEN6 disabled; CMPEN5 disabled; CMPEN4 disabled; CMPEN3 disabled; CMPEN2 disabled; CMPEN1 disabled; CMPEN0 disabled; CMPEN14 disabled; CMPEN9 disabled; CMPEN15 disabled; CMPEN8 disabled; CMPEN12 disabled; CMPEN7 disabled; CMPEN13 disabled;
    ADCMP3ENL = 0x00;
    // CMPEN20 disabled; CMPEN18 disabled; CMPEN19 disabled; CMPEN16 disabled; CMPEN17 disabled;
    ADCMP0ENH = 0x00;
    // CMPEN20 disabled; CMPEN18 disabled; CMPEN19 disabled; CMPEN16 disabled; CMPEN17 disabled;
    ADCMP1ENH = 0x00;
    // CMPEN20 disabled; CMPEN18 disabled; CMPEN19 disabled; CMPEN16 disabled; CMPEN17 disabled;
    ADCMP2ENH = 0x00;
    // CMPEN20 disabled; CMPEN18 disabled; CMPEN19 disabled; CMPEN16 disabled; CMPEN17 disabled;
    ADCMP3ENH = 0x00;
    // CMPLO 0;
    ADCMP0LO = 0x00;
    // CMPLO 0;
    ADCMP1LO = 0x00;
    // CMPLO 0;
    ADCMP2LO = 0x00;
    // CMPLO 0;
    ADCMP3LO = 0x00;
    // CMPHI 0;
    ADCMP0HI = 0x00;
    // CMPHI 0;
    ADCMP1HI = 0x00;
    // CMPHI 0;
    ADCMP2HI = 0x00;
    // CMPHI 0;
    ADCMP3HI = 0x00;
    // OVRSAM 4x; MODE Oversampling Mode; FLCHSEL AN0; IE disabled; FLEN disabled;
    ADFL0CON = 0x400;
    // OVRSAM 4x; MODE Oversampling Mode; FLCHSEL AN0; IE disabled; FLEN disabled;
    ADFL1CON = 0x400;
    // OVRSAM 4x; MODE Oversampling Mode; FLCHSEL AN0; IE disabled; FLEN disabled;
    ADFL2CON = 0x400;
    // OVRSAM 4x; MODE Oversampling Mode; FLCHSEL AN0; IE disabled; FLEN disabled;
    ADFL3CON = 0x400;
    // HIHI disabled; LOLO disabled; HILO disabled; BTWN disabled; LOHI disabled; CMPEN disabled; IE disabled;
    ADCMP0CON = 0x00;
    // HIHI disabled; LOLO disabled; HILO disabled; BTWN disabled; LOHI disabled; CMPEN disabled; IE disabled;
    ADCMP1CON = 0x00;
    // HIHI disabled; LOLO disabled; HILO disabled; BTWN disabled; LOHI disabled; CMPEN disabled; IE disabled;
    ADCMP2CON = 0x00;
    // HIHI disabled; LOLO disabled; HILO disabled; BTWN disabled; LOHI disabled; CMPEN disabled; IE disabled;
    ADCMP3CON = 0x00;
    // LVLEN9 disabled; LVLEN8 disabled; LVLEN11 disabled; LVLEN7 disabled; LVLEN10 disabled; LVLEN6 disabled; LVLEN13 disabled; LVLEN5 disabled; LVLEN12 disabled; LVLEN4 disabled; LVLEN15 disabled; LVLEN3 disabled; LVLEN14 disabled; LVLEN2 disabled; LVLEN1 disabled; LVLEN0 disabled;
    ADLVLTRGL = 0x00;
    // LVLEN20 disabled; LVLEN17 disabled; LVLEN16 disabled; LVLEN19 disabled; LVLEN18 disabled;
    ADLVLTRGH = 0x00;
    // SAMC 0;
    ADCORE0L = 0x00;
    // SAMC 0;
    ADCORE1L = 0x00;
    // RES 12-bit resolution; EISEL Early interrupt is generated 1 TADCORE clock prior to data being ready; ADCS 2;
    ADCORE0H = 0x300;
    // RES 12-bit resolution; EISEL Early interrupt is generated 1 TADCORE clock prior to data being ready; ADCS 2;
    ADCORE1H = 0x300;
    // EIEN9 disabled; EIEN7 disabled; EIEN8 disabled; EIEN5 disabled; EIEN6 disabled; EIEN3 disabled; EIEN4 disabled; EIEN1 disabled; EIEN2 disabled; EIEN13 disabled; EIEN0 disabled; EIEN12 disabled; EIEN11 disabled; EIEN10 disabled; EIEN15 disabled; EIEN14 disabled;
    ADEIEL = 0x00;
    // EIEN17 disabled; EIEN16 disabled; EIEN19 disabled; EIEN18 disabled; EIEN20 disabled;
    ADEIEH = 0x00;
    // C0CIE enabled; C1CIE enabled; SHRCIE enabled; WARMTIME 32768 Source Clock Periods;
    ADCON5H = (0xF83 & 0xF0FF); //Disabling WARMTIME bit
       
    //Assign Default Callbacks
    ADC1_SetCommonInterruptHandler(&ADC1_CallBack);
    ADC1_Setchannel_AN3InterruptHandler(&ADC1_channel_AN3_CallBack);
    ADC1_Setchannel_AN4InterruptHandler(&ADC1_channel_AN4_CallBack);
    ADC1_Setchannel_AN19InterruptHandler(&ADC1_channel_AN19_CallBack);
    ADC1_Setchannel_AN20InterruptHandler(&ADC1_channel_AN20_CallBack);
    ADC1_Setchannel_AN0InterruptHandler(&ADC1_channel_AN0_CallBack);
   
    // Clearing channel_AN19 interrupt flag.
    IFS6bits.ADCAN19IF = 0;
    // Enabling channel_AN19 interrupt.
    IEC6bits.ADCAN19IE = 1;
    // Clearing channel_AN20 interrupt flag.
    IFS6bits.ADCAN20IF = 0;
    // Enabling channel_AN20 interrupt.
    IEC6bits.ADCAN20IE = 1;
    // Clearing channel_AN0 interrupt flag.
    IFS5bits.ADCAN0IF = 0;
    // Enabling channel_AN0 interrupt.
    IEC5bits.ADCAN0IE = 1;

    // Setting WARMTIME bit
    ADCON5Hbits.WARMTIME = 0xF;
    // Enabling ADC Module
    ADCON1Lbits.ADON = 0x1;
    // Enabling Power for the Shared Core
    ADC1_SharedCorePowerEnable();
    // Enabling Power for Core0
    ADC1_Core0PowerEnable();

    //TRGSRC0 Common Software Trigger; TRGSRC1 None;
    ADTRIG0L = 0x01;
    //TRGSRC3 Common Software Trigger; TRGSRC2 None;
    ADTRIG0H = 0x100;
    //TRGSRC4 Common Software Trigger; TRGSRC5 None;
    ADTRIG1L = 0x01;
    //TRGSRC6 None; TRGSRC7 None;
    ADTRIG1H = 0x00;
    //TRGSRC8 None; TRGSRC9 None;
    ADTRIG2L = 0x00;
    //TRGSRC11 None; TRGSRC10 None;
    ADTRIG2H = 0x00;
    //TRGSRC13 None; TRGSRC12 None;
    ADTRIG3L = 0x00;
    //TRGSRC15 None; TRGSRC14 None;
    ADTRIG3H = 0x00;
    //TRGSRC17 None; TRGSRC16 None;
    ADTRIG4L = 0x00;
    //TRGSRC19 Common Software Trigger; TRGSRC18 None;
    ADTRIG4H = 0x100;
    //TRGSRC20 Common Software Trigger;
    ADTRIG5L = 0x01;
}

使用特权

评论回复
5
ynwa| | 2023-10-8 12:59 | 只看该作者
edison吴 发表于 2023-10-8 11:50
你的代碼我上周已經試過了, 是MCC產生的代碼, 結果也是0, 就是因為這個結果不對, 所以我改成了使用中斷的方 ...

你确定使用while(!ADC1_IsConversionComplete(channel)); 判断到ADC转换完成了吗?如果触发ADC后ADC转换完成,那说明ADC是工作的。结果为0,你再检查一下被采信号输入的硬件连接,还有参考电压的设置。

使用特权

评论回复
6
edison吴|  楼主 | 2023-10-8 16:43 | 只看该作者
我修改了代碼, 使用您的建議重新測試, 不使用ADC中斷的作法, AN0輸入, 電壓是0V及3.3V, 但是結果都是2300~2330左右變化的值, 代碼如下:
  while(1)
    {
      DISC=1;//使用MOS管放電
      d_ms(1);
      DISC=0; //電容充電
      d_ms(1);
      uint32_t conversion,i=0;
        ADC1_Initialize();
        ADC1_Enable();
        channel=channel_AN0;// AN0使用CORE0做ADC輸入腳
        ADC1_ChannelSelect(channel);
        ADC1_SoftwareTriggerEnable();
        //Provide Delay
        for(i=0;i <1000;i++)
        {   }
        ADC1_SoftwareTriggerDisable();
        while(!ADC1_IsConversionComplete(channel));
        conversion = ADC1_ConversionResultGet(channel);//斷點設在這裡, conversion的值永遠都是2000~2300的值, 不管我的AN0接0或是3.3V, 結果都是這樣?我把channel換成其他的輸入腳, 也是這樣, 為什麼?
        ADC1_Disable();
        conversion=0;
    }      

使用特权

评论回复
7
ynwa| | 2023-10-9 13:38 | 只看该作者
edison吴 发表于 2023-10-8 16:43
我修改了代碼, 使用您的建議重新測試, 不使用ADC中斷的作法, AN0輸入, 電壓是0V及3.3V, 但是結果都是2300~2 ...

ADC只需初始化一次即可。
按你的代码,我在自己的dsPIC33CK64MC105上试过了,没有你遇到的现象。
int main(void)
{
    // initialize the device
    SYSTEM_Initialize();

    while (1)
    {
        // Add your application code
        ADC1_Enable();
        ADC1_ChannelSelect(channel_AN9);
        ADC1_SoftwareTriggerEnable();
        //Provide Delay
        for(i=0;i <1000;i++)
        {
        }
        ADC1_SoftwareTriggerDisable();
        while(!ADC1_IsConversionComplete(channel_AN9));
        conversion = ADC1_ConversionResultGet(channel_AN9);
        ADC1_Disable();
    }
    return 1;
}

你直接查看ADCBUF0寄存器里是什么值。

使用特权

评论回复
8
edison吴|  楼主 | 2023-10-9 14:51 | 只看该作者
問題找到了, ADC有轉換, 原因是芯片壞了, 可能我輸入的電壓曾經>5V過, 沒有保護.
我重新更換了新的芯片後, 已經可以轉換了.
但是還有個問ˋ題: 我的ADC有3個輸入, AN0, AN3,AN4
AN0是CORE1, AN3,4是SHARE ADC, AN0已經可以轉換了, 請問我要如何換AN3及AN4? 在MCC的代碼中, 只看到使用channel_AN3, channel_AN4來換, 我試了, 轉換的值不對, 我用電表量電壓是0V, 但是轉換出來的值有2000多, 代碼使用跟您的相同, 也是mcc產生的. 請問哪裡錯了?

使用特权

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

本版积分规则

6

主题

11

帖子

0

粉丝