Почему я получаю разные результаты при компиляции одного и того же кода с разными 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
- Программирование микроконтроллера Attiny85 без arduino
Невозможно сказать наверняка. Возможно, Atmel studio использует фактические значения двойной точности для "double", тогда как Arduino использует только "float" (single precision)., @Majenko
Нет ничего невозможного в том, чтобы сказать это. Вы можете сравнить ассемблер, сгенерированный обоими. Я не очень хорошо знаком с ассемблером AVR, так что я не был бы лучшим выбором для этого анализа, но я уверен, что кто-то на этой плате мог бы это понять., @Duncan C
Вы также можете получить что-то вроде нечеткого подтверждения того, отвечает ли
floatпротивdouble, просто изменив свой код, чтобы использовать типыfloatвезде. Это включает в себя использование "sqrtf", а не " sqrt`. Как уже было сказано, могут быть и другие различия, поэтому результаты синхронизации могут не полностью сходиться., @timemage