Страница 1 из 1
Вопросы алгоритмов
Добавлено: Сб июл 03, 2010 20:02:29
Negor
Как мне провернуть в МК такой расчёт: зная частоту с которой должен переполнятся таймер и частоту ядра вычислить количество тиков таймера(предделитель потом подберу). Т.е. как лудше всего вычислить это внутри МК? Там с тробными числами не так всё хорошо, а мне по алгоритму нужно будет работать с периодом одного такта ядра, а это примерно 1/8000000. Вобщем пишу в WinAVR.
Re: Расчёт количества тиков таймера...
Добавлено: Вс июл 04, 2010 09:07:25
Negor
Так что, идей нет? Может сделать всё по другому?
Re: Расчёт количества тиков таймера...
Добавлено: Вс июл 04, 2010 10:44:03
aleksandr-zh
возможно, что я не так понимаю Ваш вопрос, но самое простое - воспользоваться Симулятором.
Протеус
AVR Simulator
http://www.oshonsoft.com/avr.html
запускаете вашу программу в нем, выбираете частоту вашего МК и смотрите...
Re: Расчёт количества тиков таймера...
Добавлено: Вс июл 04, 2010 11:52:50
Negor
Не, МК должен сам считать, что занести в регистр сравнения чтобы частота перепонения таймера была требуемой.
Re: Расчёт количества тиков таймера...
Добавлено: Пн июл 05, 2010 10:08:24
smac
Negor писал(а):Как мне провернуть в МК такой расчёт...
Домножать обязательно, возможно использовать умножение вместо деления на константу (если Вам будет интересно как, то потом я дам ссылки). Однако операции с большими числами занимают много программной памяти (да и не очень быстрые), скажите хотя-бы какой контроллер у вас.
Re: Расчёт количества тиков таймера...
Добавлено: Пн июл 05, 2010 22:04:54
Negor
ATMega8. Ссылки интересны. Сделал через константы.
нужно было
1/заданная_частота/(период_одного_такта_МК)
сделал
1000000000/частота/период_одного_такта_МК*1000000000
всё отлично. Теперь другой вопрос алгоритмизации
Вопрос
(абстрактно)есть некая переменная и 4 события. При наступлении первого события нужно увеличить переменную на 1, второго - на 10 и т.д. до 1000. Но, важно условие - не должно быть переполнения, т.е. если, например, переменная равная 19, то при добавлении 1 она должна быть равной 10 а не 20. или, если 291, то при добавлении 10 - 201. Как это красиво провернуть?
Re: Вопросы алгоритмов
Добавлено: Пн июл 05, 2010 22:20:55
Negor
вариант использования BCD не предлагать
Re: Расчёт количества тиков таймера...
Добавлено: Пн июл 05, 2010 23:23:38
smac
Negor писал(а):ATMega8. Ссылки интересны...
По поводу ссылок - есть такая книга: Уоррен - Алгоритмические трюки для программистов (может быть стоит искать и с вариантом "програмистов"), в торрентах точно есть, может еще где на просторе интернетов найдете, если не найдете, то могу на почту выслать (28 МБ).
Лучше в формулах поставить скобки, явно обозначив порядок действий, например (1/заданная_частота)/(период_одного_такта_МК) либо 1/(заданная_частота/период_одного_такта_МК). Меня терзают смутные сомненья - хочешь задавать период с кнопок? Не проще ли будет тогда посчитать (при выборе тактовой частоты контроллера) время одного тика таймера, допустим в наносекундах и далее все расчеты вести "дважды" - для индикации завести одну переменную и прибавлять числа кратные времени тика, а для установки таймера просто инкрементировать другую переменную. Переменные объединить в структуру. Просто дело в том, что операции сложения на АВР выполняются гораздо легче чем деления, поэтому таким макаром может быть будет быстрее, и даже есть шанс, что короче.
По поводу алгоритма - пока красивого решения предложить не могу.
Re: Вопросы алгоритмов
Добавлено: Вт июл 06, 2010 15:22:52
Bullet
Ну как вариант, конечно не сильно оптимально, но работать будет.
Допустим имеем число 1234, нужно прибавить 10. берем число и делим его на 10, получаем 123, далее, от полученного результата получаем остаток от деления на 10, получаем 3. Если результат меньше 9, значит прибавляем к числу 10, если нет, вычитаем 90.
Re: Вопросы алгоритмов
Добавлено: Вт июл 06, 2010 16:47:35
ARV
когда я делал свой проект "таймер - меньше не бывает", я столкнулся с необходимостью подобных действий, однако решение "в лоб" не прокатило. т.к. шибко много памяти потребовало. пришлось извратиться и сделать
символьные расчеты. примерно так:
Код: Выделить всё
char chislo[6] = "000001"; // 6-разрядное число в СИМВОЛЬНОМ виде
static char increment(uint8_t symb){ // инкремент одного разряда символьного числа
if(++symb > '9') symb = '0';
return symb;
}
void event(uint8_t ev){ // обработка 6 событий для инкремента разряда числа
if(ev < 6)
chislo[ev] = increment(chislo[ev]);
}
если такие действия нужны для вывода на индикатор, то код получается гораздо компктнее, чем всякие умножения-деления и сравнения чисел с последующими преобразованиями для индикации....
Re: Вопросы алгоритмов
Добавлено: Чт июл 08, 2010 13:45:01
Negor
Не, символьно не пойдёт. Вот на такую хитрую штуку натолкнули меня на одном форуме
Код: Выделить всё
int incdec(int a, int delta)
{
int b=a;
b+=delta>0?(a/delta%10==9?-delta*9:delta):(a/delta%10==0?-delta*9:delta);
return b;
}
a - число, над которым будем издеватся. delta - приращение со знаком.