请教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;
}
建议来了 先采集一路试试? 固定到地或者Vdd 试试? 你怎么看数据的?串口?串口本身运行正常吗?ad值寄存器好像由2个寄存器构成,左偏或者右偏对了吗? ADRESH<<4 + ADRESL>>4,为什么不用右对齐?为什么不用ADRES? vipcff 发表于 2017-8-12 19:02
建议来了 先采集一路试试? 固定到地或者Vdd 试试? 你怎么看数据的?串口?串口本身运行正常吗?ad ...
您好,采样一路也试过,情况是一样的,AD输入脚短接到VSS或VDD采集的数据没变化;数据是在屏幕上显示的,电路上有12864屏;数据左偏和右偏都试了(也去掉符号位了),
唉、、、、、我想应该是我程序哪里不对,现在还是没找到问题所在 砂山老妖 发表于 2017-8-13 05:03
ADRESH4,为什么不用右对齐?为什么不用ADRES?
一开始用的右对齐,数据不对换成左对齐的,
ADRES没用过,一次可以读出两个八位?明天到公司试试,板子昨天没带回家 用《4时,先强制unsigned int一下,编译器又是挺变态的 ADRESH<<4 + ADRESL>>4这句是有问题的,具体请查看运算符优先级,C功底不扎实。 两边需要加括号! n0831 发表于 2017-8-13 16:45
ADRESH4这句是有问题的,具体请查看运算符优先级,C功底不扎实。
还真是,+ - 优先于<<>>,很多细节输在“我以为”! 问题出在这,解决的路上想了很多烂招,总结为粗心不细致!
页:
[1]