реклама на сайте
подробности

 
 
> Работа таймера TMR0 (PIC16)
loghir
сообщение May 23 2011, 15:43
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 13-03-11
Пользователь №: 63 577



На данный момент проблема в смутном описании бита T0CS регистра OPTION:
Цитата
бит 5: T0CS: Выбор тактового сигнала для TMR0
1 = внешний тактовый сигнал с вывода RA4/T0CKI
0 = внутренний тактовый сигнал CLKOUT

внутренний тактовый сигнал - это Fosc/4?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
loghir
сообщение May 29 2011, 15:34
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 13-03-11
Пользователь №: 63 577



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

по поводу обработчика прерываний TMR0: он точно запускается, поскольку цифры на индикаторе меняются, и после нажатия RA1 счет прекращается. Частота прерываний TMR0 после предделителя у меня 100 Гц. Суммируя 100 временных интервалов прерываний я получаю 1 Гц, что и требуется. В #25 я написал мой обработчик прерываний для TMR0. Но цифры на индикаторе очень быстро меняются! Что-то там не так...
Go to the top of the page
 
+Quote Post
SKov
сообщение May 29 2011, 16:48
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 812
Регистрация: 22-01-05
Из: SPb
Пользователь №: 2 119



Цитата(loghir @ May 29 2011, 19:34) *
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;
И еще, если позволите, маленький совет.
Позиция "какие м...ки пишут эти даташиты!! Там ничего нельзя понять! Да и советы тут дают бестолковые.." не является оптимальной.
Гараздо более продуктивно встать в такую "позу" :
"Да, я, конечно, ламер и туго соображаю, но .. Братцы, выручайте!! Курсовик горит, а препод-зверь смотрит на меня как удав на кролика. ПАМАЖИТЕ!!!"
Такая позиция, как мне кажется, сможет вызвать к вам сочувствие и желание помочь. В отличие от первой позиции.
Удачи!
Go to the top of the page
 
+Quote Post
xemul
сообщение May 29 2011, 17:28
Сообщение #4



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(SKov @ May 29 2011, 20:48) *
Предзагрузка делается не так: TMR0 = TMR0 + 100; а вот так TMR0 = 100;

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

Цитата(sargein @ May 29 2011, 21:14) *
Код
volatile unsigned char tmp100;
...

Go to the top of the page
 
+Quote Post
SKov
сообщение May 29 2011, 18:01
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 812
Регистрация: 22-01-05
Из: SPb
Пользователь №: 2 119



Цитата(xemul @ May 29 2011, 21:28) *
Первый вариант позволяет таки учесть время, прошедшее с момента возникновения прерывания до момента собственно его обработки.

Не совсем так, т.к. при загрузке TMR0 сбрасывается прескалер.
Тогда уж логично сбрасывать не только прескалер, а и сам основной счетчик.
В этом случае мы как раз и получаем второй вариант.Ну, на самом деле это в принципе одно и то же (первый и второй вариант). Просто второй вариант действительно предзагрузка, а первый - предсуммирование или преддобавка, что звучит уж совсем коряво wink.gif
Относительно "равномерно размазанного" интервала я не понял.
Если предзагрузку ставить вначале ППОП (до ветвлений и других участков ППОП с неопределенным временем исполнения),
то никакой "размазаности" не будет. Будет четкий период.
Go to the top of the page
 
+Quote Post
xemul
сообщение May 29 2011, 19:00
Сообщение #6



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(SKov @ May 29 2011, 22:01) *
Не совсем так, т.к. при загрузке TMR0 сбрасывается прескалер.
Тогда уж логично сбрасывать не только прескалер, а и сам основной счетчик.
В этом случае мы как раз и получаем второй вариант.Ну, на самом деле это в принципе одно и то же (первый и второй вариант). Просто второй вариант действительно предзагрузка, а первый - предсуммирование или преддобавка, что звучит уж совсем коряво wink.gif
Относительно "равномерно размазанного" интервала я не понял.
Если предзагрузку ставить вначале ППОП (до ветвлений и других участков ППОП с неопределенным временем исполнения),
то никакой "размазаности" не будет. Будет четкий период.

Рассмотрите случай с несколькими источниками прерываний, когда прерывание от таймера возникает после проверки его флага, но внутри ППОП.
Сброс прескейлера, в предположении, что он равномерно размазан на все состояния прескейлера, учитывается совершенно отдельно - типа "TMR0 += TMR0_PRESET + 1;" (или, ещё точнее "TMR0 += TMR0_PRESET + 0.5;" - т.е. 1 добавляется через раз).
Go to the top of the page
 
+Quote Post
SKov
сообщение May 29 2011, 19:46
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 812
Регистрация: 22-01-05
Из: SPb
Пользователь №: 2 119



Цитата(xemul @ May 29 2011, 23:00) *
Рассмотрите случай с несколькими источниками прерываний, когда прерывание от таймера возникает после проверки его флага, но внутри ППОП.
Сброс прескейлера, в предположении, что он равномерно размазан на все состояния прескейлера, учитывается совершенно отдельно - типа "TMR0 += TMR0_PRESET + 1;" (или, ещё точнее "TMR0 += TMR0_PRESET + 0.5;" - т.е. 1 добавляется через раз).

Случай нескольких прерываний можно заменить, например, случаем, когда в основной программе есть куски с запретом прерываний.
Другими словами, мы говорим о случае, когда время реакции на прерывания непредсказуемо.
В этом случае надо смотреть на конкретный код программы. Если задержка реакции укладывается в несколько "тиков" таймера, тогда суммирование может нас спасти и обеспечить точность периода прерываний в пределах одного тика таймера.
А если задержка может быть большая, то вообще теряется смысл предустановки.
Можно рассмотреть и другой случай. Пусть задержка лежит в районе одного тика таймера плюс-минус несколько тактов Fosc/4.
В этом случае прибавление константы дает нам "дрожание" периода прерываний примерно на величину одного тика таймера.
А если мы выполняем загрузку таймера константой, то "дрожание" периода имеет величину всего лишь нескольких тактов Fosc/4.
Так что бывают случаи, когда загрузка лучше суммирования wink.gif

Go to the top of the page
 
+Quote Post
xemul
сообщение May 30 2011, 06:51
Сообщение #8



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(SKov @ May 29 2011, 23:46) *
Так что бывают случаи, когда загрузка лучше суммирования wink.gif

Я могу обосновать чиста математически, что загрузка в любом случае будет не лучше суммирования в смысле получения минимальной средней (или средней квадратичной - без разницы) ошибки формирования некоторого периода на любом числе периодов.
Случай, когда загрузка будет равна по ошибке суммированию, вообще один - прерывания только от таймера с минимальным прескейлером, никаких критических секций в коде.
Из очевидных минусов загрузки - собственно загружаемую константу придётся подрихтовать ручками, чтобы учесть задержку от возникновения прерывания до момента загрузки, или вставлять каким-либо образом этот учёт в считалку препроцессора. При суммировании оно учитывается само, и остаётся только решить, компенсировать ли сброс прескейлера или и так сойдёт.
Go to the top of the page
 
+Quote Post
SKov
сообщение May 30 2011, 07:40
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 812
Регистрация: 22-01-05
Из: SPb
Пользователь №: 2 119



Цитата(xemul @ May 30 2011, 10:51) *
Я могу обосновать чиста математически, что загрузка в любом случае будет не лучше суммирования в смысле получения минимальной средней (или средней квадратичной - без разницы) ошибки формирования некоторого периода на любом числе периодов.

Интересна не столько средняя ошибка, сколько ее дисперсия. Она определяет "дрожание" периода прерываний.
Я выше приводил пример, когда время задержки между событием, вызывающим прерывание и моментом загрузки гуляет около одного
тика таймера.(тик таймера = период срабатывания прескалера). Будем считать, что идеальным вариантом для нас является суммирование прескалера, когда задержка равна точно одному тику. Этот лишний тик мы учтем в прибавляемой константе. Это будет соответствовать нулевой ошибке.
Если время задержки в какой-то момент оказалось чуть-чуть меньше тика таймера,
то ошибка при суммирование таймера будет равна почти одному тику из-за обнуления прескалера, который к этому моменту накопил почти целый тик.
Если задержка чуть-чуть больше одного тика, то при суммировании будет ошибка небольшая. Короче говоря, ошибка при суммировании будет определяться состоянием прескалера на момент суммировния. В среднем это примерно половина тика.
В случае загрузки константы в моем примере дрожание периода определяется только интервалом времени, в котором гуляет задержка.
Это интервал между "чуть-чуть меньше тика" и "чуть-чуть больше тика".
Разница между этими моментами времени может быть существенно меньше времени тика таймера (и даже его половины).
И следовательно, дисперсия периода будет небольшой. Чиста математически wink.gif


Цитата(loghir @ May 30 2011, 11:29) *
Никак не докопаюсь, для чего нужен
Код
if (T0IF){}
.

Флаг запроса взводится автоматически при возникновении события, могущего вызвать прерывание.
А сбрасывать его должен сам программер в ППОП.
Сложность в том, что вы попадаете в одно и то же ППОП при срабатывнии прерываний от нескольких разных источников.
Вы должны определить, какой источник вас "позвал" в ППОП. Это делается опросом флагов запроса прерывания
(по-умному это называется "полинг прерываний".)
Если у вас разрешен только один источник прерываний, то эта проверка не нужна.
Цитата
Также не пойму, как в некоторых случаях работает оператор while. В книге по микроС сказано:
У Кернигана и Ритчи иная точка зрения:
И где истина?

Истина в вине wink.gif В смысле - оба источника правы. Т.к. "Ложь" кодируется нулем, а все остальное - "Правда"! wink.gif
Go to the top of the page
 
+Quote Post
xemul
сообщение May 30 2011, 08:18
Сообщение #10



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(SKov @ May 30 2011, 11:40) *
Интересна не столько средняя ошибка, сколько ее дисперсия.

Дисперсия == (средняя квадратичная ошибка)^2.
Цитата
Она определяет "дрожание" периода прерываний.

Занятное определение, ну да ладно.
Мне это было интересно во времена, когда у пиков система прерываний отсутствовала как класс, а строить какие-то диспетчеры задач и формировать интервалы всё равно приходилось. Повозил немного карандашом, пришёл к выводу... С тех пор математика (точнее, арифметика) работы таймеров не изменилась. Но у каждого кулика своё болото.sm.gif

Цитата(loghir)
Добавил квалификатор volatile а всем переменным, используемым в ППОП.

Он нужен только переменным, _модифицируемым_ в прерываниях.
Go to the top of the page
 
+Quote Post
SKov
сообщение May 30 2011, 08:42
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 812
Регистрация: 22-01-05
Из: SPb
Пользователь №: 2 119



Цитата(xemul @ May 30 2011, 12:18) *
Дисперсия == (средняя квадратичная ошибка)^2.

Ну, это если "чиста математически". wink.gif
Квадратичная ошибка, да еще и в квадрате - это сильно! wink.gif
А если посмореть в букваре (можно в Википедии), то можно убедиться, что
Дисперсия ошибки == средний квадрат отклонения от средней ошибки.
Чувствуете разницу?
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- loghir   Работа таймера TMR0 (PIC16)   May 23 2011, 15:43
- - xemul   Цитата(loghir @ May 23 2011, 19:43) На да...   May 23 2011, 17:33
- - Redguy   Блок-схема TMR0 тебе в помощь!   May 25 2011, 05:42
- - loghir   Спасибо. Но лучше бы авторы даташита делали его в ...   May 25 2011, 11:20
- - sargein   программка жесткая какая-то, в частности выносы в ...   May 25 2011, 11:51
- - xemul   Обработчик прерываний для мелких пиков должен выгл...   May 25 2011, 11:52
- - loghir   sargein, как работает оператор Кодif (T0IF...   May 25 2011, 12:46
- - sargein   пишите в конце своей программы вот это: Кодinterru...   May 25 2011, 13:58
- - loghir   Если Кодinterrupt isr() { if (T0IF...   May 25 2011, 14:26
- - sargein   писать надо после main() { } я ведь это уже два ра...   May 25 2011, 14:37
- - xemul   Цитата(loghir @ May 25 2011, 16:46) xemul...   May 25 2011, 14:55
- - loghir   Спасибо за подсказку. Буквари ценны тем, что быстр...   May 25 2011, 16:39
|- - xemul   Цитата(loghir @ May 25 2011, 20:39) Вся б...   May 26 2011, 07:26
- - loghir   Цитатавсе требуемые интервалы сделайте на программ...   May 26 2011, 16:03
|- - xemul   Цитата(loghir @ May 26 2011, 20:03) Но во...   May 26 2011, 19:11
- - sergeeff   Уважаемый loghir, я убедился в том, что удивитель...   May 26 2011, 16:27
- - loghir   Цитатая убедился в том, что удивительный лодырь, о...   May 26 2011, 17:39
- - sergeeff   Вот-вот. Именно про это я писал. Выдавил таки топи...   May 26 2011, 20:36
- - loghir   xemul, спасибо. Буду разбираться. Проблема в том, ...   May 27 2011, 02:20
|- - xemul   Цитата(loghir @ May 27 2011, 06:20) Буду ...   May 27 2011, 06:39
|- - sergeeff   Цитата(loghir @ May 27 2011, 06:20) Мозги...   May 27 2011, 09:02
- - loghir   ЦитатаНу объясните мне, с чем здесь разбираться? с...   May 27 2011, 10:05
|- - xemul   Цитата(loghir @ May 27 2011, 14:05) С Про...   May 27 2011, 11:10
- - sergeeff   Вопрос на засыпку: откуда вы знаете, что ваш обраб...   May 27 2011, 10:44
- - loghir   ЦитатаВопрос на засыпку: откуда вы знаете, что ваш...   May 29 2011, 14:19
|- - xemul   Цитата(loghir @ May 29 2011, 18:19) где-т...   May 29 2011, 14:58
- - sargein   смутная программка а не могли бы вы еще раз уточн...   May 29 2011, 14:36
- - sargein   ну как то примерно так Кодunsigned char tmp100 = ...   May 29 2011, 17:14
- - sargein   xemul, согласен, забыл про это   May 29 2011, 17:51
- - loghir   Спасибо за гору инфы! Еще бы переварить... Д...   May 30 2011, 07:29
- - _Pasha   Не встречал задач, где предзагрузка таймера в комб...   May 30 2011, 08:28
- - loghir   Вот что получилось: Кодvoid init (void) {...   May 30 2011, 14:32
|- - SKov   Цитата(loghir @ May 30 2011, 18:32) Вот ч...   May 30 2011, 15:28
- - sargein   Цитата(loghir @ May 30 2011, 17:32) while...   May 30 2011, 15:37
- - sergeeff   Коллеги! Уважаемый loghir не хочет сам ничего...   May 30 2011, 15:56
- - loghir   ЦитатаУ вас проблемы с элементарным программирован...   May 30 2011, 17:02
- - loghir   Всем большое спасибо!!!!!...   May 31 2011, 07:56


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 14:30
Рейтинг@Mail.ru


Страница сгенерированна за 0.01537 секунд с 7
ELECTRONIX ©2004-2016