📄 monitor.c
字号:
// monitor.c
/********************************************************************/
/* */
/* Monitor routines */
/* */
/********************************************************************/
#include <ADuC7020.h>
#include "common.h"
#include <math.h>
void monitor(void){
#if DEBUG == 1
GP4SET = 0x00040000;
#endif
temp_monitor();
voltage_monitor();
tx_bias_monitor();
tx_mod_monitor();
tx_pow_monitor();
rx_pow_monitor();
#if DEBUG == 1
GP4CLR = 0x00040000;
#endif
}
HALFWORD adc(BYTE adc_ch){
BYTE cnt;
HALFWORD adcread[4];
ADCCP = adc_ch;
for(cnt=0; cnt<4; cnt++){
ADCCON = 0xA3; // software start, single-end input
while(!ADCSTA){} // wait for end of conversion
adcread[cnt]=(ADCDAT>>16);
}
// ADC bug fix
if(adcread[3] > ADC_HIGH_MAX) adcread[3] = 0; // limits a highest
return adcread[3];
}
/********************************************************************/
/* */
/* Temperature Monitor */
/* */
/********************************************************************/
void temp_monitor(void)
{
volatile HALFWORD adcread, sum=0, adcread_avr;
volatile short delta, temp;
volatile BYTE cnt;
static HALFWORD buf[8] = {0x400,0x400,0x400,0x400,0x400,0x400,0x400,0x400};
static BYTE p_buf=0;
// secect ADC channel
ADCCP = 0x10; // select internal temperature sensor
// start AD conversion at ADC input channel 0x10
adcread = adc(0x10);
// averaging
buf[p_buf] = adcread;
p_buf++;
p_buf &= 0x07; // reset ring-buffer pointer
for(cnt=0; cnt<8; cnt++){
sum += buf[cnt];
}
adcread_avr = sum>>3;
// delta[LSB] = Ref_ADCDAT[LSB] - ADCDAT[LSB]
delta = (((REF_ADCDAT_MSB<<8) + REF_ADCDAT_LSB) - adcread_avr);
// temperature[degC] = Ref_temperature[degC] + ((delta[LSB] * 610e-6 / 1.3mv) * 256)
temp = ((REF_TEMP_MSB<<8) + REF_TEMP_LSB) + delta * T_SLOPE;
// save data
A2h[96] = (BYTE)(temp>>8); // write high-byte
A2h[97] = (BYTE)(temp & 0x00F0); // write low-byte, fix low-order data at zero
}
/********************************************************************/
/* */
/* Power Supply Voltage Monitor */
/* */
/********************************************************************/
void voltage_monitor(void)
{
float volt;
HALFWORD volt_res;
HALFWORD i[2];
BYTE cnt;
// select ADC channel
ADCCP = 0x00; // select ADC0 input channel
// start A/D conversion
for(cnt=0; cnt<2; cnt++){
ADCCON = 0xA3; // software start, single-end input
while (!ADCSTA){} // wait for end of conversion
i[cnt] = (ADCDAT >> 16);
}
// Voltage = 2 * ADCDATA * 610uV / 100uV
volt = 2 * i[1] * 610e-6 / 100e-6;
//volt = 2 * (ADCDAT>>16) * 610e-6 / 100e-6;
volt_res = (HALFWORD)volt;
// save data
A2h[98] = (BYTE)(volt_res>>8); // write high-byte
A2h[99] = (BYTE)(volt_res & 0x00F0); // write low-byte, fix low-order data at zero
}
/********************************************************************/
/* */
/* TX Bias Current Monitor */
/* */
/********************************************************************/
void tx_bias_monitor(void)
{
float bias;
HALFWORD bias_res;
HALFWORD i[4];
BYTE cnt;
static HALFWORD buf[8];
static BYTE p_buf=0;
HALFWORD dat=0;
// select ADC channel
ADCCP = 0x01; // select ADC1 input channel
// start A/D conversion
for(cnt=0; cnt<4; cnt++){
ADCCON=0xA3; // software start, single-end input
while(!ADCSTA){} // wait for end of conversion
i[cnt]=(ADCDAT>>16);
}
// ADC bug fix
if(i[3] > ADC_HIGH_MAX) i[3] = 0; // limits a highest
// averaging
buf[p_buf] = i[3];
p_buf++;
p_buf &= 0x07; // reset ring-buffer pointer
for(cnt=0; cnt<8; cnt++){
dat += buf[cnt];
}
dat = dat>>3; // delta/8;
// Ibias[A] = Ibmon[A] * 100
// Ibmon[A] = ADCDATA * 610[uV] / 1000ohm
bias = (dat * 610e-6 / 1e3) * 100;
// Ibias[A] : 1LSB = 0.2[uA]
bias /= 2e-6;
bias_res = (HALFWORD)bias;
// save data
A2h[100] = (BYTE)(bias_res>>8); // write high-byte
A2h[101] = (BYTE)(bias_res & 0x00F0); // write low-byte, fix low-order 4-bit at zero
}
/********************************************************************/
/* */
/* TX Modulation Current Monitor */
/* */
/********************************************************************/
void tx_mod_monitor(void)
{
float mod;
HALFWORD mod_res;
HALFWORD i[4];
BYTE cnt;
static HALFWORD buf[8];
static BYTE p_buf=0;
HALFWORD dat=0;
// select ADC channel
ADCCP = 0x02; // select ADC2 input channel
// start A/D conversion
for(cnt=0; cnt<4; cnt++){
ADCCON=0xA3; // software start, single-end input
while(!ADCSTA){} // wait for end of conversion
i[cnt]=(ADCDAT>>16);
}
// ADC bug fix
if(i[3] > ADC_HIGH_MAX) i[3] = 0; // limits a highest
// averaging
buf[p_buf] = i[3];
p_buf++;
p_buf &= 0x07; // reset ring-buffer pointer
for(cnt=0; cnt<8; cnt++){
dat += buf[cnt];
}
dat = dat>>3; // delta/8;
// Imod[A] = Immon[A] * 50
// Immon[A] = ADCdat * 610e-6 / 470ohm
mod = (dat * 610e-6 / 470) * 50;
// Imod[A] : 1LSB = 0.2[uA]
mod /= 2e-6;
mod_res = (HALFWORD)mod;
// save data
TXMOD_MSB = (BYTE)(mod_res>>8); // write high-byte
TXMOD_LSB = (BYTE)(mod_res & 0x00F0); // write low-byte, fix low-order 4-bit at zero
// save raw adc data for ER compensation control
TXMOD_RAWDAT_MSB = dat>>8; // write high-byte
TXMOD_RAWDAT_LSB = (dat & 0x00FF);
}
/********************************************************************/
/* */
/* TX Output Power Monitor */
/* */
/********************************************************************/
void tx_pow_monitor(void)
{
float pow;
HALFWORD pow_res;
HALFWORD i[4];
BYTE cnt;
static HALFWORD buf[8];
static BYTE p_buf=0;
HALFWORD dat=0;
// select ADC channel
ADCCP = 0x0F; // ADC15 bufferred input
// kernel update and 100pF on DAC3 required
// start A/D conversion
for(cnt=0; cnt<4; cnt++){
ADCCON=0xA3; // software start, single-end input
while(!ADCSTA){} // wait for end of conversion
i[cnt]=(ADCDAT>>16);
}
// averaging
buf[p_buf] = i[3];
p_buf++;
p_buf &= 0x07; // reset ring-buffer pointer
for(cnt=0; cnt<8; cnt++){
dat += buf[cnt];
}
dat = dat>>3; // delta/8;
// TxPower[W] = reference tx power[W] * (measured Impd[A] / reference Impd[A])
// measured Impd[A] = (ADCDAT * 610e-6 / 1kohm)
// reference power[W] : 1LSB = 0.1[uW], byte location A2h[122][123]
// reference Impd[A] : 1LSB = 0.1[uA], byte location A2h[124][125]
pow = (((A2h[122]<<8) + A2h[123]) * 0.1e-6 ) * (dat * 610e-6 / 1000) / (((A2h[124]<<8) + A2h[125]) * 0.1e-6);
// TxPower[W] : 1LSB = 0.1[uW]
pow /= 0.1e-6;
pow_res = (HALFWORD)pow;
// save data
A2h[102] = (BYTE)(pow_res>>8); // write high-byte
A2h[103] = (BYTE)(pow_res & 0x00F0); // write low-byte, fix low-order 4-bit at zero
}
/********************************************************************/
/* */
/* Rx Recived Power Monitor */
/* */
/********************************************************************/
void rx_pow_monitor(void)
{
float pow;
HALFWORD pow_res;
HALFWORD i[4]; // for debug
BYTE cnt;
static HALFWORD buf[8];
static BYTE p_buf=0;
HALFWORD dat=0;
// select ADC channel
ADCCP = 0x04; // select ADC4 input channel
// start A/D conversion
for(cnt=0; cnt<4; cnt++){
ADCCON=0xA3; // software start, single-end input
while(!ADCSTA){} // wait for end of conversion
i[cnt]=(ADCDAT>>16);
}
// ADC bug fix
if(i[3] > ADC_HIGH_MAX) i[3] = 0; // limits a highest
// averaging
buf[p_buf] = i[3];
p_buf++;
p_buf &= 0x07; // reset ring-buffer pointer
for(cnt=0; cnt<8; cnt++){
dat += buf[cnt];
}
dat = dat>>3; // delta/8;
// RxPower[W] = Ipd[A] / Responsivity[A/W]
// Ipd[A] = ADCDAT * 610e-6 / 2.00Kohm
// Responsivity[A/W] : 1LSB = 0.01[A/W], byte location A2h[126]
pow = (i[3] * 610e-6 / 2e3) / (A2h[126] * 0.01);
// RxPower[W] : 1LSB = 0.1[uW]
pow /= 0.1e-6;
pow_res = (HALFWORD)pow;
// save data
A2h[104] = (BYTE)(pow_res>>8); // write high-byte
A2h[105] = (BYTE)(pow_res & 0x00F0); // write low-byte, fix low-order 4-bit at zero
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -