⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adc2.c

📁 C8051系列单片机开发与C语言编程!
💻 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 + -