zheka 1 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба Господа, пишу программку для подсчета периода импульсов. Могу применять только 8-битный таймер, ибо 16-ти битный таймер занят. Всвязи с тем что переполнение его наступает через каждые 256 тактов, их приходится точно просчитывать. Вот такой вот код: interrupt [TIM0_OVF] void timer0_ovf_isr(void) { //tacts++; a=TCNT0; TCCR0=0x00; lcd_gotoxy(0,0); lcd_putsf(" "); lcd_gotoxy(0,0); sprintf(s," %i", a); lcd_puts(s); TCCR0=0x01; } То есть сразу по прерывания по переполнения таймер по идее должен сбрасываться. В самом начале обработчика значение TCNT0 записывается в переменную a. И ее значение выводится на экран. Так вот в данном случае оно равно 32 или 33 (в зависимости от фазы луны и того, чем я похмелялся )))) ). Что контроллер делает эти 32 такта? ПРичем 32 такта выдается хоть при 16 000 кГц, хоть при делении на 8 (2000 кГц). Инициализирую таймер так: // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 16000,000 kHz // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x01; TCNT0=0x00; OCR0=0x00; Что делать и кто виноват? У кого нибьудь есть опыт написания таких программ, когда приходилось несколько циклов переполнения таймера складывать. Как-нибудь компенсировали время, затрачиваемое на обработку прерывания? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба ...Всвязи с тем что переполнение его наступает через каждые 256 тактов, их приходится точно просчитывать... Просчитыванию очень способствуют функции типа: interrupt [TIM0_OVF] void timer0_ovf_isr(void) { ... lcd_gotoxy(0,0); lcd_putsf(" "); lcd_gotoxy(0,0); sprintf(s," %i", a); lcd_puts(s); ...} Как Вы думаете, за сколько тактов они выполнятся и сколько раз за это время переполнится таймер?.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба Господи, ну читайте же внимательно мой код. Или укажите где я не прав? Прежде чем обращаться к LCD, я загнал в переменную а содержание TCNT0. А эта операция, как я выяснил для char занимает один такт, для int - 4 такта, для long int 20 тактов. А потом хоть заобращайся к LCD, он будет выводить правильное значение. Еще версии будут? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба Что контроллер делает эти 32 такта?Скорее всего выполняет пролог обработчика прерывания - сохранение содержимого регистров на стеке. А листинг ассемблера посмотреть не догадались? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба А листинг ассемблера посмотреть не догадались? К сожалению, китайский не изучал))) Никак нельзя этот период стабилизировать? У меня две цифры отображаются - 32 и 33. Опять таки-чисто практический вопрос - имея таймер 8 бит, как посчитать период импульсов? Длительность от 500 мкс до 1 сек. Точность - 1 такт (клок 160 МГц). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба К сожалению, китайский не изучал)))Ну сюда его (листинг) выложите, тут его поймут. Никак нельзя этот период стабилизировать?Попробуйте использовать для сохранения TCNT0 глобальную или статическую переменную и вынести из обработчика прерывания вызовы любых функций. Пока в обработчике прерывания есть вызовы других функций компилятор будет формировать пролог из блока сохранения всех регистров. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба Никак нельзя этот период стабилизировать? Можно, но для этого придется выучить "китайский" и на китайском переписать пролог, да и собсно тело обработчика тоже. Опять таки-чисто практический вопрос - имея таймер 8 бит, как посчитать период импульсов? Длительность от 500 мкс до 1 сек. Точность - 1 такт (клок 160 МГц). 160Mhz это не опечатка? Вроде в ветке по AVR находимся... стало быть 16Mhz. В свете того что 8-ми битный таймер как правило обделенный, то есть только один вариант - очень и очень долго мерять и с помощью мат статисткики отсеивать результаты с большой погрешностью. А если хотите быстро, тогда обязательно нужен input capture и хотя бы поверхностное знание китайского. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 22 января, 2010 Опубликовано 22 января, 2010 · Жалоба Господа, я в принципе только сейчас понял: вывод на экран - это временно, в процессе изучения работы таймера, в дальнейшем там будет только tacts++. Мне главное посчитать, сколько раз таймер переполнился. То есть компенсировать и прибавлять эти 32 такта мне не потребуется. ПРоблема в другом - на каждые 256 тактов будет приходиться 32 такта бесполезной работы, то есть 12,5% времени псу под хвост. Так что решение проблемы только одно, освободить 16-битный таймер (там й меня все равно PWM который можно на 0 или 2 таймер посадить) и с ним работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 22 января, 2010 Опубликовано 22 января, 2010 · Жалоба на каждые 256 тактов будет приходиться 32 такта бесполезной работы, то есть 12,5% времени псу под хвост. :1111493779: Вы чего там надумали? // Registers used // SaveSREG - keep SREG during ISR execution // TickL, TickH - store 16-bit overflow data timer0_ovf_isr: in SaveSREG,SREG //1 inc TickL//1 brne label1//2 inc TickH//1 label1: out SREG,SaveSREG //1 reti //4 //Total: 4+1+1+2+1+1=10 clocks + interrupt response time Комментировать очевидное не буду. в помощь Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kool 0 22 января, 2010 Опубликовано 22 января, 2010 · Жалоба Длительность от 500 мкс до 1 сек. Точность - 1 такт (клок 160 МГц). Такую точность можно получить только используя регистр захвата + прерывание по захвату. И, само собой разумеется, считать прерывания по переполнению. А в прерывании по захвату (после второго перепада) анализировать значения TCNT и ICR. Если TCNT < ICR, то последнее переполнение не учитывать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fantex 0 22 января, 2010 Опубликовано 22 января, 2010 · Жалоба Опять таки-чисто практический вопрос - имея таймер 8 бит, как посчитать период импульсов? Длительность от 500 мкс до 1 сек. Точность - 1 такт (клок 16 МГц). При периоде импульсов 1 сек, получается точность измерения 0.00000625%. Что это за такие импульсы, которые требуют такую точность измерения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 22 января, 2010 Опубликовано 22 января, 2010 · Жалоба При периоде импульсов 1 сек, получается точность измерения 0.00000625%. Что это за такие импульсы, которые требуют такую точность измерения?Очередное заблуждение. Это не точность, а разрешение. Реальная точность порядка на три меньше будет. Точность зависит от стабильности частоты кварцевого генератора и стабильности логических уровней входной логики порта МК на который подается входной сигнал. В общем случае (если не принимать спец. приемов и методов) точность ну никак не лучше 50ppm (0,005%) будет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fantex 0 22 января, 2010 Опубликовано 22 января, 2010 (изменено) · Жалоба Тогда какой смысл измерять с таким разрешением (0.0625 мкс), когда достаточно для точности 0.005% разрешения 25мкс? Или может у автора стоит прецизионный кварцевый генератор с точностью 1ppm и он делает прецизионный частотомер? Изменено 22 января, 2010 пользователем fantex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 22 января, 2010 Опубликовано 22 января, 2010 · Жалоба При периоде импульсов 1 сек, получается точность измерения 0.00000625%. Что это за такие импульсы, которые требуют такую точность измерения? Это скорее юношеский максимализм))) Хочется написать рациональную программу. И если она позволяет измерять с точностью до такта то почему-бы нет? ПО сути - это тахометр для модельного двигателя, который раскручивается до 100 тыс об/мин. ПРи рассчитанной предыдущим оратором точности разрешающая способность будет равна 15 об/мин. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 22 января, 2010 Опубликовано 22 января, 2010 · Жалоба Если точность 1 клок, то Вам без input capture не обойтись. В противном случае Вам надо формировать точные задержки, при этом проц будет занят только этой задачей - тоже не годится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться