/******************************************************************************
* @file adc.c
* @author
* @version V0.5
* @date 2011-05-12
* @brief ADC ADS1248 abstract functions
******************************************************************************/
/* Includes */
#include "adc.h"
#include "define.h"
/*Imported functions*/
//#define ADC_SET GPIO_SetBits(GPIOE, GPIO_Pin_11);
//#define ADC_RESET GPIO_ReSetBits(GPIOE, GPIO_Pin_11);
extern void Delay_us(u16 x);
/* Private variables */
bool adc_task,pre_read;
u16 adc_time_counter; //RTC for scheduling tasks, interrupts every 10mS
u8 previous_adc_channel;
adcdata ADData_IH, ADData_IC;
vu8 RxIdx,bufferIdx;
bool Err_Sensor=FALSE;
/*vihot, vpcold signals */
double vihot,vpcold,prev_vihot,current_vihot,prev_vpcold;
double filter_sensor;
u16 Chan0_Com[buffer_size];
u16 Chan2_Com[buffer_size];
u16 Diag_Chan0_Com[1];
u16 Diag_Chan2_Com[1];
volatile bool channel_buffer_busy;
vu32 temp_adcvh,temp_adcvc;
u8 task_old=0;
u32 ADCData;
u8 i,j,k;
u32 ADCInputData;
adcdata ADCBuffer;
u8 configure_conversion_chan;
/**********************************************************
@brief Init ADC private and public variables
@params none
@notes
***********************************************************/
void ADCInit(void)
{
/* 状态、变量初始化 */
adc_task = FALSE;
pre_read = FALSE;
adc_time_counter = ADC_Schedule;
previous_adc_channel = CH2_COM; //select previous Channel CH2-COM as default
ADData_IH.adc_8[3] = 0;
ADData_IC.adc_8[3] = 0;
RxIdx = 2; //MSB of ADC data
bufferIdx = 0;
vihot = 0.0;
vpcold = 0.0;
temp_adcvh = 0;
temp_adcvc = 0;
ADData_IH.adc_32 = 0;
ADData_IC.adc_32 = 0;
ADCBuffer.adc_32 = 0;
channel_buffer_busy = FALSE;
prev_vihot = 0.0;
Diag_Chan0_Com[0] = 0;
Diag_Chan2_Com[0] = 0;
/* 寄存器初始化 */
ADC_CS_1;
Delay_us(_120US_);
ADC_CS_0;
Delay_us(_5US_);
ads1248_write_cmd_byte(ADS1248_RESET); //Reset to power-up values for debug
Delay_us(_120US_);
Delay_us(_120US_);
//if(ADC_DYDR)
//{
// Delay_us(_5MS_);
// if(ADC_DYDR)
// {
// SetAsciiFont(ENUM_ASCII_12_24, 0xf800, 0x0000);
// DisString(170, 105, "No sensor board!!!", 18);
// }
//}
//while(ADC_DYDR) //读取AD1248的DRDY引脚的状态
// ;
Delay_us(_5MS_); //用此延时时间来代替读取AD1248的DRDY引脚的状态
//ads1248_write_register(ADS1248_MUX0_ADDR, ADS1248_MUX_SP_AIN0 | ADS1248_MUX_SN_AIN1); //Positive Input AIN2,Negative Input AIN3
//Delay_us(_120US_);
//ads1248_write_register(ADS1248_VBIAS_ADDR, ADS1248_VBIAS_AIN1); //AIN1 Vbias
//Delay_us(_120US_);
ads1248_write_register(ADS1248_MUX1_ADDR, ADS1248_VREFCON_ON | ADS1248_REFSELT_INT | ADS1248_MUXCAL_NORMAL); //Internal Oscillator;Internal Reference;Onboard reference selected;Normal operation
Delay_us(_120US_); //延时等待,等待内部基准稳定
//ads1248_write_register(ADS1248_SYS0_ADDR, ADS1248_DOR_10SPS); //Gain=1;Highest data rate=10sps
//Delay_us(_120US_);
/* The IDACs require the internal reference to be on */
//ads1248_write_register(ADS1248_IDAC0_ADDR, ADS1248_DRDY_MODE_0 | ADS1248_IMAG_250UA);
//ads1248_write_register(ADS1248_IDAC1_ADDR, ADS1248_I1DIR_IEXT1 | ADS1248_I2DIR_DIS);
//Delay_us(_120US_);
//ads1248_write_cmd_byte(ADS1248_SYNC);
//Delay_us(_120US_);
//ads1248_write_cmd_byte(ADS1248_SYSOCAL); //系统失调校准,调试时用:被选择的模拟输入VIN = 0时,执行该语句
//while(ADC_DYDR) //ADS1248的/DRDR脚为低电平时表示校准完成
// ;
//ads1248_write_cmd_byte(ADS1248_SYSGCAL); //系统增益校准,调试时用:被选择的模拟输入为满量程时,执行该语句
//while(ADC_DYDR) //ADS1248的/DRDR脚为低电平时表示校准完成
// ;
//ads1248_write_cmd_byte(ADS1248_SELFOCAL); //自身失调校准,调试时用:断开模拟输入端与内部电路的连接,且内部信号为0时执行该语句
//while(ADC_DYDR) //ADS1248的/DRDR脚为低电平时表示校准完成
// ;
//ads1248_write_cmd_byte(ADS1248_RDATA); //发送读数据命令(读一次)
ads1248_write_cmd_byte(ADS1248_RDATAC); //发送读数据命令(连续读)
Delay_us(_120US_);
ADC_CS_1; //cs is high
}
/***********************************************************************************
@brief Read from LTC2488 24 bit read MSB first
bit 23 provides End of Conversion results Logic low is data ready
bit 22 always 0
bit 21 sign, should be 1 for single ended conversions
bit 20- bit4 (LSB) bit 3- bit0 all zeros
@params
@notes SPI port interfaces to ADC LTC2488 24 bit MSB first
Configured as 8 bit reads
************************************************************************************/
void ADCConvert_Read(void)
{
if(previous_adc_channel == CH2_COM)
{
configure_conversion_chan = ch0_config;
previous_adc_channel = CH0_COM;
}
else
{
configure_conversion_chan = ch2_config;
previous_adc_channel = CH2_COM;
}
ADCConvert_AlternateRead();
MoveADCData();
}
void ADCConvert_AlternateRead(void)
{
ADCData=0;
ADCInputData = 0x40000000;
ADCInputData |= (u32)(configure_conversion_chan<<8); //switch channel for next read
ADC_CS_0; //cs is low
//while(ADC_DYDR) //读取AD1248的DRDY引脚的状态
// ;
Delay_us(_5US_); //用此延时时间来代替读取AD1248的DRDY引脚的状态
ADC_SCK_0;
ADC_SDI_0;
Delay_us(_5US_);
for(i=0;i<24;i++)
{
if((ADCInputData&0x80000000) == 0x80000000) ADC_SDI_1;
else ADC_SDI_0;
ADCInputData <<= 1;
ADC_SCK_1;
Delay_us(_5US_);
ADCData <<=1;
if(ADC_SDO_IN==1) ADCData|=0x00000001; //sda==1
else {;}
ADC_SCK_0;
Delay_us(_5US_);
}
ADC_CS_1; //cs is high
ADC_SDI_0;
}
/******************************************************************************
@brief MoveADCData
@params none
@notes move data from ADCBuffer struct to ADData_IC & ADData_IH struct
store in Channel_0 and Channel_2 buffer
*******************************************************************************/
void MoveADCData(void)
{
channel_buffer_busy = TRUE;
if(previous_adc_channel == CH0_COM)
{
ADData_IC.adc_32 = ADCData; //通道已转换,现在读的是转换前通道的数据
}
else
{
ADData_IH.adc_32 = ADCData; //通道已转换,现在读的是转换前通道的数据
}
temp_adcvh = ADData_IH.adc_32 >> 8;
Chan0_Com[bufferIdx] = (u16)(temp_adcvh & 0xFFFF);
temp_adcvc = ADData_IC.adc_32 >> 8;
Chan2_Com[bufferIdx] = (u16)(temp_adcvc & 0xFFFF);
if(bufferIdx < (buffer_size - 1)) bufferIdx++;
else bufferIdx =0;
Diag_Chan0_Com[0]= Chan0_Com[0];
Diag_Chan2_Com[0]= Chan2_Com[0];
channel_buffer_busy = FALSE;
}
/************************************
@brief
@params
@notes
*************************************/
void ComputeSignal(void)
{
double filter;
u32 difference;
/*if channels are not updating compute signal*/
if(!channel_buffer_busy)
{
vihot=(double)(max_min_chioce(Chan0_Com,7)*ADC_REF/ADC_FullScale);
vpcold=(double)(max_min_chioce(Chan2_Com,7)*ADC_REF/ADC_FullScale);
//vihot = (double) ((((Chan0_Com[0]+Chan0_Com[1]+Chan0_Com[2]+Chan0_Com[3])/4)*ADC_REF)/ADC_FullScale);
//vpcold = (double) ((((Chan2_Com[0]+Chan2_Com[1]+Chan2_Com[2]+Chan2_Com[3]+Chan2_Com[4])/5)*ADC_REF)/ADC_FullScale);
if((vpcold>1.05)||(vihot>0.95)||(vpcold<0.1)||(vihot<0.1)) Err_Sensor=TRUE;//sensor 故障检测。
}
if(vihot >= prev_vihot) difference = 1000*(vihot - prev_vihot); //vihot加权处理
else difference = 1000*(prev_vihot - vihot);
if(difference > 5) filter = 0.5;
else filter = filter_sensor;
评论1