Почему я получаю разные результаты при компиляции одного и того же кода с разными 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 ответ
Разные компиляторы создают разный машинный код.
Как отметил Майенко, компилятор Arduino IDE, который является GCC, использует float
даже тогда, когда вы пишете double
.
Студия Atmel создает double
for double
, используя в два раза больше битов.
Вычисление с большим количеством битов занимает больше времени.
Я действительно парил.результат опять тот же.И я сделал sqrtf вместо sqrt., @harun caliskanoglu
Вы заглядывали в сгенерированную сборку? Там могут быть некоторые неявные преобразования в double
, или компилятор Atmel использует стандартный "sqrt ()" даже для " sqrtf ()"., @the busybee
нет, я не обследовался.Но с чего бы это вдруг?Вместо sqrt я набрал sqrtf, потому что не хотел использовать двойные числа без необходимости. Что касается основной проблемы, то я думаю, что она связана с конфигурациями компилятора. Но я еще не понял этого., @harun caliskanoglu
- Поскольку double и float представляют один и тот же тип данных (обычно), что предпочтительнее?
- Хранение данных в SDRAM Arduino Portenta H7
- устаревшее преобразование из строковой константы в 'char*'
- Какие есть другие IDE для Arduino?
- Esp8266 Vin контакт
- Плата для разработки STM8 с Arduino IDE
- Эквивалент millis() в студии Atmel
- Скрытие пароля WLAN при отправке на GitHub
Невозможно сказать наверняка. Возможно, Atmel studio использует фактические значения двойной точности для "double", тогда как Arduino использует только "float" (single precision)., @Majenko
Нет ничего невозможного в том, чтобы сказать это. Вы можете сравнить ассемблер, сгенерированный обоими. Я не очень хорошо знаком с ассемблером AVR, так что я не был бы лучшим выбором для этого анализа, но я уверен, что кто-то на этой плате мог бы это понять., @Duncan C
Вы также можете получить что-то вроде нечеткого подтверждения того, отвечает ли
float
противdouble
, просто изменив свой код, чтобы использовать типыfloat
везде. Это включает в себя использование "sqrtf", а не " sqrt`. Как уже было сказано, могут быть и другие различия, поэтому результаты синхронизации могут не полностью сходиться., @timemage