Я тестировал некоторые функции зуммера на ATtiny85 и заметил странные колебания использования памяти fla sh при изменении постоянных аргументов функции.
Более подробно, компилируя следующий код памяти занято 162 байта
int main(){
beep_once(1000,500);
silence(1000);
beep_once(1000,500);
silence(200);
for(;;){ }
}
При изменении первого beep_once(1000,500);
на beep_once(1500,500);
размер программы становится 1378 байтов.
Кстати, я использую PlatformIO, которая компилируется через avr -g cc. Используя проверку памяти PlatformIO, я вижу, что c. 1кб памяти из-за unknown .
Надеюсь, кто-нибудь поможет мне понять, что происходит и на какой стороне проблема: PlatformIO, компилятор или это я.
Вот полный код, использованный для теста:
#include <avr/interrupt.h>
#define F_CLK 1000000
void silence(unsigned int);
void beep_once(unsigned int, unsigned int);
int main(){
beep_once(1500,500);
silence(1000);
beep_once(1000,500);
silence(200);
for(;;){ }
}
void silence(unsigned int duration)
{
TCCR1 = 5; // Set the prescaler to 16 bit.
OCR1A = 61; // Tops at 1ms with prescaler of 16x
unsigned int counter=duration;
do
{
if ((TIFR >> OCF1A) & 0x01)
{
counter--;
TCNT1 = 0; // Reset counter to 0
TIFR |= 1 << OCF1A; // Clear the flag
}
} while (counter);
TCCR1 &= ~((1 << CS12) | (1 << CS11) | (1 << CS10)); // Stop the timer
}
void beep_once(unsigned int frequency /*Herz*/, const unsigned int duration /*milliseconds*/)
{
/*
* The frequency is given by:
* Freq = F_CLK / (prescaler * (1 + OCR1C))
*/
TCCR1 |= (5 << CS10) |(1 << CTC1); // Set the prescaler to 16 bit (for 1MHz)(freq range from 31kHz to 250 Hz)
OCR1C = (uint8_t)((F_CLK / frequency) >> 5); // divided by the prescaler (16)
TIMSK &= ~(1 << OCIE1B); // Disable timer compare interrupt
GTCCR |= 1 << COM1B0; // Timer Counter Comparator B connected to output pin OC1B.
unsigned int counter = duration * ((float)frequency / 1000.) * 2;;
do
{
if ((TIFR >> OCF1B) & 0x01)
{
counter--;
TIFR |= 1 << OCF1B; // Clear the flag
}
} while (counter);
TCCR1 &= ~((1 << CS12) | (1 << CS11) | (1 << CS10)); // Stop the timer
GTCCR &= ~(1 << COM1B0); // Timer Counter Comparator B disconnected from output pin OC1B.
}