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

📄 adc0_temp_pro.c

📁 C8051系列单片机开发与C语言编程!
💻 C
字号:
//内部温度传感器调试程序//
//利用过采样实现16位精度//
//ADC0_TEMP_PRO.c
#include <C8051F040.h>
#define ADC0START temppage=SFRPAGE;SFRPAGE=0x00;AD0BUSY=1;SFRPAGE=temppage
#define STACK_LEN 128
//采样128次,再将128个数据总和除以8
//处理后的数据相当于16个原始数据之和,在数值表现形式上为16bit
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long ulong;
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 canread;
uint kk;
float temp;
xdata uchar stack_index;
xdata ulong total;
xdata float t[20],t12[20];//存放温度检测数据,为20个数据
xdata uint ad16[20],ad12[20];
xdata uint mystack[STACK_LEN];//过采样数据数组
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 delay1ms(uint time);
void config();
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){//配置p3口模拟输入管脚
	SFRPAGE=0x00;
	AMX0PRT=port;
	SFRPAGE=0x0f;
	P3MDIN&=~port;//将相应管脚配置成模拟输入口
}
void HVDA_ini(uchar gaind){//高压差动放大器配置
	SFRPAGE=0x00;
	HVA0CN=gaind;
}
void adc0_ini(){
	SFRPAGE=0x00;
	ADC0CF=0x80;//ADC0时钟为系统时钟17分频,PGA增益为1
	ADC0CN=0x80;
	/*AD0EN=1,ADC0模块使能
	AD0TM=0,ADC0为连续跟踪模式
	AD0CM1:AD0CM0=00b,为AD0BUSY启动方式
	AD0LJST=0,数据存储格式右对齐,即ADC0H存放12bit高四位*/
	REF0CN&=0x0f;//AD0VRS=0,ADC0参考电压为VREFA
	REF0CN|=0x07;//TEMPE=1,内部温度传感器工作
	/*BIASE=1,偏移产生器工作
	REFBE=1,内部参考电平工作,电路部分须将VREF参考输出(C8051F40的第12管脚)与VREF0(C8051F040的16管脚相连,并最好并联一个4.7uF和0.1uF的旁路电容以电平滤波*/
	adc0_source(9);//选择第9通道,即选择温度信号为AD转换
//	EIE2 |= 0x02;        //开ADC0中断
}
void delay1ms(uint time){//延迟1ms
	uint i;
	uint j;
	for (i=0;i<time;i++){
		for(j=0;j<300;j++);
	}
}	
void config(){
//看门狗禁止
	WDTCN = 0x07;	
    WDTCN = 0xDE;   
   	WDTCN = 0xAD;
	SFRPAGE = 0x0F;
//交叉开关使能,但没有进行外围设备配置
	XBR0 = 0x00;	
	XBR1 = 0x00;	
	XBR2 = 0x40;
 	XBR3 = 0x00;   
//管脚输出配置,P0口为开漏输出,其中P0.6接上拉电阻,P0为数字输入口
 	SFRPAGE = 0x0F;
 	P0MDOUT = 0x00; 
 	P1MDIN = 0xFF;  
//晶振配置,采用内部晶振8分频
	SFRPAGE = 0x0F;
 	CLKSEL = 0x00;  
	OSCXCN = 0x00;	
	OSCICN = 0x84;	
}
void main(){
	uchar i;
	uchar dataindex;
	config();
	adc0_ini();//ADC0初始化
	ADC0START;//ADC0启动
	EA=0;
	i=0;
	stack_index=0;
	canread=0;
	dataindex=0;
	while(1){
		SFRPAGE=0x00;
		if(AD0INT){
				AD0INT=0;
				isnewdata=1;
				if(stack_index>=STACK_LEN){
				/*STACK_LEN需小于等于256,否则stack_index要定义成uint型数据*/
				stack_index=0;
				canread=1;
				}
				mystack[stack_index]=ADC0VAL;
				stack_index++;
				ADC0START;
		}
		if(isnewdata&&canread){//由该位查询ADC0转化值是否更新
			for(i=0,total=0L;i<STACK_LEN;i++)/*注意若i定义为char型,则进入死循环,因为条件判断恒真*/
					total+=mystack[i];
			total/=8L;//此时total的值即为16bit精度采样值
			temp=(float)total/65536.0;
			temp*=2.43;
			temp-=0.776;
			temp/=0.00286;//将测量值转化成真实温度值
			isnewdata=0;
			t[dataindex]=temp;//将温度检测值存入长度为20的数组中
			ad16[dataindex]=(uint)total;
			ad12[dataindex]=mystack[stack_index];
			total=mystack[stack_index];/*12bit测量温度,以便与16bit过采样比较*/
			temp=(float)total/4096.0;
			temp*=2.43;
			temp-=0.776;
			temp/=0.00286;
			t12[dataindex]=temp;
			dataindex++;
			if(dataindex>19)
				dataindex=0;//在此设断点,观察程序运行结果
			
		}
	}
}
void ADC0_ISR() interrupt 15{//ADC0中断,此程序中采用查询法,暂不用中断
	SFRPAGE=0x00;
	AD0INT=0;
	isnewdata=1;
	if(stack_index>=STACK_LEN){
	//STACK_LEN需小于等于256,否则stack_index要定义成uint型数据
		stack_index=0;
		canread=1;
	}
	mystack[stack_index]=ADC0VAL;
	stack_index++;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -