我试图用DSPIC30F3011读取半波信号的均方根值。我在LCD显示器上得到了正确的值,但问题是需要花费太多的时间来更新值。我想每500毫秒扫描模拟值。我用的是10兆赫的晶体。
以上来自于百度翻译
以下为原文
I am trying to read RMS value of a half wave signal using dspic30f3011. I am get
ting correct value at my LCD display, but problem is that It's taking too much time to update value I want to scan analog value at every 500 ms.
I am using 10 MHz crystal.
unsigned char ADC_buffer [5];
unsigned long ADCValue;
unsigned int *ADC16Ptr;
float ADC_float = 0;
double ADC_average[];
// int ii ,jj , kk ;
static int ii = 0, jj = 0, kk = 0;
void ADC_AN2(void)
{
float maxima[1];
float average[10];
float maxima_average;
ADPCFG = 0b0000000000000000; // all PORTB = Digital; RB2 = analog
ADCON1 = 0x00E0; // SSRC bit = 111 implies internal
// counter ends sampling and starts
// converting.
ADCHS = 0x0005; // Connect RB2/AN2 as CH0 input
// in this example RB2/AN2 is the input
ADCSSL = 0;
ADCON3 = 0x0203; // Sample time = 2Tad, Tad = 95.24 ns @ 21 MIPS
// which will give 1 / (14 * 95.24 ns) = 750 ksps
ADCON2 = 0b111111000000100; // Select external VREF+ and VREF- pins
// Interrupt after every 2 samples
ADCON1bits.ADON = 1; // turn ADC ON
ADCValue = 0; // clear value
ADC16Ptr = &ADCBUF0; // initialize ADCBUF pointer
IFS0bits.ADIF = 0; // clear ADC interrupt flag
ADCON1bits.ASAM = 1; // auto start sampling
// for 31Tad then go to conversion
while (!IFS0bits.ADIF); // conversion done?
ADCON1bits.ASAM = 0; // yes then stop sample/convert
//for (ii = 0; ii <15; ii++) // average the 2 ADC value
{
ADCValue = ADCValue+ *ADC16Ptr++;
}
//ADCValue = ADCValue >> 1;
ADC_float = (float)(ADCValue);
//i=0;
dis_cmd(0x80);
sprintf(ADC_buffer,"%f",ADC_float);
for(ii=0;ii<3;ii++)
{
dis_data(ADC_buffer[ii]);
}
*/
// I1 SHUNT
ADPCFG = 0xFFFB; // all PORTB = Digital; RB2 = analog
ADCON1 = 0x00E0; // SSRC bit = 111 implies internal
// counter ends sampling and starts
// converting.
ADCHS = 0x0002; // Connect RB2/AN2 as CH0 input ..
// in this example RB2/AN2 is the input
ADCSSL = 0;
ADCON3 = 0x0113; // Sample time = 15Tad, Tad = internal Tcy/2
ADCON2 = 0x0004; // Interrupt after every 2 samples
ADCON2bits.SMPI = 15;
//for(kk=0;kk<=10;kk++)
{
for(jj=0;jj<=10;jj++)
{
ADCON1bits.ADON = 1; // turn ADC ON
ADCValue = 0; // clear value
ADC16Ptr = &ADCBUF0; // initialize ADCBUF pointer
IFS0bits.ADIF = 0; // clear ADC interrupt flag
ADCON1bits.ASAM = 1; // auto start sampling
// for 31Tad then go to conversion
while (!IFS0bits.ADIF); // conversion done?
ADCON1bits.ASAM = 0; // yes then stop sample/convert
for (ii = 0; ii < 2; ii++) // average the 2 ADC value
ADCValue = ADCValue + *ADC16Ptr++;
ADCValue = ADCValue >> 1;
dis_cmd(0x80);
ADC_float = (float)((ADCValue)*(5.03/1023)*4);
maxima_average = maxima_average + ADC_float;
}
average[kk] = maxima_average/10;
average[kk] = average[kk]*average[kk];
kk++;
if(kk>=10)
{
kk=0;
for(kk=0;kk<=10;kk++)
average[0] = average[0] + average[kk];
average[0] = average[0]/10;
average[0] = sqrt(average[0]);
//average[kk] = (average[kk]/1.417);
sprintf(ADC_buffer,"%f",average[0]);
kk=0;
average[0]=0;
maxima_average = 0;
for(ii=0;ii<4;ii++)
{
dis_data(ADC_buffer[ii]);
//dis_cmd(0x01);
}
}
//if(average[0]
////dis_cmd(0x01);
}
}