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

📄 ads7871.cpp

📁 ADS7871驱动:使用SPI通讯
💻 CPP
字号:
//#include "..\ArmBIOS.h"
#include <stdio.h>
#include "..\..\Lib\ArmOs\ArmLib.h"
#include "ADS7871.h"
#include "..\SPI\spi.h"

#define PIN1 1
#define PIN0 0
//--------------------------------------------------------------------------------------------
#define Sleep( x )

#define SPI_CS_LOW_1    SetPinOff(1,31) //PinSetLev( PIN1, 31, LEVEL_LOW )
#define SPI_CS_HIGH_1 	SetPinOn(1,31)  //PinSetLev( PIN1, 31, LEVEL_HIGH )

#define SPI_CS_LOW_2    SetPinOff(1,21) //PinSetLev( PIN1, 21, LEVEL_LOW )
#define SPI_CS_HIGH_2 	SetPinOn(1,21)  //PinSetLev( PIN1, 21, LEVEL_HIGH )

//--------------------------------------------------------------------------------------------
//register below
#define ADC_OUTPUT_0 0x00
#define ADC_OUTPUT_1 0x01
#define PGA_VALID    0x02
#define ADC_CONTROL  0x03
#define GAIN_MUX     0x04
#define IO_STATE     0x05
#define IO_CONTROL   0x06
#define REF_OSC      0x07
#define SPI_CONTROL  0x18
#define ID_7871      0x1f

#define AD_MAX_CHANNEL_NUMBER	16

unsigned char g_ad_start_convert_command[AD_MAX_CHANNEL_NUMBER];
unsigned char g_ad_gain[AD_MAX_CHANNEL_NUMBER];
//--------------------------------------------------------------------------------------------
void ADParameterInit( void )
{
	unsigned char i,j;
	for( j = 0, i = 0; i < 16; i ++, j ++ )
	{
		g_ad_start_convert_command[i] = 0x88;
		if( j > 7 )
			j = 0;
		g_ad_start_convert_command[i] |= j;
		g_ad_gain[i] = 1;
	}
}
//--------------------------------------------------------------------------------------------
//enum{ GAIN_1, GAIN_2, GAIN_4, GAIN_5, GAIN_8, GAIN_10, GAIN_16, GAIN20 };
unsigned char ConvertGainToOctal( unsigned char gain )
{
	unsigned char return_value = 0;
	switch( gain )
	{
		case 1:  return_value = 0x00; break;
		case 2:  return_value = 0x01; break;
		case 4:  return_value = 0x02; break;
		case 5:  return_value = 0x03; break;
		case 8:  return_value = 0x04; break;
		case 10: return_value = 0x05; break;
		case 16: return_value = 0x06; break;
		case 20: return_value = 0x07; break;
		default: printf("Undefined gain value, available as follow: 1,2,4,5,8,10,16,20.\n"); break;
	}
	
	return return_value;
}
//--------------------------------------------------------------------------------------------
//gain_value: GAIN_1, GAIN_2, GAIN_4, GAIN_5, GAIN_8, GAIN_10, GAIN_16, GAIN20
//channel_number = 0~15, 若 channel_number == 0xff, 则对所有通道进行同一设置
void AD_SetGain( unsigned char channel_number, unsigned char gain_value )
{
	unsigned char gain_octal;
	int i;
	
	if( gain_value != 1 && gain_value != 2 && gain_value != 4 && gain_value != 5 &&
		gain_value != 8 && gain_value != 10 && gain_value != 16 && gain_value != 20 )
		return;
	if( ( channel_number > AD_MAX_CHANNEL_NUMBER ) && ( channel_number != 0xff ) )
		return;
	
	gain_octal = ConvertGainToOctal( gain_value );
	
	if( channel_number < AD_MAX_CHANNEL_NUMBER )
	{
		g_ad_start_convert_command[channel_number] &= 0x8f;
		g_ad_start_convert_command[channel_number] |= gain_octal << 4;
		g_ad_gain[channel_number] = gain_value;
	}else if( channel_number == 0XFF )
	{
		for( i = 0; i < AD_MAX_CHANNEL_NUMBER; i ++ )
		{
			g_ad_start_convert_command[i] &= 0x8f;
			g_ad_start_convert_command[i] |= gain_octal << 4;
			g_ad_gain[i] = gain_value;
		}
	}
}
//--------------------------------------------------------------------------------------------
//polarity = 0,1,2   number=0~15
unsigned char ConvertPolarityToOctal( unsigned channel_number, unsigned char polarity_mode )
{
	unsigned char return_value = 0;
	unsigned char number = channel_number;
	
	if( channel_number > 7 ){ number -= 8; }

	if( polarity_mode == 0 ){//single mode
		return_value |= 0x08;
		return_value |= number;
	}else if( polarity_mode == 1 ){//+-
		switch( number )
		{
			case 0: break;
			case 1: break;
			case 2: return_value |= 0x01; break;
			case 3: return_value |= 0x01; break;
			case 4: return_value |= 0x02; break;
			case 5: return_value |= 0x02; break;
			case 6: return_value |= 0x03; break;
			case 7: return_value |= 0x03; break;
			default: printf("SetPolarity fail, channel_number out of range\n"); break;
		}
	}else if( polarity_mode == 2 ){//-+
		switch( number )
		{
			case 0: return_value |= 0x04; break;
			case 1: return_value |= 0x04; break;
			case 2: return_value |= 0x05; break;
			case 3: return_value |= 0x05; break;
			case 4: return_value |= 0x06; break;
			case 5: return_value |= 0x06; break;
			case 6: return_value |= 0x07; break;
			case 7: return_value |= 0x07; break;
			default: printf("SetPolarity fail, channel_number out of range\n"); break;
		}
	}else{
		printf("polarity_mode error\n");
	}
	
	return return_value;
}
//--------------------------------------------------------------------------------------------
//polarity_mode = 0(single),1(+-),2(-+)
void AD_SetPolarity( unsigned char channel_number, unsigned char polarity_mode )
{
	unsigned char write_octal = 0;
	unsigned char i,j;
	
	if( (channel_number >= AD_MAX_CHANNEL_NUMBER) || (polarity_mode > 2) )
		return;
		
	if( channel_number < AD_MAX_CHANNEL_NUMBER )
	{
		write_octal = ConvertPolarityToOctal( channel_number, polarity_mode );
		g_ad_start_convert_command[channel_number] |= write_octal;
	}else if( channel_number == 0xff )
	{
		for( i = 0, j = 0; i < AD_MAX_CHANNEL_NUMBER; i ++, j ++ )
		{
			if( j > 7 )
				j = 0;
			g_ad_start_convert_command[i] &= 0xf0;
			g_ad_start_convert_command[i] |= j;
		}
	}
}
//--------------------------------------------------------------------------------------------
enum{BYTE,WORD};
void AD_Select7871( unsigned char sel_num )//sel_num为0时选1,为非0时选2
{
	if( sel_num ){
		SPI_CS_LOW_2;
	}else{
		SPI_CS_LOW_1;
	}
}
//--------------------------------------------------------------------------------------------
void AD_DeSelect7871( unsigned char sel_num )
{
	if( sel_num ){
		SPI_CS_HIGH_2;
	}else{
		SPI_CS_HIGH_1;
	}
}
//--------------------------------------------------------------------------------------------
void AD_Reset7871( unsigned char sel_num )
{
	AD_Select7871( sel_num );
	
	SPI_SendBuf( ADC_OUTPUT_0, 1, sel_num );
	SPI_SendBuf( 0x00, 1, sel_num );
	
	AD_DeSelect7871( sel_num );	
}
//--------------------------------------------------------------------------------------------
unsigned char AD_Get7871ID( unsigned char sel_num )
{
	unsigned char id_value = 0;
	unsigned char op_code = 0x5f;
	
	AD_Select7871( sel_num );
	
	SPI_SendBuf( &op_code, 1, sel_num );
	SPI_RcvBuf( &id_value, 1, sel_num );
	
	AD_DeSelect7871( sel_num );	
	
	return id_value;
}
//--------------------------------------------------------------------------------------------
//sel_num=0,1;  reg_num=0~7,24,31(0,1,2,31 are read only);  
void AD_WriteRegister( unsigned char sel_num, unsigned char reg_num, unsigned char reg_value )//0~7,24,31,其中0、1、2、31只读
{
	if( ( ( reg_num < 0x03 ) && ( reg_num != 0x00 ) ) || ( ( reg_num > 0x07 ) && ( reg_num != 0x18 ) ) )
	{
		printf("The register you write is invalid in AD_WriteRegister()\n");
		return;
	}
	AD_Select7871( sel_num );
	
	SPI_SendBuf( &reg_num, 1, sel_num );
	SPI_SendBuf( &reg_value, 1, sel_num );
	
	AD_DeSelect7871( sel_num );	
}
//--------------------------------------------------------------------------------------------
//sel_num=0,1;  reg_num=0~7,24,31;  byte_or_word=0(byte),1(word)
//当读byte是,返回值在低8位
unsigned int AD_ReadRegister( unsigned char sel_num, unsigned char read_reg_num, unsigned char byte_or_word )
{
	unsigned char read_instruction = read_reg_num;
	unsigned short int read_value = 0;
	unsigned char read_temp = 0;
	unsigned char temp = 0;
	read_instruction |= 0x40;
	if( byte_or_word ){ read_instruction |= 0x20; }
	
	AD_Select7871( sel_num );
	
	SPI_SendBuf( &read_instruction, 1, sel_num );
	if( byte_or_word )//读16位
	{
		if( read_reg_num & 0x01 )//奇地址,下一次读到前一个地址的值,奇地址放入高字节
		{
			//这里或许可以改一下,直接读到int的值里
			SPI_RcvBuf( &read_temp, 1, sel_num );
			read_value = (unsigned int)read_temp << 8;
			SPI_RcvBuf( &read_temp, 1, sel_num );
			read_value |= read_temp;
		}else
		{
			SPI_RcvBuf( &temp, 1, sel_num );
			read_value = temp;
			SPI_RcvBuf( &temp, 1, sel_num );
			read_value |= (unsigned short int)temp << 8;
		}
	}else
	{             //读8位
		SPI_RcvBuf( &temp, 1, sel_num );
		read_value = temp;
	}
	
	AD_DeSelect7871( sel_num );	
	
	return read_value;
}
//--------------------------------------------------------------------------------------------
void AD_SetADLEDState( unsigned char state )//state = 0,~0, if ~0, set led on
{
	AD_WriteRegister( 0, IO_CONTROL, 0x01 );
	if( state )
		AD_WriteRegister( 0, IO_STATE, 0x01 );
	else
		AD_WriteRegister( 0, IO_STATE, 0x00 );
}
//--------------------------------------------------------------------------------------------
void WaitEndOfOperation( unsigned channel_number )
{
	unsigned char chip_num = 0;
	
	chip_num = (channel_number > 7) ? 1 : 0;
	
	while( AD_ReadRegister( chip_num, IO_STATE, BYTE ) & 0x80 )
	{
		Sleep( 1 );//wait here, maybe not good
	}
}
//--------------------------------------------------------------------------------------------
void AD_StartConvertOneChannel( unsigned char channel_number )
{
	unsigned char chip_num = 0;
	
	if( channel_number > AD_MAX_CHANNEL_NUMBER )
		return;
	
	chip_num = (channel_number > 7) ? 1 : 0;
	
	WaitEndOfOperation( channel_number );
	
	AD_Select7871( chip_num );
	
	SPI_SendBuf( &g_ad_start_convert_command[channel_number], 1, chip_num );
	
	AD_DeSelect7871( chip_num );
}
//--------------------------------------------------------------------------------------------
//读两个结果寄存器的值,屏蔽掉最低的两位非结果位,但最低位为OVR,可能用得到。
int AD_ReadResult( unsigned char channel_number )
{
	unsigned int value = 0;
	unsigned char chip_num = 0;
	
	if( channel_number > AD_MAX_CHANNEL_NUMBER )
		return 0;
	
	chip_num = (channel_number > 7) ? 1 : 0;
	
	WaitEndOfOperation( channel_number );
	
	value = AD_ReadRegister( chip_num, ADC_OUTPUT_1, WORD );
	value >>= 2;
	
	//value /= g_ad_gain[channel_number];
	if(value & 0x2000)
	{
		value |= 0xffffc000;
	}
	return (int)value;
}
//--------------------------------------------------------------------------------------------
//初始化函数,程序运行时或可以定时调用初始化
void AD_Init7871( unsigned char sel_num )
{
	AD_Reset7871( sel_num );
	AD_WriteRegister( sel_num, REF_OSC, 0x2c );
}
//--------------------------------------------------------------------------------------------
float AD_ReadResultFloat( unsigned char channel_num )
{
	unsigned int result = 0;
	float result_f;
	
	result = AD_ReadResult( channel_num );
	
	if( result & 0x2000 )
	{
		result_f = ( ( float )( 0x4000 -result ) / 8192 ) *2.5;
	}else
	{
		result_f = ( ( float )( result ) / 8192 ) * 2.5;
	}

	return result_f;
}
//--------------------------------------------------------------------------------------------
void AD_InitADs( void )
{
	AD_Init7871( 0 );// to be del********
	AD_Init7871( 1 );// to be del******
	ADParameterInit();
}
//--------------------------------------------------------------------------------------------
/*
void _________Modified070621____()
*/
//--------------------------------------------------------------------------------------------
//--下面的内容2007-6-21 13:44后添加,测试AD-------------------------------------------------------
//--------------------------------------------------------------------------------------------
//sel_num=0,1;  channel_number=0~7;   single_or_differencial=0,1;    gain_value=0~7
//gain_value=0(1),1(2),2(4),3(5),4(8),5(10),6(16),7(20)
//当single_or_differencial=1时,channel_number<4时,表示选中差分,并且记号小的通道为正; chanenl_number>=4时,差分,序号大的为正
//void AD_StartConvert( unsigned char sel_num, unsigned char channel_number, unsigned char single_or_differencial, unsigned char gain_value )

//读两个结果寄存器的值,屏蔽掉最低的两位非结果位,但最低位为OVR,可能用得到。
void GetOneChannelResult( unsigned char channel_num )
{
	float f_result = 0;
	
	//AD_SetPolarity( channel_num, 0 );
	AD_StartConvertOneChannel( channel_num );
	f_result = AD_ReadResultFloat( channel_num );
	printf("%d=%6.4f,  ", channel_num, f_result);
}
//--------------------------------------------------------------------------------------------
void GetAllChannelResult( unsigned char gain_value )
{
	int i;
	
	AD_SetGain( 0xff, gain_value );
	
	//for( i = 0; i < AD_MAX_CHANNEL_NUMBER; i ++ )
	//	printf("%d=0x%x  ", i, g_ad_start_convert_command[i]);
	//printf("\n");
	
	for( i = 0; i < AD_MAX_CHANNEL_NUMBER; i ++ )
	{
		GetOneChannelResult( i );
	}
	printf("\n");
}
//--------------------------------------------------------------------------------------------
//--上面的内容2007-6-21 13:44后添加,测试AD-------------------------------------------------------
//--------------------------------------------------------------------------------------------

⌨️ 快捷键说明

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