请教PIC18F67K22的ADC采集问题

2020-02-06 09:55发布

本帖最后由 fangjikun 于 2017-8-12 17:23 编辑

18f67k22单片机,8M晶振,4路ADC采集一直不正常,不管有没有输入AD值均会在12、25、38、50、76、88、102、、、、等这样来回蹦(不超过200),初始化部分关闭了与引脚复用的其他功能,也来来回回改了很多次AD模块的配置,情况依然没有改变,这个芯片这么难搞吗?哪位用过这个芯片的AD功能?给点建议或提示吧!

电路在最下面
单片机初始化如下:
void Init_MCU(void)
{  
//   unsigned char i;   
        OSCCON = 0x00;//系统时钟选择位,默认主振荡器,由FOSC<3:0>配置位CONFIG1H<3:0>定义。
        TRISA = 0x8c;
        TRISB = 0xe0;
        TRISC = 0xbc;//
        TRISD = 0x00;//
        TRISE = 0x00;//  
        TRISF = 0x32;// 无F0
        TRISG = 0x0c;// 无G7 G6
        asm("nop");
        asm("nop");
        ANCON0 = 0;//清零AN7-AN0
        ANCON1 = 0x06;//An10-HA  An9-HB
        ANCON2 = 0x06;//An18-TA  An17-TB


//以下是关闭与端口复用的其他功能
        TXSTA1 = 0;
        TXSTA2 = 0;
        RCSTA1 = 0;
        RCSTA2 = 0;
//        RCSTA2bits.SPEN = 0;//串口2关闭
//        TXSTA2bits.SYNC = 0;//异步模式
//        RCSTA2bits.CREN = 0;//禁止接收器
//        TXSTA2bits.TXEN = 0;//禁止发送
//        SSPEN = 0;
        CVRCON = 0;//关比较器参考电压
        RBPU = 1;//:PORTB上拉使能位  1 = 禁止所有PORTB上拉 0=按各个TRIS寄存器值使能PORTB上拉
        CTMUEN = 0;//禁止CTMU模块               
        CCP1CON = 0;//关捕捉/比较/PWM(CCP)模块
        CCP2CON = 0;
        CCP3CON = 0;
        CCP4CON = 0;
        CCP5CON = 0;
        CCP6CON = 0;
        CCP7CON = 0;
        CCP8CON = 0;
        CCP9CON = 0;
        CCP10CON = 0;   
        CM1CON = 0;//关比较器       
        CM2CON = 0;       
        CM3CON = 0;        
       
                     
        GIE = 0;//关     //允许所有未屏蔽的中断
        PEIE = 0;//关     //允许所有未屏蔽的外设中断

        TMR0ON = 0;//off T0
       
        K_Out_En =0;// LATGbits.LATG1 //595继电器输出允许 1禁止 0允许
       
}

以下是ADC部分程序,主函数调用RMS_Operation


#include <p18cxxx.h>
#include "Public.h"
#include "adc.h"  
#include "lcd12864.h"  

#define  BLOCK_LENGTH 10 //每路取10次

void InitAdc1(void);//初始化ADC
void RMS_Operation(void);//有效值运算
unsigned int RMS_Operation_SubFunction(unsigned int *p,unsigned char i);

unsigned int TA_ADCBuff[BLOCK_LENGTH];
unsigned int TB_ADCBuff[BLOCK_LENGTH];
unsigned int HA_ADCBuff[BLOCK_LENGTH];
unsigned int HB_ADCBuff[BLOCK_LENGTH];//暂存12位AD结果  

unsigned int TA,TB,RHA,RHB;
   
unsigned char SampleCounter;//BLOCK_LENGTH个数据计数变量
unsigned char ConduitCounter;//通道计数器
unsigned char ConduitNum[4]={18,17,10,9};//Ta Tb Ha Hb
const unsigned int T_ADC[]={
                                          94 ,100 ,106 ,113 ,119 ,127 ,134 ,142 ,151 ,160 ,
                                          169 ,179 ,189 ,200 ,211 ,223 ,235 ,248 ,261 ,275 ,
                                          289 ,304 ,319 ,336 ,352 ,370 ,388 ,407 ,426 ,446 ,
                                          467 ,489 ,511 ,534 ,558 ,582 ,607 ,633 ,659 ,687 ,
                                          714 ,743 ,772 ,802 ,833 ,864 ,896 ,929 ,962 ,995 ,
                                          1030,1064 ,1100 ,1135 ,1171 ,1208 ,1245 ,1282 ,1320 ,1358 ,
                                          1396 ,1435 ,1474 ,1513 ,1552 ,1591 ,1630 ,1668 ,1707 ,1746 ,
                                          1785 ,1824 ,1863 ,1902 ,1941 ,1980 ,2018 ,2056 ,2094 ,2132 ,
                                          2169 ,2205 ,2242 ,2278 ,2313 ,2348 ,2384 ,2419 ,2453 ,2486 ,
                                          2519 ,2551 ,2582 ,2612 ,2642 ,2670 ,2701 ,2731 ,2761 ,2789 ,
                                          2816 ,2843 ,2868 ,2893 ,2917 ,2940 ,2964 ,2987 ,3010 ,3032
};

void InitAdc1(void)
{
        SampleCounter = 0;;//BLOCK_LENGTH个数量计数器
        ConduitCounter = 0;;//4个通道计数器
//        ADIE = 0;
       
          ADCON1bits.VCFG = 0;//ADCON1 A/D VREF+参考vdd
          ADCON1bits.VNCFG = 0;//ADCON1 A/D VREF-参考vss
          ADCON1bits.CHSN = 0;//ADCON1 模拟负通道vss
        ADCON0bits.CHS =  ConduitNum[ConduitCounter] ;//模拟正通道={18,17,10,9};//Ta Tb Ha Hb
        ADCON2bits.ADFM = 0;//AD结果左对齐
        ADCON2bits.ACQT = 1;//采集时间2tad=8US
        ADCON2bits.ADCS = 2;//采集时钟FOSC/32 = 250000HZ(4us )
        asm("nop");
        ADCON0bits.ADON = 1;
        asm("nop");
}

void RMS_Operation(void)
{  
          
                ADCON0bits.GODONE = 0;
                asm("nop");
                asm("nop");
                ADCON0bits.GODONE = 1;
                while(ADCON0bits.GODONE){asm("nop");}
                asm("nop");
                asm("nop");
                switch(ConduitCounter)
                                 {case 0://Ta
                                          TA_ADCBuff[SampleCounter] = ADRESH<<4 + ADRESL>>4;break;
                                  case 1://Tb
                                          TB_ADCBuff[SampleCounter] = ADRESH<<4 + ADRESL>>4;break;
                                  case 2://Ha
                                          HA_ADCBuff[SampleCounter] = ADRESH<<4 + ADRESL>>4;break;
                                  case 3://Hb
                                          HB_ADCBuff[SampleCounter] = ADRESH<<4 + ADRESL>>4;break;                  
                                  }        
                SampleCounter += 1;//通道内次数+1
                if(SampleCounter >= BLOCK_LENGTH)//通道采集BLOCK_LENGTH次
                        {SampleCounter = 0;
                         switch(ConduitCounter)
                                 {case 0://Ta
                                          TA  = RMS_Operation_SubFunction(TA_ADCBuff,1);break;
                                  case 1://Tb
                                          TB  = RMS_Operation_SubFunction(TB_ADCBuff,2);break;
                                  case 2://Ha
                                          RHA  = RMS_Operation_SubFunction(HA_ADCBuff,3);break;
                                  case 3://Hb
                                          RHB  = RMS_Operation_SubFunction(HB_ADCBuff,4);break;                          
                                  }
                          ConduitCounter += 1;//通道计数器//换下一通道
                          if(ConduitCounter >= 4){ConduitCounter = 0;}//共4通道
                          ADCON0bits.CHS = ConduitNum[ConduitCounter];//={18,17,10,9};//Ta Tb Ha Hb  
                         }
       
}

  
unsigned int RMS_Operation_SubFunction(unsigned int *p,unsigned char j)//ADC数据 1电流1 ... 5温度
{
       
        unsigned int i,count,Data;  
        Data = 0;
        sum=0;
        for(count = 0;count<BLOCK_LENGTH;count++){sum += *p++;}                  
        Data = sum/10;
           return Data;
}   









友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
vipcff
1楼-- · 2020-02-06 14:46
 精彩回答 2  元偷偷看……
砂山老妖
2楼-- · 2020-02-06 17:30
ADRESH<<4 + ADRESL>>4,为什么不用右对齐?为什么不用ADRES?
fangjikun
3楼-- · 2020-02-06 17:35
vipcff 发表于 2017-8-12 19:02
建议来了   先采集一路试试? 固定到地或者Vdd 试试?   你怎么看数据的?串口?串口本身运行正常吗?  ad ...

您好,采样一路也试过,情况是一样的,AD输入脚短接到VSS或VDD采集的数据没变化;数据是在屏幕上显示的,电路上有12864屏;数据左偏和右偏都试了(也去掉符号位了),
唉、、、、、我想应该是我程序哪里不对,现在还是没找到问题所在
fangjikun
4楼-- · 2020-02-06 17:59
砂山老妖 发表于 2017-8-13 05:03
ADRESH4,为什么不用右对齐?为什么不用ADRES?

一开始用的右对齐,数据不对换成左对齐的,
ADRES没用过,一次可以读出两个八位?明天到公司试试,板子昨天没带回家
砂山老妖
5楼-- · 2020-02-06 22:00
用《4时,先强制unsigned int一下,编译器又是挺变态的
n0831
6楼-- · 2020-02-07 01:01
 精彩回答 2  元偷偷看……

一周热门 更多>