📄 adc2.c
字号:
/////////ADC2调试程序,p1.2口单端输入/////////////////
/////////T2定时采样,ADC2监控中断/////////////////////
/////////ADC2.c////////////////////////////////////////
#include "lcd.h"
#define ADC0START temppage=SFRPAGE;SFRPAGE=0x00;AD0BUSY=1;SFRPAGE=temppage
#define ADJRATEDIF 260L
#define ADJRATESE 130L
sfr16 RCAP2=0xca;
sfr16 RCAP3=0xca;
sfr16 RCAP4=0xca;
sfr16 TMR4=0xcc;
sfr16 TMR3=0xcc;
sfr16 TMR2=0xcc;
sfr16 PCA0CP0=0xfb;
sfr16 PCA0CP1=0xfd;
sfr16 PCA0CP2=0xe9;
sfr16 PCA0CP3=0xeb;
sfr16 PCA0CP4=0xed;
sfr16 PCA0CP5=0xe1;
sfr16 ADC0VAL=0xbe;
sfr16 ADC0GT=0xc4;
sfr16 ADC0LT=0xc6;
uchar temppage;
bit isnewdata;
bit adc_is_capture;
uchar kk;
long realvol;
void adc2_mux(uchar type,uchar source);
void adc2_source(uchar source);
void anologPort_ini(uchar port);
void adc2_ini();
void config();
void t2_ini();
void t2_baud(uint t2reload);
void t2_ini(){
SFRPAGE = 0x00;
TMR2CF = 0x08; // T2时钟为系统时钟
TMR2CN = 0x04; // 开启T2定时器
}
void t2_baud(uint t2reload){
SFRPAGE = 0x00;
RCAP2=~t2reload+1;
TMR2=RCAP2;
}
void adc2_mux(uchar type,uchar source){//type 配置测量方式为差动还是单端输入
//source 为ADC2通道选择(共有8个通道)
SFRPAGE=0x02;
AMX2CF=type;
AMX2SL=source;
}
void adc2_source(uchar source){//ADC2通道选择
SFRPAGE=0x02;
AMX2SL=source;
}
void anologPort_ini(uchar port){//配置p1口模拟输入管脚
SFRPAGE=0x0f;
P1MDIN&=~port;//将相应管脚配置成模拟输入口
}
void adc2_ini(){
SFRPAGE=0x02;
ADC2CF=0x09;//ADC2时钟为系统时钟2分频,PGA增益为1
ADC2CN=0x86;//AD2TM=0,ADC2为连续跟踪模式由T2溢出率启动ADC2
SFRPAGE=0x00;
REF0CN|=0x0b;//采用AV+作为参考电压
/*BIASE=1,偏移产生器工作,注意若AD启动此位必须置1,不管是否采用内部参考电平
REFBE=1,内部参考电平工作,电路部分须将VREF参考输出(C8051F40的第12管脚)与
VREF2(C8051F040的17管脚)相连,并最好并联一个4.7uF和0.1uF的旁路电容以电平滤波*/
anologPort_ini(0x0f);//将P1.0-P1.3配置到AMUX2 0-3通道上,pdf文件上p2是错误的。
adc2_mux(0x01,2);
/* 0,1通道为差动输入模式,其他为单端输入模式,选择2通道单端输入进入AD转化*/
EIE2|= 0x08; //开ADC2中断
t2_ini();
t2_baud(6000);//设置6000个T2时钟为采样周期
SFRPAGE=0x00;
TR2=1;
}
void adc2_capture(uchar greater,uchar less){
SFRPAGE=0x02;
ADC2GT=greater;
ADC2LT=less;
AD2WINT=0;
EIE2|=0x10;
}
void config (void) {
//看门狗禁止
WDTCN = 0x07;
WDTCN = 0xDE;
WDTCN = 0xAD;
SFRPAGE = 0x0F;
XBR0 = 0x00;
XBR1 = 0x00;
XBR2 = 0x40; //交叉开关使能,使得P0-P3口能输出
XBR3 = 0x00;
SFRPAGE = 0x0F;
P0MDOUT = 0x00; //端口配置,P0-P3,P6-P7口为开漏输出
P1MDOUT = 0x00;
P2MDOUT = 0x00;
P3MDOUT = 0x00;
P4MDOUT = 0x00; //P4口为开漏,若为推挽式则无法读取LCD数据
P5MDOUT = 0x07;
P6MDOUT = 0x00;
P7MDOUT = 0x00;
P1MDIN = 0xFF; //所有端口为数字输入,没有模拟输入端口
P2MDIN = 0xFF;
P3MDIN = 0xFF;
SFRPAGE = 0x0F;
CLKSEL = 0x00;
OSCXCN = 0x00;
OSCICN = 0x84;
//采用内部晶振,为24.5MHZ8分频
}
void main(){
uchar i;
config();
dispini();
adc2_ini();
i=0;
kk=0;
isnewdata=0;
adc_is_capture=0;
adc2_capture(64,128);//当电压在0.83-1.65之内发生ADC2中断
EA=1;
while(1){
if(isnewdata){
i++;
if(i>40){
i=0;
showline("AIN1.2 VAL",0);
showf(realvol,4,1);
}
isnewdata=0;
}
if(adc_is_capture){ //ADC2监控条件测试
adc_is_capture=0;
showline("ADC2 CAPTURE",0);
showf(realvol,4,1);
delay1ms(100);
EIE2|=0x10;//开ADC2监控中断
}
}
}
void ADC2_WIN_ISR() interrupt 17{//ADC2监控中断程序
//只要ADC转化值在此监视范围内,则一直处于此中断
adc_is_capture=1;
SFRPAGE=0x02;
AD2WINT=0;
EIE2&=~0x10;//关ADC2监控中断
/*
注意c8051f040.h头文件定义错误
原定义为:
sbit AD2WINT = ADC2CN ^ 3;
sbit AD2CM2 = ADC2CN ^ 2;
sbit AD2CM1 = ADC2CN ^ 1;
sbit AD2CM0 = ADC2CN ^ 0;
改为:
sbit AD2WINT = ADC2CN ^ 0;
sbit AD2CM2 = ADC2CN ^ 3;
sbit AD2CM1 = ADC2CN ^ 2;
sbit AD2CM0 = ADC2CN ^ 1;
*/
}
void ADC2_ISR() interrupt 18{//ADC2转化完毕中断程序
AD2INT=0;
kk=ADC2;
realvol=(long)kk;
realvol*=ADJRATESE;//realvol为真实电压值的1.0e4倍
isnewdata=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -