21ic问答首页 - 芯片是dsPIC33CK32MP105, 我的ADC轉換結果永遠是0? 請問哪裡錯了?
芯片是dsPIC33CK32MP105, 我的ADC轉換結果永遠是0? 請問哪裡錯了?
edison吴2023-10-07
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;
}
如提, 芯片是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;
}
赞0
我重新更換了新的芯片後, 已經可以轉換了.
但是還有個問ˋ題: 我的ADC有3個輸入, AN0, AN3,AN4
AN0是CORE1, AN3,4是SHARE ADC, AN0已經可以轉換了, 請問我要如何換AN3及AN4? 在MCC的代碼中, 只看到使用channel_AN3, channel_AN4來換, 我試了, 轉換的值不對, 我用電表量電壓是0V, 但是轉換出來的值有2000多, 代碼使用跟您的相同, 也是mcc產生的. 請問哪裡錯了?
评论
2023-10-09
赞0
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寄存器里是什么值。
评论
2023-10-09
赞0
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;
}
评论
2023-10-08
赞0
你确定使用while(!ADC1_IsConversionComplete(channel)); 判断到ADC转换完成了吗?如果触发ADC后ADC转换完成,那说明ADC是工作的。结果为0,你再检查一下被采信号输入的硬件连接,还有参考电压的设置。
评论
2023-10-08
赞0
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;
}
评论
2023-10-08
赞0
void ADC0_ENABLE(void)
{
IEC5bits.ADCAN0IE = 1;
IFS5bits.ADCAN0IF = 1;
}
评论
2023-10-08
赞0
你是选择用什么触发源来启动ADC采样转换的?如果是软件触发,没有看到你软件设置触发位的语句。如果是其他外设触发,请确认作为触发源的外设是否产生触发条件来触发ADC。
按你说的情况,个人判断应该不会产生ADC中断。你说能进ADC中断,但读结果都是0,这点从逻辑上解释不通。
一般用软件触发ACD的操作流程如下,你可以先用简单的查询法测试一下。
ADC1_Initialize();
ADC1_Enable();
ADC1_ChannelSelect(channel);
ADC1_SoftwareTriggerEnable();
while(!ADC1_IsConversionComplete(channel));
conversion = ADC1_ConversionResultGet(channel);
评论
2023-10-08
您需要登录后才可以回复 登录 | 注册