Zynq-Linux移植学习笔记之24-VPVN温度监测

在对模块进行信息监测时,会用到ZYNQ内部的VPVN通道,默认情况下该通道是不开启的,需要手动在内核驱动代码中设置


修改为


重新编译内核,加载镜像就能够系统/sys/bus/iio/devices/iio:device0/中看到VPVN了


将VPVN电压转换为温度可以参考下面代码TEMP1848_1

#ifndef _XADC_CORE_H
#define _XADC_CORE_H

#define MAX_PATH_SIZE	200
#define MAX_NAME_SIZE	50
#define MAX_VALUE_SIZE  100

#define MAX_CMD_NAME_SIZE 100
#define MAX_UNIT_NAME_SIZE 50

#define SYS_PATH_IIO	"/sys/bus/iio/devices/iio:device0"

#define VCC_INT_CMD		"xadc_get_value_vccint"
#define VCC_AUX_CMD		"xadc_get_value_vccaux"
#define VCC_BRAM_CMD		"xadc_get_value_vccbram"
#define VCC_TEMP_CMD		"xadc_get_value_temp"
#define VCC_EXT_CH_CMD		"xadc_get_value_ext_ch"


#define FPGA_TEMP "/sys/bus/iio/devices/iio:device0/in_temp0_raw"
#define TEMP1848_1 "/sys/bus/iio/devices/iio:device0/in_voltage8_vpvn_raw"

#define VCC_1 	"/sys/bus/iio/devices/iio:device0/in_voltage0_vccint_raw"
#define VCC_1V8 "/sys/bus/iio/devices/iio:device0/in_voltage4_vccpaux_raw"
#define VCC_PINT "/sys/bus/iio/devices/iio:device0/in_voltage3_vccpint_raw"
#define VCC_PAUX "/sys/bus/iio/devices/iio:device0/in_voltage4_vccpaux_raw"
#define VCC_PDDR "/sys/bus/iio/devices/iio:device0/in_voltage5_vccoddr_raw"

static const int mV_mul = 1000;

static const int multiplier = 1 << 12;

enum EConvType
{
	EConvType_None,
	EConvType_Raw_to_Scale,
	EConvType_Scale_to_Raw,
	EConvType_Max
};

enum XADC_Param
{
	EParamVccInt,
  	EParamVccAux,
	EParamVccBRam,
	EParamTemp,
	EParamVAux0,
	EParamMax
};

struct command
{
	const enum XADC_Param parameter_id;
	const char cmd_name[MAX_CMD_NAME_SIZE];
	const char unit[MAX_UNIT_NAME_SIZE];
};

struct command command_list[EParamMax] = {
				{EParamVccInt, 	VCC_INT_CMD, "mV"},
				{EParamVccAux, 	VCC_AUX_CMD, "mV"},
				{EParamVccBRam, VCC_BRAM_CMD, "mV"},
				{EParamTemp, 	VCC_TEMP_CMD, "Degree Celsius"},
				{EParamVAux0, 	VCC_EXT_CH_CMD, "mV"}
};

struct XadcParameter
{
	const char name[MAX_NAME_SIZE];
	float value;
	float (* const conv_fn)(float,enum EConvType);
};

#endif


/*
 * xadc_core.c
 *
 *  Created on: 2017年9月20日
 *      Author: Administrator
 */

#include "xadc_core.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <ctype.h>
#include <pthread.h>
#include <assert.h>

//utility functions
float conv_voltage(float input, enum EConvType conv_direction)
{
	float result=0;

	switch(conv_direction)
	{
	case EConvType_Raw_to_Scale:
		result = ((input * 3.0 * mV_mul)/multiplier);
		break;
	case EConvType_Scale_to_Raw:
		result = (input/(3.0 * mV_mul))*multiplier;
		break;
	default:
		printf("Convertion type incorrect... Doing no conversion\n");
		//  intentional no break;
	case EConvType_None:
		result = input;
		break;
	}

	return result;
}

#if 0
float conv_voltage_ext_ch(float input, enum EConvType conv_direction)
{
	float result=0;

	switch(conv_direction)
	{
	case EConvType_Raw_to_Scale:
		result = ((input * mV_mul)/multiplier);
		break;
	case EConvType_Scale_to_Raw:
		result = (input/mV_mul)*multiplier;
		break;
	default:
		printf("Convertion type incorrect... Doing no conversion\n");
		//  intentional no break;
	case EConvType_None:
		result = input;
		break;
	}

	return result;
}
#endif

float conv_temperature(float input, enum EConvType conv_direction)
{
	float result=0;

	switch(conv_direction)
	{
	case EConvType_Raw_to_Scale:
		result = ((input * 503.975)/multiplier) - 273.15;
		break;
	case EConvType_Scale_to_Raw:
		result = (input + 273.15)*multiplier/503.975;
		break;
	default:
		printf("Conversion type incorrect... Doing no conversion\n");
		//  intentional no break;
	case EConvType_None:
		result = input;
		break;
	}

	return result;
}

float get_temp(int num)
{
	int number;
	int fd = -1;
	char upset[20];
	float raw_data=0;
	float true_data=0;
	int offset=0;
	char value=0;
	float max_temp=0;
	number=num;
	if(number==0)
	{
		fd = open(FPGA_TEMP, O_RDWR );
		offset=0;
		while(offset<5)
		{
			lseek(fd,offset,SEEK_SET);
			read(fd,&value,sizeof(char));
			upset[offset]=value;
			offset++;
		}
		upset[offset]='\0';
		raw_data=atoi(upset);
		true_data=conv_temperature(raw_data, EConvType_Raw_to_Scale);
//		true_data=(conv_voltage(raw_data, EConvType_Raw_to_Scale)*1000/(3*2.2)-273.15)/10000;
		//printf("FPGA temp is %f cent\n",true_data);
		close(fd);
		return true_data;
	}
	else
	{
		fd = open(TEMP1848_1, O_RDWR );
		offset=0;
		while(offset<5)
		{
			lseek(fd,offset,SEEK_SET);
			read(fd,&value,sizeof(char));
			upset[offset]=value;
			offset++;
		}
		upset[offset]='\0';
		raw_data=atoi(upset);
		true_data=(conv_voltage(raw_data, EConvType_Raw_to_Scale)*1000/(3*2.2)-273.15)/10000;
		max_temp=true_data;
		//printf("1848-1 temp is %f cent\n",true_data);
		close(fd);

		return max_temp;
	}

}

float get_vcc(int num)
{
	int number;
	int fd = -1;
	char upset[20];
	float raw_data=0;
	float true_data=0;
	int offset=0;
	char value=0;
	number=num;
	if(number==0)
	{
		fd = open(VCC_1, O_RDWR );
		offset=0;
		while(offset<5)
		{
			lseek(fd,offset,SEEK_SET);
			read(fd,&value,sizeof(char));
			upset[offset]=value;
			offset++;
		}
		upset[offset]='\0';
		raw_data=atoi(upset);
		true_data=conv_voltage(raw_data, EConvType_Raw_to_Scale);
		//printf("vcc 1 is %f mv\n",true_data);
		close(fd);
	}
	else if(number==1)
	{
		fd = open(VCC_1V8, O_RDWR );
		offset=0;
		while(offset<5)
		{
			lseek(fd,offset,SEEK_SET);
			read(fd,&value,sizeof(char));
			upset[offset]=value;
			offset++;
		}
		upset[offset]='\0';
		raw_data=atoi(upset);
		true_data=conv_voltage(raw_data, EConvType_Raw_to_Scale);
		//printf("vcc 1v8 is %f mv\n",true_data);
		close(fd);

	}
	else if(number==2)
	{
		fd = open(VCC_PINT, O_RDWR );
		offset=0;
		while(offset<5)
		{
			lseek(fd,offset,SEEK_SET);
			read(fd,&value,sizeof(char));
			upset[offset]=value;
			offset++;
		}
		upset[offset]='\0';
		raw_data=atoi(upset);
		true_data=conv_voltage(raw_data, EConvType_Raw_to_Scale);
		//printf("vcc pint is %f mv\n",true_data);
		close(fd);

	}
	else if(number==3)
	{
		fd = open(VCC_PAUX, O_RDWR );
		offset=0;
		while(offset<5)
		{
			lseek(fd,offset,SEEK_SET);
			read(fd,&value,sizeof(char));
			upset[offset]=value;
			offset++;
		}
		upset[offset]='\0';
		raw_data=atoi(upset);
		true_data=conv_voltage(raw_data, EConvType_Raw_to_Scale);
		//printf("vcc paux is %f mv\n",true_data);
		close(fd);

	}
	else if(number==4)
	{
		fd = open(VCC_PDDR, O_RDWR );
		offset=0;
		while(offset<5)
		{
			lseek(fd,offset,SEEK_SET);
			read(fd,&value,sizeof(char));
			upset[offset]=value;
			offset++;
		}
		upset[offset]='\0';
		raw_data=atoi(upset);
		true_data=conv_voltage(raw_data, EConvType_Raw_to_Scale);
		//printf("vcc pddr is %f mv\n",true_data);
		close(fd);

	}
	return true_data/1000;
}

重点是下面这个公式

true_data=(conv_voltage(raw_data, EConvType_Raw_to_Scale)*1000/(3*2.2)-273.15)/10000;

猜你喜欢

转载自blog.csdn.net/jj12345jj198999/article/details/79519150