fangjikun 发表于 2017-8-12 17:21:03

请教PIC18F67K22的ADC采集问题

本帖最后由 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-HAAn9-HB
        ANCON2 = 0x06;//An18-TAAn17-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"

#defineBLOCK_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;
unsigned int TB_ADCBuff;
unsigned int HA_ADCBuff;
unsigned int HB_ADCBuff;//暂存12位AD结果

unsigned int TA,TB,RHA,RHB;
   
unsigned char SampleCounter;//BLOCK_LENGTH个数据计数变量
unsigned char ConduitCounter;//通道计数器
unsigned char ConduitNum={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 ;//模拟正通道={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 = ADRESH<<4 + ADRESL>>4;break;
                              case 1://Tb
                                      TB_ADCBuff = ADRESH<<4 + ADRESL>>4;break;
                              case 2://Ha
                                      HA_ADCBuff = ADRESH<<4 + ADRESL>>4;break;
                              case 3://Hb
                                      HB_ADCBuff = 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;//={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;
}   









vipcff 发表于 2017-8-12 19:02:21

建议来了   先采集一路试试? 固定到地或者Vdd 试试?   你怎么看数据的?串口?串口本身运行正常吗?ad值寄存器好像由2个寄存器构成,左偏或者右偏对了吗?

砂山老妖 发表于 2017-8-13 05:03:33

ADRESH<<4 + ADRESL>>4,为什么不用右对齐?为什么不用ADRES?

fangjikun 发表于 2017-8-13 15:12:20

vipcff 发表于 2017-8-12 19:02
建议来了   先采集一路试试? 固定到地或者Vdd 试试?   你怎么看数据的?串口?串口本身运行正常吗?ad ...

您好,采样一路也试过,情况是一样的,AD输入脚短接到VSS或VDD采集的数据没变化;数据是在屏幕上显示的,电路上有12864屏;数据左偏和右偏都试了(也去掉符号位了),
唉、、、、、我想应该是我程序哪里不对,现在还是没找到问题所在

fangjikun 发表于 2017-8-13 15:15:02

砂山老妖 发表于 2017-8-13 05:03
ADRESH4,为什么不用右对齐?为什么不用ADRES?

一开始用的右对齐,数据不对换成左对齐的,
ADRES没用过,一次可以读出两个八位?明天到公司试试,板子昨天没带回家

砂山老妖 发表于 2017-8-13 16:35:27

用《4时,先强制unsigned int一下,编译器又是挺变态的

n0831 发表于 2017-8-13 16:45:56

ADRESH<<4 + ADRESL>>4这句是有问题的,具体请查看运算符优先级,C功底不扎实。

n0831 发表于 2017-8-13 16:46:42

两边需要加括号!

fangjikun 发表于 2017-8-13 20:49:57

n0831 发表于 2017-8-13 16:45
ADRESH4这句是有问题的,具体请查看运算符优先级,C功底不扎实。

还真是,+ - 优先于<<>>,很多细节输在“我以为”!

fangjikun 发表于 2017-8-14 11:26:18

问题出在这,解决的路上想了很多烂招,总结为粗心不细致!
页: [1]
查看完整版本: 请教PIC18F67K22的ADC采集问题