Почему я получаю разные результаты при компиляции одного и того же кода с разными ide?

У меня есть базовый код для чтения true rms.Я скомпилировал тот же код с помощью arduino ide и atmel studio, а затем запустил его в симуляции proteus.Я пытаюсь измерить, сколько времени занимает функция read_rms ().

Мой mcu:attiny84

1.эксперимент)Я добавил плату в arduino ide с помощью board manager.И я выбрал attiny84 и internal 1MHz из меню tools в меню arduino. В результате функция read_rms() заняла 23,25 миллисекунды.

2.эксперимент)Я скомпилировал тот же код без каких-либо изменений в Atmel Studio.Устройство,выбрано attiny84. В результате функция read_rms() заняла 44 миллисекунды.

44 миллисекунды против 23,25 миллисекунд. Почему?

Примечание:В proteus выбраны следующие настройки.Внутренний RC Osc. 8 МГц,а CKDIV8=запрограммирован.

Мой код:

#define F_CPU 1000000UL
#include <avr/io.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stdint.h>   
const uint8_t muxbits = 1<<MUX3 | 1<<MUX2 | 1<<MUX1 | 1<<MUX0;   


void adc_init()
{
    ADMUX = 0;    //Vcc_ref_
    ADCSRA = (1<<ADEN)|(1<<ADPS1)|(1<<ADPS0); //adc_enable_and_prescaler_8_ 125000 Гц (1000000/8)
    //first_try
    ADCSRA |= (1<<ADSC);
    while ((ADCSRA & (1<<ADSC)) != 0);
}

uint16_t adc_read(uint8_t channel)  
{
    ADMUX = (ADMUX & ~muxbits) | channel;
    // start_single_convertion
    ADCSRA |= (1<<ADSC);
    
    // дождитесь завершения преобразования
    while ((ADCSRA & (1<<ADSC)) != 0);
    
    return (ADC);
}
   
double read_rms()
{
    uint16_t i=0;
    uint16_t a_data=0;
    uint32_t sum=0;
    float avarage=0;
    double rms=0;
    for(i=0;i<200;i++)
    {
        a_data=adc_read(1);
        
        sum=sum+(a_data*a_data);
    }
    avarage=(float)sum/200;
    rms=sqrt((double)avarage);
    
    
    return rms;
    
}


int main(void)
{
    
    DDRA|=(1<<7);
    PORTA &=~ (1<<7);       
    adc_init();

    while(1)
    {

    read_rms();    
    PORTA ^= (1<<7);// TOOGLE_PA7 for_measure_time_of_read_rms()_with_oscilloscope
        
    }
}

, 👍1

Обсуждение

Невозможно сказать наверняка. Возможно, Atmel studio использует фактические значения двойной точности для "double", тогда как Arduino использует только "float" (single precision)., @Majenko

Нет ничего невозможного в том, чтобы сказать это. Вы можете сравнить ассемблер, сгенерированный обоими. Я не очень хорошо знаком с ассемблером AVR, так что я не был бы лучшим выбором для этого анализа, но я уверен, что кто-то на этой плате мог бы это понять., @Duncan C

Вы также можете получить что-то вроде нечеткого подтверждения того, отвечает ли float против double , просто изменив свой код, чтобы использовать типы float везде. Это включает в себя использование "sqrtf", а не " sqrt`. Как уже было сказано, могут быть и другие различия, поэтому результаты синхронизации могут не полностью сходиться., @timemage


1 ответ


1

Разные компиляторы создают разный машинный код.

Как отметил Майенко, компилятор Arduino IDE, который является GCC, использует float даже тогда, когда вы пишете double.

Студия Atmel создает double for double, используя в два раза больше битов.

Вычисление с большим количеством битов занимает больше времени.

,

Я действительно парил.результат опять тот же.И я сделал sqrtf вместо sqrt., @harun caliskanoglu

Вы заглядывали в сгенерированную сборку? Там могут быть некоторые неявные преобразования в double, или компилятор Atmel использует стандартный "sqrt ()" даже для " sqrtf ()"., @the busybee

нет, я не обследовался.Но с чего бы это вдруг?Вместо sqrt я набрал sqrtf, потому что не хотел использовать двойные числа без необходимости. Что касается основной проблемы, то я думаю, что она связана с конфигурациями компилятора. Но я еще не понял этого., @harun caliskanoglu