Перейти к содержанию
    

Работа таймера TMR0 (PIC16)

я убедился в том, что удивительный лодырь, обладающий определенным талантом напрячь окружающих на решение ваших задач. Сами думать вы, почему то, категорически не хотите.

Я всего лишь прошу инфу по работе предделителя. А применю формулу расчета частоты прерываний самостоятельно. Лодырь тот, кто не написал ее в даташите. Я понимаю, что надо все делать через...осциллограф в данном случае. Может, сразу частотомер купить? (ну не даст осциллоскоп нужной точности...) Для эмпирического нахождения секретной формулы, которую никто не знает, а я напрягаю бедный форум ее выводить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но вот связать настройку предделителя с частотой на выходе... При кварце 4 МГц Fosc/4 = 1 МГц. Как считать частоту прерываний при коэфф. деления предделителя 2, 4... 256 ?

Можно в уме, можно в столбик на бамажке, можно в куркуляторе. По-любому, сначала нужно представлять, как оно работает.

1. Задаёте частоту тактирования таймера и желаемую частоту F (или период) его прерываний.

2. Находите частное (или произведение) первого и второго. Обзовём его A.

3. (ceil(log2(A)) - (разрядность таймера)) даст Вам требуемый коэффициент деления прескейлера

4. A/2^(ceil(log2(A)) - (разрядность таймера)) даст Вам TMRx_PRESET

 

В случае, если у Вас есть причины заставить TMRx работать с определённым коэффициентом деления прескейлера, п.3. пропускается.

 

Когда надоедает считать самому, после недолгих раздумий эта работа поручается препроцессору. Правда, п.1 таки приходится выполнять самому.

 

Я всего лишь прошу инфу по работе предделителя... Лодырь тот, кто не написал ее в даташите.

Предделитель делит. Трансформатор делает "у-у-у-у". "- Лодка? Она утонула."

Капитан Очевидность уже спешит к Вам на помощь.

Я понимаю, что надо все делать через...осциллограф в данном случае.

В МПЛаб есть симулятор (МПСим), View->Logic Analizer позволит Вам в данном случае съэкономить на частотомере и осциллоскопе.

Если ещё и ман к МПСим прочитаете, то не придётся так часто менять ZF-сокет. А потом и до ICSP доберётесь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот-вот. Именно про это я писал. Выдавил таки топик-стартер кучу информации с форума, вместо персонального шевеления мозгами! Не хочет человек сам думать, хоть режь его. Чудеса, да и только. И при этом все излагает с фантастическим ехидством.

 

P.S. Осциллограф - главнейший прибор электронщика.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

xemul, спасибо.

Буду разбираться. Проблема в том, что без предзагрузки таймер физически не может выдать желаемую частоту прерываний...

Пока что считаю для 8-разрядного таймера так:

Частота прерываний TMR0 (при Fosc/4, для 4 МГц, коэфф. - 256) = (1000000)/256/256 = 15,2587890625 Гц

Частота прерываний TMR0 (при Fosc/4, для 4 МГц, коэфф. - 64) = (1000000)/256/64 = 61,03515625 Гц

Частота прерываний TMR0 (при Fosc/4, для 4 МГц, коэфф. - 16) = (1000000)/256/16 = 244,184375 Гц

 

P.S. srergeeff, Мозги - вот главный прибор разработчика электронной аппаратуры. Тому, кто первый начал, нечего жаловаться по поводу ответного ехидства. :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Буду разбираться. Проблема в том, что без предзагрузки таймер физически не может выдать желаемую частоту прерываний...

Пока что считаю для 8-разрядного таймера так:

Частота прерываний TMR0 (при Fosc/4, для 4 МГц, коэфф. - 256) = (1000000)/256/256 = 15,2587890625 Гц

Частота прерываний TMR0 (при Fosc/4, для 4 МГц, коэфф. - 64) = (1000000)/256/64 = 61,03515625 Гц

Частота прерываний TMR0 (при Fosc/4, для 4 МГц, коэфф. - 16) = (1000000)/256/16 = 244,184375 Гц

Ну объясните мне, с чем здесь разбираться? Всё на уровне арифметики, если держать в голове 2^n для n хотя бы до 16.

Пусть хочется получить 50 Гц.

1000000/50 = 20000 - столько периодов тактовой частоты таймера помещается в 1 период требуемой частоты.

Сначала ищете требуемый прескейлер: (1000000/50)/256 = 78.125

Округляете вверх до степени 2: = 128 (в предыдущем посте я сначала неправильно написал, что округлять нужно вниз)

Считаете предустановку таймера: (1000000/50)/128 = 156

 

Далее в симуляторе ставите точку останова в нужном месте и смотрите, насколько врёт таймер. (а врать он будет и из-за целочисленности арифметики, и из-за сброса прескейлера при записи в таймер)

 

Если считать ручками, можно ещё проще.

20000 округляете вверх до степени 2: = 32768 = 2^15

Из 15 на таймер приходится 8 разрядов, значит степень предделителя 7.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мозги - вот главный прибор разработчика электронной аппаратуры

 

99% ошибок работы с железом состоит в том, что мы думаем или предполагаем, что оно должно работать так-то, а на самом деле работает оно по-другому. Вы зря ехидничаете насчет осциллографа. Это инструмент для действительного контроля работы вашей программы на реальном железе (в том случае, если это можно вообще как-то проанализировать или померять). Или у вас его нет? Тогда, пардон.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну объясните мне, с чем здесь разбираться?

с информацией из #17. С Протеусом пока нехочу связываться - на реальном железе быстрее. Ненадо ни инсталляху искать, ни разбираться с управлением.

Это инструмент для действительного контроля работы вашей программы на реальном железе

не спорю. Но в моем случае глазом видно, что при суммировании временных промежутков прерываний TMR0 частота слишком велика. Мой С1-68 все равно ее точно не покажет, не цифровик чай. (Лодырям вот сюда, на калькулятор http://pictimer.picbingo.com/download/index.php который просчитает и настройку, и предзагрузку, и даже код на С выдаст.)

Изменено пользователем loghir

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос на засыпку: откуда вы знаете, что ваш обработчик прерывания по таймеру 0 работает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С Протеусом пока нехочу связываться - на реальном железе быстрее.

Заниматься такими странностями Вам никто и не предлагал.

Отладка в железе может быть быстрее только при наличии железного отладчика или продуманного и отлаженного самопального способа общения с программой. У Вас нет ни того, ни другого, поэтому и тычетесь наугад в потёмках.

Я не понимаю, почему Вы упорно не желаете отлаживать свои программы в симуляторе МПЛаба - используемые Вами фичи контроллера он показывает во всех подробностях. А если ещё поймёте, зачем нужны стимулы, то можете справиться и с не-симулируемыми фичами. Через неделю Вы или поймёте, как оно (и контроллер, и симулятор) работает, или ... не поймёте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос на засыпку: откуда вы знаете, что ваш обработчик прерывания по таймеру 0 работает?

цифры на индикаторе меняются. Но очень быстро.

void interrupt isr (void)
{
if (T0IF) 
{
while (tmp100 < 100) // выполняется до тех пор, пока истинно (tmp100 < 100)
{
    T0IE = 0;                // Запрет прерываний по переполнению TMR0
    tmp100 = tmp100 + 1;    // прибавление до 100 (в сумме 1 сек)
    TMR0 = TMR0 + 100;        // предзагрузка TMR0
    PS2  = 1;    // bit 2 Настройка предделителя
    PS1  = 0;    // bit 1 Настройка предделителя
    PS0  = 1;    // bit 0 Настройка предделителя
    GIE = 1;                // разрешены все немаскированные прерывания
    T0IF = 0;                 // сброс флага прерывания по переполнению TMR0
    T0IE = 1;                // Разрешение прерывания по переполнению TMR0
}
time1 = time1 + 1;            // счет сотен циклов TMR0. Это число выводится 7-сегментный индикатор.
tmp100 = 0;                    // обнуление счетчика
}
}

где-то ошибка... Но где?

Отладка в железе может быть быстрее только при наличии железного отладчика или продуманного и отлаженного самопального способа общения с программой. У Вас нет ни того, ни другого, поэтому и тычетесь наугад в потёмках.

В процессе тыканья отрабатываю самопальный способ. Всего-то надо 2 таймера запустить.

Я не понимаю, почему Вы упорно не желаете отлаживать свои программы в симуляторе МПЛаба

нет времени и смысла разбираться, как он работает. (Там наверняка свои глюки есть. Вот будет смеху, если в в симуляторе МПЛаба все заработает, а в железе - нет.) Ради запуска 2-х таймеров?! В моей задаче точность не нужна. Всегда можно положить на таймеры и сделать простым суммированием машинных циклов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

смутная программка :)

а не могли бы вы еще раз уточнить, что конкретно нужно в итоге получить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

где-то ошибка... Но где?

"- В ДНК." (из анекдота)

(я устал комментировать бездумное нагромождение букафф)

В процессе тыканья отрабатываю самопальный способ. Всего-то надо 2 таймера запустить.

 

нет времени и смысла разбираться, как он работает. (Там наверняка свои глюки есть. Вот будет смеху, если в в симуляторе МПЛаба все заработает, а в железе - нет.) Ради запуска 2-х таймеров?! В моей задаче точность не нужна. Всегда можно положить на таймеры и сделать простым суммированием машинных циклов.

Флаг в руки, барабан на шею. Каждый сам себе злобный буратин.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

xemul

в #14 я всего-навсего спросил, как рассчитать частоту прерываний TMR0 в зависимости от записанного в битах PS0...PS2. И более ничего! Нужную мне частоту я получу простым суммированием. Если много информации, я просто в ней теряюсь. Поэтому я не принимаю во внимание некоторые советы, ибо стараюсь делать программу (и процесс ее написания) попроще.

 

по поводу обработчика прерываний TMR0: он точно запускается, поскольку цифры на индикаторе меняются, и после нажатия RA1 счет прекращается. Частота прерываний TMR0 после предделителя у меня 100 Гц. Суммируя 100 временных интервалов прерываний я получаю 1 Гц, что и требуется. В #25 я написал мой обработчик прерываний для TMR0. Но цифры на индикаторе очень быстро меняются! Что-то там не так...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

xemul

в #14 я всего-навсего спросил, как рассчитать частоту прерываний TMR0 в зависимости от записанного в битах PS0...PS2. И более ничего!

Эта информация есть в даташите в том месте,где описаны биты PS0...PS2. (описание регистра OPTION).

Коэффициент деления, вносимый пресалером, там указан в виде таблички.

Точно вычислить коэффициент предзагрузки TMR0 "по формуле" не представляется возможным,

поскольку не определен интервал времени между моментом прерывания и моментом предзагрузки - этот интервал

зависит от того, как написана ваша подпрограммы обработки прерывания(ППОП).

Обычно сначала грубо расчитывается частота прерваний, а более точно она подгоняется в дебагере.

Там все очень просто. Ставите точку останова на первом операторе ППОП

и замеряете время между двумя остановами (для этого надо открыть и обнулить окно StopWatch).

Затем вы корректируете константу предзагрузки в нужную сторону.

 

по поводу обработчика прерываний TMR0: он точно запускается, поскольку цифры на индикаторе меняются, и после нажатия RA1 счет прекращается. Частота прерываний TMR0 после предделителя у меня 100 Гц. Суммируя 100 временных интервалов прерываний я получаю 1 Гц, что и требуется. В #25 я написал мой обработчик прерываний для TMR0. Но цифры на индикаторе очень быстро меняются! Что-то там не так...

У вас там все не так.

Не надо трогать в ППОП никаких флагов, кроме флага запроса прерывания. Т.е кроме T0IF = 0; все остальное, включая установки для

PS0...PS2. надо делать один раз вначале основной программы.

Все переменные, которые вы используете а ППОП (tmp100) надо описывать как volatile .

Предзагрузка делается не так: TMR0 = TMR0 + 100; а вот так TMR0 = 100;

И еще, если позволите, маленький совет.

Позиция "какие м...ки пишут эти даташиты!! Там ничего нельзя понять! Да и советы тут дают бестолковые.." не является оптимальной.

Гараздо более продуктивно встать в такую "позу" :

"Да, я, конечно, ламер и туго соображаю, но .. Братцы, выручайте!! Курсовик горит, а препод-зверь смотрит на меня как удав на кролика. ПАМАЖИТЕ!!!"

Такая позиция, как мне кажется, сможет вызвать к вам сочувствие и желание помочь. В отличие от первой позиции.

Удачи!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну как то примерно так

 

unsigned char tmp100 = 0;
unsigned char time1 = 0;

void main(void) {
бла бла настройки таймера и прочей фигни

for (;;) {
if (tmp100 == 100) { 
                           time1++;
                           tmp100 = 0;
                           функция вывода числа time1 на индикатор ();
                           }
}


}

void interrupt isr (void)
{
if (T0IF)
{
TMR0 = 100;
tmp100++;
T0IF = 0;
}
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...