📄 ads7871.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( ®_num, 1, sel_num );
SPI_SendBuf( ®_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 + -