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

📄 monitor.c

📁 ADI公司的关于光通讯模块的监控程序,在KEIL FOR ARM 的编译环境编译.程序大小约12K,芯片是ADu7020.
💻 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 + -