搜索
bottom↓
回复: 9

请教PIC18F67K22的ADC采集问题

[复制链接]

出0入0汤圆

发表于 2017-8-12 17:21:03 | 显示全部楼层 |阅读模式
本帖最后由 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;
}   









本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2017-8-12 19:02:21 来自手机 | 显示全部楼层
建议来了   先采集一路试试? 固定到地或者Vdd 试试?   你怎么看数据的?串口?串口本身运行正常吗?  ad值寄存器好像由2个寄存器构成,左偏或者右偏对了吗?

出0入0汤圆

发表于 2017-8-13 05:03:33 来自手机 | 显示全部楼层
ADRESH<<4 + ADRESL>>4,为什么不用右对齐?为什么不用ADRES?

出0入0汤圆

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

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

出0入0汤圆

 楼主| 发表于 2017-8-13 15:15:02 | 显示全部楼层
砂山老妖 发表于 2017-8-13 05:03
ADRESH4,为什么不用右对齐?为什么不用ADRES?

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

出0入0汤圆

发表于 2017-8-13 16:35:27 来自手机 | 显示全部楼层
用《4时,先强制unsigned int一下,编译器又是挺变态的

出0入42汤圆

发表于 2017-8-13 16:45:56 来自手机 | 显示全部楼层
ADRESH<<4 + ADRESL>>4这句是有问题的,具体请查看运算符优先级,C功底不扎实。

出0入42汤圆

发表于 2017-8-13 16:46:42 来自手机 | 显示全部楼层
两边需要加括号!

出0入0汤圆

 楼主| 发表于 2017-8-13 20:49:57 | 显示全部楼层
n0831 发表于 2017-8-13 16:45
ADRESH4这句是有问题的,具体请查看运算符优先级,C功底不扎实。

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

出0入0汤圆

 楼主| 发表于 2017-8-14 11:26:18 | 显示全部楼层
问题出在这,解决的路上想了很多烂招,总结为粗心不细致!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 07:51

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表