Страница 16 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс фев 20, 2011 15:56:47
ChipKiller
HeLiO писал(а):Не вредно ли это с точки зрения оптимизации -не жрет ли оперативу, не забивает ли стек такие действия..? или лучше по возможности уменьшать их количество - в общем есть ли на это какие нибудь ограничения или нет? Компилятор IAR для ядра 8051
... любой вызов функции работает медленнее inline-кода, но экономит Flash - что важнее выбирать разработчику. Если в функции не используется рекурсия, и не передается куча параметров по значению, то чаще всего стек (он же RAM) не "умирает". На счет ограничений - все хорошо в меру

Re: Вопросы по С/С++ (СИ)
Добавлено: Вс фев 20, 2011 16:13:30
ARV
ChipKiller писал(а):HeLiO писал(а):Не вредно ли это с точки зрения оптимизации -не жрет ли оперативу, не забивает ли стек такие действия..? или лучше по возможности уменьшать их количество - в общем есть ли на это какие нибудь ограничения или нет? Компилятор IAR для ядра 8051
... любой вызов функции работает медленнее inline-кода, но экономит Flash - что важнее выбирать разработчику. Если в функции не используется рекурсия, и не передается куча параметров по значению, то чаще всего стек (он же RAM) не "умирает". На счет ограничений - все хорошо в меру

не совсем так, не всегда так

например, нормальный компилятор умеет встраивать автоматически static-функции в код, т.е. что функция, что обычный код - по скорости и объему разницы не будет.
но конкретно про поведение IAR для x51 - тут я пас, не знаю. но общее мнение остается таким: раз уж взялся за язык высокого уровня, то писать надо так, как на нем УДОБНО, а не думать о байтах памяти и микросекундах выполнения.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс фев 20, 2011 19:26:59
HeLiO
ARV писал(а):ChipKiller писал(а):
... любой вызов функции работает медленнее inline-кода, но экономит Flash - что важнее выбирать разработчику. Если в функции не используется рекурсия, и не передается куча параметров по значению, то чаще всего стек (он же RAM) не "умирает". На счет ограничений - все хорошо в меру

не совсем так, не всегда так

например, нормальный компилятор умеет встраивать автоматически static-функции в код, т.е. что функция, что обычный код - по скорости и объему разницы не будет.
но конкретно про поведение IAR для x51 - тут я пас, не знаю. но общее мнение остается таким: раз уж взялся за язык высокого уровня, то писать надо так, как на нем УДОБНО, а не думать о байтах памяти и микросекундах выполнения.
Про последнее не соглашусь - даже в виндах ищут возвожности для оптимизаций например - что теперь им на ассе писать что ли?) а вообще за совет(ты) спасибо.
У меня функции ничего не принимают, иногда имеют свои собственные внутренние переменные (которые в стеке буду хранится), функции небольшие по размерам (5-10 строк). И вопрос собственно заключался, не сильно ли вредит скорости работы МК частое обращение к функциям. Проц у меня совсем слабый - это Nordi - еле дышит 1+ 1 складывает такое ощущение что секунду)) Ассемблер не знаю (и не хчоу знать), вот и ищу ввсе возможные способы уменьшения нагрузки на МК
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс фев 20, 2011 19:52:01
ChipKiller
Ассемблер не знаю (и не хчоу знать), вот и ищу ввсе возможные способы уменьшения нагрузки на МК
... можно писать на С и не зная ассемблера (собственно для этого и есть ключи оптимизации ) - просто знание последнего дает дополнительные знания.
например
при одинаковом результате последний пример работает быстрее - ведь в первом случае "умный" компилятор будет именно
умножать, а если в машинных инструкциях нет операции умножения - появляется "торможение".
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс фев 20, 2011 19:56:53
HeLiO
ChipKiller писал(а):Ассемблер не знаю (и не хчоу знать), вот и ищу ввсе возможные способы уменьшения нагрузки на МК
... можно писать на С и не зная ассемблера (собственно для этого и есть ключи оптимизации ) - просто знание последнего дает дополнительные знания.
например
при одинаковом результате последний пример работает быстрее - ведь в первом случае "умный" компилятор будет именно
умножать, а если в машинных инструкциях нет операции умножения - появляется "торможение".
ну само собой дисассемблированием частенько пользуюсь.. но далеко не всегда, потому как раздражает и тормозит работу, да и пока что не делал ничего такого, что реально бы съедало ресурсы сверх меры. Я больше написал про не знаю и не хочу знать в противоввес товарищу, котоырй писал что если уж писать на языках верхнего уровня то забыть обо всём нужно обязательно- это не так, и с вами я согласен.
Так а с функциями не дадите совет всё таки - если 1 функция взять просто и разрезать на 8-9 маленьких - не сильно это повредит скорости работы..?
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс фев 20, 2011 20:01:58
ChipKiller
Так а с функциями не дадите совет всё таки - если 1 функция взять просто и разрезать на 8-9 маленьких - не сильно это повредит скорости работы..?
... думаю
ARV писал как раз об этом. А именно "нормальный" С-компилятор там, где это возможно оптимизирует ваш код - если задана оптимизация по-скорости, он (компилятор) заменит вызовы функций их inline-кодом.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс фев 20, 2011 20:13:32
HeLiO
Все ,понял. Всем спасибо за советы
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс фев 20, 2011 23:15:29
aeroplan-t50
ibiza11 писал(а):Код: Выделить всё
unsigned char a[9]={1,2,3,4,5,6,7,8,9};
unsigned char b[9];
unsigned char i=0;
unsigned char j=8;
...
while (i<9)
{
b[j]=a[i];
i++;
j--;
}
А если так:
Код: Выделить всё
unsigned char a[9]={1,2,3,4,5,6,7,8,9};
unsigned char b[9];
unsigned char i, j=8;
...
for(i = 0; i<9 ; b[j--] = a[i++]);
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн фев 21, 2011 06:39:00
ibiza11
aeroplan-t50 писал(а):
А если так:
Код: Выделить всё
unsigned char a[9]={1,2,3,4,5,6,7,8,9};
unsigned char b[9];
unsigned char i, j=8;
...
for(i = 0; i<9 ; b[j--] = a[i++]);
Что письками меряться будем?

Начинающий товарищ просил пример, я привел наиболее простой для понимания. когда он почитает док "эффективное программирование на Си для AVR" тогда и поменяет while на for и переменные объявлять будет в одну строчку.
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб фев 26, 2011 19:13:47
levaclaus
вопрос
есть переменная temp, в которой хранится температура. Бывает она >= 0 или <0.
Далее формируется строка для вывода на экран
что бы строка оставалась статичной при появлении минуса и его пропаже, как записать условие вывода строки?
lcd_gotoxy(9,0); //Курсор в 9-й столбец, 0-я строка
if (temp<0);
sprintf(lcd_buffer,"\xfa%i\xeeC",temp,temp%1); //если температура отрицательна, строка вывода будет С-1'С
lcd_puts(lcd_buffer); //выводим масив на LCD
else
sprintf(lcd_buffer,"\xfa+%i\xeeC",temp,temp%1); //иначе строка будет С+1'С
lcd_puts(lcd_buffer); //выводим масив на LCD
cvavr матерится на ELSE, no matching if
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб фев 26, 2011 19:20:38
ChipKiller
levaclaus писал(а):cvavr матерится на ELSE, no matching if
... заключите все что отноится к
if и
else в
{}
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб фев 26, 2011 19:28:23
md5sum
И точку с запятой после if(...) убрать не помешало-б

Re: Вопросы по С/С++ (СИ)
Добавлено: Сб фев 26, 2011 19:35:50
ChipKiller
md5sum писал(а):И точку с запятой после if(...) убрать не помешало-б

... при записи
else должно идти следующей строкой , но похоже автору все равно ....

Re: Вопросы по С/С++ (СИ)
Добавлено: Сб фев 26, 2011 22:19:46
levaclaus
записал так
{
if (temp<0)
sprintf(lcd_buffer,"\xfa%i\xeeC",temp,temp%1);
else
sprintf(lcd_buffer,"\xfa+%i\xeeC",temp,temp%1);
lcd_puts(lcd_buffer); //выводим масив на LCD
}
заработало, спасибо.
а как ещё можно обновлять строку, кроме lcd_clear();?
Температура бывает 1 знак (9) и 2 знака (10), при переходе на 1 знак, второй символ остаётся на экране. Можно было бы заюзать lcd_clear();, но тогда начинает моргать экран
Нужно как то заставить обновляться этот массив на экране, не трогая остальные данные
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб фев 26, 2011 22:46:38
ut1wpr
levaclaus писал(а):записал так
{
if (temp<0)
sprintf(lcd_buffer,"\xfa%i\xeeC",temp,temp%1);
else
sprintf(lcd_buffer,"\xfa+%i\xeeC",temp,temp%1);
lcd_puts(lcd_buffer); //выводим масив на LCD
}
заработало, спасибо.
а как ещё можно обновлять строку, кроме lcd_clear();?
Температура бывает 1 знак (9) и 2 знака (10), при переходе на 1 знак, второй символ остаётся на экране. Можно было бы заюзать lcd_clear();, но тогда начинает моргать экран
Нужно как то заставить обновляться этот массив на экране, не трогая остальные данные
Почитайте все, что касается форматированного вывода. В вашем случае достаточно указать размерность выводимых чисел, равных 2 с выводом лидирующего пробела.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн фев 28, 2011 00:46:27
levaclaus
ut1wpr
спасибо, вроде как разобрался, осталось отрицательную температуру проверить...
сделал так
lcd_gotoxy(10,0);
{
if (temp<0)
sprintf(lcd_buffer,"\xfa%02i\xeeC",temp,temp%02);
else
sprintf(lcd_buffer,"\xfa+%02i\xeeC",temp,temp%02);
lcd_puts(lcd_buffer);
}
ещё вопрос
temp=ds18b20_temperature(0); //считываем температуру
как только эта строка попадает в основной цикл программы, перестаёт работать кнопка настройки часов. Как это связано, немогу понять. При этом прерывания работают, настроить можно с пульта. Как вариант можно попробовать завести кнопку настройки на прерывание, но хотелось бы програмно обойтись
если эта строка вне основного цикла, температура считывается один раз при загрузке и всё. Как быть, кто подскажет - хотелось бы и термометр и кнопку настройки оставить
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн фев 28, 2011 09:50:47
md5sum
Есть подозрения что,
ChipKiller писал(а):заключите все что отноится к if и else в {}
Имелось в ввиду
Код: Выделить всё
if (temp<0) {
sprintf(lcd_buffer,"\xfa%02i\xeeC",temp,temp%02);
} else {
sprintf(lcd_buffer,"\xfa+%02i\xeeC",temp,temp%02);
}
lcd_puts(lcd_buffer);
levaclaus писал(а):ещё вопрос
temp=ds18b20_temperature(0); //считываем температуру
как только эта строка попадает в основной цикл программы, перестаёт работать кнопка настройки часов. Как это связано, немогу понять.
А подольше кнопку держать?
Связано это скорее всего с тем, то измерение температуры в "лоб" занимет чуть меньше секунды и Ваша программа в это время ждет ответа датчика и никаких действий в основном цикле не выполняет. А прерывания на то они и прерывания...
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн фев 28, 2011 10:47:06
ChipKiller
md5sum писал(а):Есть подозрения что,
... даже не думал, что можно по-другому понять ... мда
levaclaus писал(а):как только эта строка попадает в основной цикл программы, перестаёт работать кнопка настройки часов
... приведите весь код во вложенном файле - программист и медиум не одно и то же.

Re: Вопросы по С/С++ (СИ)
Добавлено: Пн фев 28, 2011 23:29:00
levaclaus
вот исходник
-------
@я не волшебник, я только учусь@
if (temp<0)
{
sprintf(lcd_buffer,"\xfa %02i",temp,temp%02);
}
else
{
sprintf(lcd_buffer,"\xfa+%02i",temp,temp%02);
}
lcd_puts(lcd_buffer); //выводим масив на LCD
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт мар 01, 2011 10:49:46
ChipKiller
levaclaus писал(а):как только эта строка попадает в основной цикл программы, перестаёт работать кнопка настройки часов. Как это связано, немогу понять.
... строка
Код: Выделить всё
temp=ds18b20_temperature(0); //читаем температуру
..работает при выключенных прерываниях. Без коренной переделки попробуйте следующее - настройте на 9-ти битное преобразование (по умолчанию оно 12-ти битное), при этом время преобразования уменьшится в 8 раз.
Что касается
Часы.rar - очень активно пользуетесь библиотечными функциями, хотя их возможности используются % на 20 - может проще написать самому? ... размер hex-файла при этом сильно уменьшится. Некоторые вещи не стоит делать "в лоб" - проявите фантазию

(все сказанное ИМХО - не правило и на Ваш вкус....)
например:
Код: Выделить всё
switch (month) //Определение максимального дня в месяце
{
case 1: maxday=31; break;
case 2: maxday=29; break;
case 3: maxday=31; break;
case 4: maxday=30; break;
case 5: maxday=31; break;
case 6: maxday=30; break;
case 7: maxday=31; break;
case 8: maxday=31; break;
case 9: maxday=30; break;
case 10: maxday=31; break;
case 11: maxday=30; break;
case 12: maxday=31; break;
}
проще написать так
Код: Выделить всё
flash char tab_maxday[12]={31,29,31,30,31,30,31,31,30,31,30,31};
.....
maxday=tab_maxday[month-1];
.. результат тот-же, но работает быстрее и занимает меньше места.