[PIC32/SAM] 关于pic30f4011的adc单通道多模拟输入

[复制链接]
 楼主| 两只袜子 发表于 2025-2-19 16:00 | 显示全部楼层 |阅读模式
最近需要用到4011自带的adc,然后再官方例程的基础上将程序进行修改,想实现用通道0来处理3个模拟输入,现在的问题是当执行到第三个转换的时候直接又从for语句重新开始。并没有产生中断,转换也没有完成。程序挺简单的,但是不知道哪里没有改好,希望大神帮忙看一下。谢谢下面贴上我的代码



#include

_FOSC(CSW_FSCM_OFF&XT_PLL4);//4分频

_FWDT(WDT_OFF);


_FBORPOR(PBOR_OFF&MCLR_EN);
_FGS(CODE_PROT_OFF);

#define Fcy 73728

void delay(unsigned int z)
{
        unsigned int x,y,t;
        for(x=z;x>0;x--)
          for(y=300;y>0;y--);

}

void ConfigAdc()//只转换一个通道,不仅要选择通道还要设置通道的输入类型(配置只需要配置这6个方面即可)
{
  ADCON1=0x0004;//关闭adc,数据输出的是整数,采用时钟计数,每次转换完成后继续自动采样,转换未完成,按顺序采集多个输入
  ADCON2=0x0408;//选择通道CH0,只是用这一个通道,每完成3个转换完成后产生中断其余的置零
  ADCON3=0x1fbf;//采集时间是31TAD,TAD=31Tcy,使用rc时钟
  ADCHS=0x0000;//选择通道CH0
  ADPCFG=0xfff8;//选择RN0,RN1,RN2的输入模式为模拟输入其余的为数字输入
  ADCSSL=0x0007;//对an0,an1,an2输入进行扫描
  IEC0bits.ADIE=1;//给adc后的中断使能
  IPC2bits.ADIP=7;//给adc的中断设置优先级
  IFS0bits.ADIF=0;
}


//这里需要初始化一下lcd;
void _ISR _AdcInterrupt(void)
{
  IFS0bits.ADIF=0;//清除flag即可
}


int main(void)
{
  unsigned int T,I,U,cnt;
  ConfigAdc();
  ADCON1bits.ADON=1;
  TRISB=1;
  while(1)
{
  while(!ADCON1bits.SAMP);//确定第一个信号已经采集好了
        for(cnt=0;cnt<3;cnt++)
    {
     while(!ADCON1bits.SAMP);//为了确定第二个第三个信号采集完成
     ADCON1bits.SAMP=0;//开始转换
     delay(100);//等待转换完成   
    }

    while(!ADCON1bits.DONE);//三次循环后判断一次ad转换完成
    T=ADCBUF0;
    U=ADCBUF1;

}
}
幸福小强 发表于 2025-2-21 15:46 | 显示全部楼层
调整ADCON2的设置,确保在三个转换后触发中断。
在中断服务程序中读取所有三个ADCBUF,并处理数据。
主循环中只需启动一次采样,然后等待中断,而不是循环三次。
检查ADC时钟配置是否足够,确保转换时间足够。
幸福小强 发表于 2025-2-21 15:47 | 显示全部楼层
  1. // ADC配置修正
  2. void ConfigAdc() {
  3.     ADCON1 = 0x0004;      // 12-bit整数格式,禁止自动转换
  4.     ADCON2 = 0x0418;      // 扫描模式,3次转换后中断(SMPI=3)
  5.     ADCON3 = 0x1FBF;      // 31TAD采样时间,RC时钟
  6.     ADCHS = 0x0000;       // CH0作为主通道
  7.     ADPCFG = 0xFFF8;      // AN0-2模拟输入
  8.     ADCSSL = 0x0007;      // 扫描AN0-AN2
  9.     // 中断配置
  10.     IFS0bits.ADIF = 0;
  11.     IEC0bits.ADIE = 1;
  12.     IPC2bits.ADIP = 7;
  13. }

  14. volatile unsigned int adc_results;
  15. volatile uint8_t conv_complete = 0;

  16. // 中断服务程序优化
  17. void __attribute__((__interrupt__)) _AdcInterrupt(void) {
  18.     if(ADCON1bits.DONE) {
  19.         adc_results = ADCBUF0;  // 读取AN0结果
  20.         adc_results = ADCBUF1;  // 读取AN1结果
  21.         adc_results = ADCBUF2;  // 读取AN2结果
  22.         conv_complete = 1;         // 置位完成标志
  23.         ADCON1bits.DONE = 0;       // 清除完成标志
  24.     }
  25.     IFS0bits.ADIF = 0;             // 清除中断标志
  26. }

  27. // 主程序逻辑优化
  28. int main(void) {
  29.     ConfigAdc();
  30.     ADCON1bits.ADON = 1;          // 开启ADC
  31.     TRISB = 0x0007;               // RB0-2为输入
  32.    
  33.     while(1) {
  34.         ADCON1bits.SAMP = 1;      // 启动自动采样
  35.         while(!conv_complete);    // 等待转换完成
  36.         conv_complete = 0;        // 清除标志
  37.         
  38.         // 使用adc_results数组中的数据
  39.         unsigned int T = adc_results;
  40.         unsigned int I = adc_results;
  41.         unsigned int U = adc_results;
  42.         
  43.         // 数据处理代码...
  44.     }
  45. }
huahuagg 发表于 2025-2-21 17:54 | 显示全部楼层
单通道,多模拟?
是多路吗?
慢醇 发表于 2025-2-23 00:03 | 显示全部楼层
配置支持连续扫描多个通道的转换?
远芳侵古道 发表于 2025-2-23 06:02 | 显示全部楼层
问题可能出在 ADC 配置 或 中断处理 上。
小明的同学 发表于 2025-2-23 10:28 | 显示全部楼层
不知道这个系列的要不要有配置字这个概念。
dongnanxibei 发表于 2025-2-23 13:13 | 显示全部楼层
多路?一个通道可以用多个IO分时?
jiekou001 发表于 2025-2-26 15:30 | 显示全部楼层
这个芯片好配置吗?
wahahaheihei 发表于 2025-2-26 19:28 | 显示全部楼层
这个型号分辨率是多少,多少通道?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2122

主题

8117

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部