Помогите ужать програаму, немного не влезает в ATTiny13
Компилятор должен соблюдать порядок действий, предписанный стандартом. ) И если речь идет о плавающей точке - там еще можно сделать такое упрощение. НО с целыми числами.. это должен быть очень плохой компилятор.. )
Fucking static initialization order fiasco
- Реклама
То есть CV еще и менее оптимально код переводит в инструкции?
ПС: Видимо с этого и начинают переходить на другие компиляторы.
Чувствую вы сейчас сожмете так что вся память высвободится
Это как понимать? Чтобы все переменные в выражених и результаты вычислений были не более 16бит?Важнее переход к 16-ти битным операциям.
ПС: Видимо с этого и начинают переходить на другие компиляторы.
Чувствую вы сейчас сожмете так что вся память высвободится
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
уже предлагал автору подсократить:Ведь толковый компилятор что должен сделать? Правильно, на этапе компиляции посчитать, что 5000/1024 = 4.
5000/1024=1250/256
т.е. достаточно значение ацп умножить на 1250 (получится long) и сдвинуть вправо на 8:
Voltage = (unsigned int)(((unsigned long)ADC*1250)>>8);
- Сообщения: 410
- Зарегистрирован: Чт ноя 13, 2008 16:33:42
Таки Вы правы. Стандарт предписывает строгую ассоциативность в случае смешения операций "*" и "/". Это я спутал с другим языком программированияPink-Pank писал(а):Компилятор должен соблюдать порядок действий, предписанный стандартом.
Совсем не факт. Ваш первоначальный код в GCC был более 1200 байтGisteresis писал(а):То есть CV еще и менее оптимально код переводит в инструкции?
Скорее всего компилятор сам справится с этой задачей. Вот как GCC выполнил "/1024/64"oleg110592 писал(а): т.е. достаточно значение ацп умножить на 1250 (получится long) и сдвинуть вправо на 8:
Код: Выделить всё
movw r22,r24
clr r24
clr r25
- Сообщения: 238
- Зарегистрирован: Чт фев 28, 2013 14:16:10
Ничего я не понял, извините. Есть флеш (память программы), есть ОЗУ (RAM). Как правило, сколько кодил, чаще не хватает именно RAM.Gisteresis писал(а): ks0, компилятор говорит что РАМ, но увеличиваю рам чтобы все глобальные переменные влезли. Потом появляется окно в котором говорится что мы вылезли за пределы 512слов... что то порядка 546слов получалось. (В общем более одного килобайта)
И что значит "увеличиваю рам". Это как вообще?!
Я посмотрел программу, но у меня только AVR Studio с GCC, не на чем протестить. Но такой функционал однозначно легко вписывается на аттини13. И проблем с флешем вообще быть не должно. А вот в 64 байта рам может и не влезть вся эта куча глобальных переменных! Отвыкайте кодить как на компе.
Здесь иногда для экономии оперативки лучше делать, так
Код: Выделить всё
switch(a){
case 1: PORTB |= 0b01; break;
case 2: PORTB |= 0b10; break;
case 3: PORTB |= 0b11; break;
.... }
Код: Выделить всё
char n[]={0b01, 0b10, 0b11, ....};
PORTB |= n[a];
- Реклама
- Сообщения: 410
- Зарегистрирован: Чт ноя 13, 2008 16:33:42
Как раз в GCC RAM используется на 56%, а вот флеша не хватает. Вам же никто не мешает откомпилировать это в Студии? Правки минимальны. Что касается volatile, то оно там по-делу, поскольку cDigit используется в двух разных прерываниях.ks0 писал(а): А вот в 64 байта рам может и не влезть вся эта куча глобальных переменных!
- Сообщения: 238
- Зарегистрирован: Чт фев 28, 2013 14:16:10
itoa использовать был вариант, чтоб от делений избавиться?
Смотрел варианты перевода цифр в строку.
Не дошло. Чем помогает itoa при переводе в код семисегментного? Там что, значение цифры совпадает с таблицей символов?
Не дошло. Чем помогает itoa при переводе в код семисегментного? Там что, значение цифры совпадает с таблицей символов?
- Сообщения: 238
- Зарегистрирован: Чт фев 28, 2013 14:16:10
Простой вариант. Попробуйте делить на sCounterASum когда он приравнивается 0, т.е. байт переполняется, фактически пропишите деление на 256, оно выполнится просто сдвигами. Куча экономии.
Если все еще нужно, выкладываю проект. (с ужасным невлезающим в кристалл кодом)
- Вложения
-
- Программа Милливольтметр 0..50В 0..5А Дисплей 4х2.zip
- (4.12 КБ) 157 скачиваний
- Сообщения: 238
- Зарегистрирован: Чт фев 28, 2013 14:16:10
Вот такое работает?
Код: Выделить всё
sCounterVSum++;
if( !sCounterVSum )
{
unsigned int t= *((unsigned int*)&ulVoltsSum+1); // берем старшие 2 байт (т.е. делим на 256)
cDigit[0][0] = ~cSeg[((t/1000)%10)];
cDigit[1][0] = ~cSeg[((t/100 )%10)];
cDigit[2][0] = ~cSeg[((t/10 )%10)];
cDigit[3][0] = ~cSeg[((t/1 )%10)];
ulVoltsSum = 0;
} Код влез. Но работает не так как надо. В момент первого включения цифры пробегаются и все.Pink-Pank писал(а):Вот такой код у меня уже влез. Единственное, в настройках проекта поставил поменьше размер стека (14 байт). как раз ровно под его размер.
А изначально- то код рабочий был? А то я его не особо ковырял. Только на предмет явных ошибок и неточностей.
Fucking static initialization order fiasco
Pink-Pank
Изначально код был рабочий, но под один АЦП, был просто милливольтметр. Остальное все тоже самое.
При переделке в 2 АЦП, забыл изменить ноги вывода. Поправил. Заработал дисплей.
vdavid, вставил ваш код, он заработал. Предыдущий вариант показывал все сегменты на индикаторах.
Последний код стал показывать, но первая декада всегда 0. Значение начинает отображаться со второй декады. Значение выводится правильное.
Не успел попробовать, думаю просто в цикле нужно к i прибавить или отнять 1. Тогда значение будет отображаться с первой декады.
Всем котам спокойной ночи.
Изначально код был рабочий, но под один АЦП, был просто милливольтметр. Остальное все тоже самое.
При переделке в 2 АЦП, забыл изменить ноги вывода. Поправил. Заработал дисплей.
vdavid, вставил ваш код, он заработал. Предыдущий вариант показывал все сегменты на индикаторах.
Последний код стал показывать, но первая декада всегда 0. Значение начинает отображаться со второй декады. Значение выводится правильное.
Не успел попробовать, думаю просто в цикле нужно к i прибавить или отнять 1. Тогда значение будет отображаться с первой декады.
Всем котам спокойной ночи.
- Сообщения: 410
- Зарегистрирован: Чт ноя 13, 2008 16:33:42
Да, должно быть так:
и так:
Код: Выделить всё
i=4;
while (i>0) {
i--;
cDigit[i] = ~cSeg[ulVoltsSum%10];
ulVoltsSum /=10;
} Код: Выделить всё
i=8;
while (i>4) {
i--;
cDigit[i] = ~cSeg[ulAmpersSum%10];
ulAmpersSum /=10;
}Работает, вывел еще десятичную точку. Всетаки 64 отсчетов в усреднении мало, рябит. Сейчас разбираюсь в вашем коде, хочу еще сделать отсчетов 256 (на 300 нормально выводило) и поменять уже на реальные 50В и 5А.
В начале не мог понять почему десятичная точка не выводится, а у меня число выводится по снятым битам, операция |= наоборот ее гасила
В начале не мог понять почему десятичная точка не выводится, а у меня число выводится по снятым битам, операция |= наоборот ее гасила
Спойлер
Код: Выделить всё
if( input_index == 2 )
{
ulVoltsSum += ADCW;
sCounterVSum++;
if( sCounterVSum == 64 )
{
ulVoltsSum=(5000UL*ulVoltsSum)>>16;
i=4;
while (i>0) {
i--;
cDigit[i] = ~cSeg[ulVoltsSum%10];
ulVoltsSum /=10;
}
cDigit[1] &= ~0b10000000;
ulVoltsSum = 0;
sCounterVSum = 0;
}
}
if( input_index == 3 )
{
ulAmpersSum += ADCW;
sCounterASum++;
if( sCounterASum == 64 )
{
ulAmpersSum=(5000UL*ulAmpersSum)>>16;
i=8;
while (i>4) {
i--;
cDigit[i] = ~cSeg[ulAmpersSum%10];
ulAmpersSum /=10;
}
cDigit[4] &= ~0b10000000;
ulAmpersSum = 0;
sCounterASum = 0;
}
}Сколько по памяти получилось? А то надо байт 30 минимум на стек оставлять при использовании математики и прерываний.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- Сообщения: 410
- Зарегистрирован: Чт ноя 13, 2008 16:33:42
Нет, не мало. О чем речь? Болтанка сильная или частые обновления приводят к мельтишению? Болтанку можно дополнительно уменьшить конденсаторами на входах АЦП. Ну и, естественно, посмотреть на разводку земли. Кроме того шумы будут от коммутации индикаторов. Возможно надо развязать питание МК LC фильтром.Gisteresis писал(а): Всетаки 64 отсчетов в усреднении мало,
Частота же обновления уменьшается тысячей и одним способом без изменения числа отсчетов.
Впрочем, если очень хочется, то вот Вам 256 отчетов. Пробуйте.
- Вложения
-
- rk2.zip
- (4.07 КБ) 155 скачиваний


