///差动输入,定期启动T2定时/6,7通道ADC0差动转换通道,第六通道为P3.6,第7通道为P.7dif_input.c///#include "lcd.h"///作者写的LCD具体见显示头文件LCD章节/*若读者没有条件使用"lcd.h"每个显示和键盘函数,则可在lcd.h文件中的定义如下:#include "c8051f040.h"void dispini();void showf();*///可编译调试文件,用户也可调试,通过设置点观察数据#define ADC0START temppage=SFRPAGE;SFRPAGE=0x00;AD0BUSY=1;SFRPAGE=temppage#define REAL_RATE 989L#define ADJRATEDIF 237L#define ADJRATESE 118L/*REAL_RATE物理量转化系数,由具体对象决定ADJRATEDIF在差动模式下,增益为0.5时ADC0转换值和真实电压的转换系数ADJRATESE在单端输入模式下,增益为0.5时ADC0转换值和真实电压的转换系数*/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;//将ADC0H-ADC0L通过sfr16实现sfr16 ADC0GT=0xc4;sfr16 ADC0LT=0xc6;uchar temppage;bit isnewdata;int kk;long target_val;///工程量转化值long realvol;///真实测量电压值float temp;void adc0_mux(uchar type,uchar source);void adc0_source(uchar source);void p3anolog_ini(uchar port);void HVDA_ini(uchar gaind);void adc0_ini();void config();void t2_ini();void t2_baud(uint t2reload);void t2_ini(){SFRPAGE = 0x00;TMR2CF = 0x08; // T2时钟是系统时钟,计数方向为增值计数TMR2CN = 0x04; // T2为16bit定时器模式,启动定时器运行}void t2_baud(uint t2reload){//每隔t2reload个T2时钟,定期溢出SFRPAGE = 0x00;RCAP2=~t2reload 1./相当于65536-t2reloadTMR2=RCAP2;}void adc0_mux(uchar type,uchar source){//type 配置测量方法是差动还是单端输入///source 为ADC0通道选择(共9个通道)SFRPAGE=0x00;AMX0CF=type;AMX0SL=source;}void adc0_source(uchar source){//ADC0通道选择,为adc0_mux()简化函数SFRPAGE=0x00;AMX0SL=source;}void p3anolog_ini(uchar port){//配置p三口模拟输入管脚SFRPAGE=0x00;AMX0PRT=port;SFRPAGE=0x0f;P3MDIN&=~port;///将相应的管脚配置成模拟输入口}void HVDA_ini(uchar gaind){/*配置高压差动放大器,调的只是第二级的增益,整体增益还需再乘以0.05;*///HVDA禁止时,HCAP+上检测到的是HVAIN+的电压SFRPAGE=0x00;HVA0CN=gaind;}void adc0_ini(){SFRPAGE=0x00;ADC0CF=0x0f;//ADC0时钟为系统时钟2分频,PGA增益为0.5ADC0CN=0x8c;//AD0TM=0,ADC0是连续跟踪模式T2溢出率启动ADC0//AD0LJST=0.数据存储格式右对齐,即ADC0H存放12bit高四位REF0CN&=0x0f;//AD0VRS=0,ADC0参考电压为VREFAREF0CN|=0x07;//TEMPE=1.内部温度传感器工作///BIASE=1.偏移产生器工作/*REFBE=1.电路部分必须参考内部电平工作VREF参考输出(C8051F第12管脚40)与VREF0(C8051F04016管脚相连,并且最好并联一个4.7uF和0.1uF旁路电容采用电平滤波器*/p3anolog_ini(0xc0);//将P3.6和P3.7配置到AMUX 6、7通道上adc0_mux(0x08,6);//PORT3IC=1,ADC0 6.7通道为差动模式///HVDA2C=0,4.5通道为单端模式///AIN0.0-AIN0.3为单端模式//选6,7通道为ADC0差动转换通道,注意不要选择7,7不能选择差动通道EIE2 |= 0x02; //开ADC0中断t2_ini();t2_baud(20000)T2时产生一次ADC0采样SFRPAGE=0x00;TR2=1;}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口为开漏,也可推挽 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();//LCD初始化,具体见LCD章节部分adc0_ini();//ADC0初始化EA=1;i=0;realvol=0;while(1){if(isnewdata){i ;if(i>30){///每采样30次,显示刷新一次i=0.//如果读者没有条件使用它lcd.h,此设置断点可查看realvol和target_val的值showf(realvol,5,0);showf(target_val,6,1);}isnewdata=0;}}}void ADC0_ISR() interrupt 15{SFRPAGE=0x00;AD0INT=0;kk=ADC0VAL;realvol=(long)kk*ADJRATEDIF;/*ADC转换值乘以差动电平系数,结果是电平真实值乘以10000ADC0VAL=64512时,即kk=-1024,则realvol=-1024*237=-242688,即表示真实电压为-2.42688v */target_val=(long)kk*REAL_RATE;/*ADC0转换值乘以物理量转换系数,例如,某速度传感器的输出为0-2.4V,其量程为-1m/s至1m/s,传感器提供1.2V参考电平输出将是1.2V接入P3.7.接收传感器输出P3.6.构成差动测量模式target_val物理量值乘以100000ADC0VAL=65136时,即kk=-400,target_val=-400*989=-395600意味着真实物理量为-0.3956m/s*/isnewdata=1;}