|
Простенькая программка измерения длительности импульса. |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Aug 30 2008, 08:30
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(rv3dll(lex) @ Aug 30 2008, 11:00)  если импульс гладкий ез промсечек надо после прерывания поменять в регистре статуса прерывания полярность Ну, если и есть то можна сгладить простейшим интегратором - RC -фильтром подобрав тау под мин длит импульса.
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 30 2008, 19:53
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(Зверюга @ Aug 30 2008, 18:29)  Я вот например запустил CodeVision Wisard и мне совершенно непонятно, как привязать внешнее прерывание к запуску и остановке таймера. я тоже извиняюсь, только после именин крёсника. Во первых про остановку таймера я ничего не говорил. во вторых, режим захвата общеизвестен. чего уж тут обяснять. зверюга, а при чём здесь помощник CodeVision ? ну а как померять период? зверюга , представьте себе ситуацию, когда Ваш счётчик сам себе считает. Ну и пускай себе считает, ведь правда? мы инициализируем периферию так, что бы обрабатывать прерывание по фронту или по спаду, как Вам уже удобно будет, на любителя. счётчик себе считает, ну и пускай..... но тут приходит спад (Falling Edge) измеряемого сигнала и у нас возникает прерывание поскольку мы настроили прерывание по Falling Edge (ну так нам захотелось). представим себе что счётчик считал себе и никто его не трогал. тут возникло наше прерывание. ну и тут остановки или запуска нету. в общем, когда происходит захват то состояние счётчика копируется в регистр захвата. если это понятно, тогда обясню следующее разница в счёте регистра захвата между первым прерыванием и вторым будет равна периоду Вашего измеряемого сигнала умноженную на частоту тактирования вашего счетчика и делённую на величину предделителя. я даже в таком состоянии немогу понять какой код Вы хотите увидеть?тут то писать нечего
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 31 2008, 13:25
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Боюсь Ваш метод мне не подойдет. Объясню: время необходимо измерять довольно точно. Ввиду этого я буду использовать 16-ти битный таймер, источником для счета выберу System clock. Таким образом получу переполнение таймера за 4095,9375 мкс. А если длительность импульса будет больше указанной величины? Я планирую сделать так: По переполнению таймера генерировать прерывание, в обработчике которого некая величина cycles будет инкрементироваться. А контроллировать измеряемый импульс я буду внешним прерыванием. По спаду имульса на входе INT0 будет генерироваться прерывание, в обработчике которого будет производиться операция (cycles*65535+состояние счетчика на данны момент) / 16 - получаем длительность импульса в микросекундах при частоте кварца 16 МГц. После чего счетчик сбрасывается, переменная cycles обнуляется. Уточню - мне нужно не время импульса, а время от фронта до следущего фронта. То есть период. Кроме того, использоваться бедт не только INT0, но и INT1, INT2, импульсы на которые будут приходить поочередно, а обработчк будет один и тот же. Если предложенный мной алгоритм с использованием не только счетчика но и внешнего прерывания слишком сложен и объясняется незнанием мной всех возможностей счетчика, укажите мне на это. В таймерах/счетчиках я полный ноль, заглянул в руководство - там 50 страниц с дикими 5-6-ти буквенными похожими друг на друга труднозапоминаемыми аббревиатурами. Господа, я знаю, что разбираться с этим буду недели две, а что конечный результат инициализации строк таймера займет 5-6 строк. Будьте добры, помогите с примером кода, а я изменяя его и экспериментирую, как-нибудь дальше разберусь. Вот мой код: Код interrupt [TIM1_OVF] void timer1_ovf_isr(void) { lcd_setxy(2,15); lcd_str_fl("timer is overflow",f8x14,green);//ñòðîêà èç flash
cycle++; }
void main(void) { TCCR1A=0x00; TCCR1B=0x01; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; ........ .........
for (;;) { lcd_setxy(32,50); lcd_str_ram(cycle, f8x8,textcolor);//ñòðîêà èç ram }
} Если таймер хотя бы один раз переполнится, на экран должна вылезти надпись "timer is oferflow". А если он переполняется неоднократно, то постоянно будет обновляться значение переменной cycle. На экране же "0". Таймер не запущен? Генерировал код при помощи CodeVision Wizard.
|
|
|
|
|
Aug 31 2008, 13:57
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Вы глобально не разрешили прерывания. инициализация таймера правильная, как Вы и хотели. для КВ, непомню но вроде вот так напишите в мейне перед циклом Код #asm sei #endasm Цитата(Зверюга @ Aug 31 2008, 16:25)  время необходимо измерять довольно точно. Ввиду этого я буду использовать 16-ти битный таймер, источником для счета выберу System clock. Таким образом получу переполнение таймера за 4095,9375 мкс. Если таймер хотя бы один раз переполнится, на экран должна вылезти надпись "timer is oferflow". А если он переполняется неоднократно, то постоянно будет обновляться значение переменной cycle. ЖКИ графический, успеет? четыре милисекунды слишком мало. Цитата(Зверюга @ Aug 31 2008, 16:25)  время необходимо измерять довольно точно. Ввиду этого я буду использовать 16-ти битный таймер, источником для счета выберу System clock. Таким образом получу переполнение таймера за 4095,9375 мкс. А если длительность импульса будет больше указанной величины? А чё Вам мешает подсчитывать колличество переполнений, а в регистре захвата будете иметь значение счётчика на момент прихода следующего фронта? о, всё придумано уже до меня ссылка.
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 31 2008, 14:13
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Цитата ЖКИ графический, успеет? четыре милисекунды слишком мало. Вы правы. Разрешил глобально прерывания, ЖКИ перестал выводить на экран))) Убрал все из обработчика прерываний, даже остановил таймер (TCCR1B=0x00;) - тоже не работает. Сам факт разрешеиня прерываий не дает работать ЖКИ. Поставил #asm cli #endasm до начала обращения к ЖКИ и #asm sei #endasm после. Выясняется, что sei вызывает перезагрузку ЖКИ... Что делать.. Цитата о, всё придумано уже до меня ссылка. Прочитано до Вас. Там по-видимому для WinAVR. По крайнй мере TIMSK |= (1 << TOIE1); переваривать не хочет, TOIE1 не знает. Так все-таки - куда точно ставить разрешение прерываний? Поставил перед void main() - ЖКИ не перегружается но и проргамма не работает...
|
|
|
|
|
Aug 31 2008, 14:31
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(Зверюга @ Aug 31 2008, 17:13)  Прочитано до Вас. Там по-видимому для WinAVR. По крайнй мере TIMSK |= (1 << TOIE1); переваривать не хочет, TOIE1 не знает.
Так все-таки - куда точно ставить разрешение прерываний? Поставил перед void main() - ЖКИ не перегружается но и проргамма не работает... у вашего компилятора нету битовых определений регистров. в регистре TIMSK, бит TOIE1 третий для Вашего МК. Поможет определение Код #define TOIE1 2 тогда будет работать выражение приведённое вами выше. Цитата(Зверюга @ Aug 31 2008, 17:13)  Так все-таки - куда точно ставить разрешение прерываний? Поставил перед void main() - ЖКИ не перегружается но и проргамма не работает... Глобальное разрешение прерываний пишут в мейне непосредственно перед бессконечным циклом for (;;). На моменте отладки в прерывании переполнения таймера запретите прерывания, выведите надпись, и разрешите перед выходом.
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 31 2008, 14:53
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Спасибо конечно, но вот разрешение прерываний не дает работать ЖКИ.. Для чистоты эксперимента убрал все лишнее, убрал инициализацию таймера, убрал обработчик прерывания - просто сделал sei - перезагружается.. УХ ТЫ!!!! Посмотрите код! Запретил прерывания, инициализировал экранчик. Поставил задержку в 3 секунды - чтобы хоть посмотреть на черный экран. Затем включил прерывания. - Экран стал моргать с периодичнстью в 3 секунды. ЭТО НЕ ЖКИ, ЭТО КОНТРОЛЛЕР РЕСЕТИТСЯ. Почему? Куда копать? Вот код: Код #include <mega32.h> #include <delay.h> #include <disp.h> #include <stdio.h> #include <defines.c> //**************************************************** #define INT_ON #asm("sei") #define INT_OFF #asm("cli")
u08 variable; ui16 textcolor; // color of text ui16 backcolor; // color of background
ui16 varvar; volatile int cycle=0; ///////////////////////////////////////////////////
interrupt [TIM1_OVF] void timer1_ovf_isr(void) { //lcd_setxy(2,15); // lcd_str_fl("timer_ovfl",f8x14,green);//ñòðîêà èç flash
cycle++; }
void main(void) {
INT_ON; /* TCCR1A=0x00; TCCR1B=0x03; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00;
*/
//================================================= varvar = 4500 + 60123;
INT_OFF; lcd_init(); backcolor=black; textcolor=yellow;
lcd_clr(); fill_screen(black); delay_ms(3000); INT_ON;
} Для общей информации - вот библиотека ЖКИ При этом регистр MCUCSR=0x03, то есть оба бита равны 1
|
|
|
|
|
Aug 31 2008, 15:18
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(Зверюга @ Aug 31 2008, 17:53)  ЭТО НЕ ЖКИ, ЭТО КОНТРОЛЛЕР РЕСЕТИТСЯ. Почему? Куда копать? При этом регистр MCUCSR=0x03, то есть оба бита равны 1 Как у Вас организован внешний сброс? Чё к ресету подсоединено и как? Цитата Bit 1 – EXTRF: External Reset Flag This bit is set if an External Reset occurs. The bit is reset by a Power-on Reset, or by writing a logic zero to the flag. • Bit 0 – PORF: Power-on Reset Flag This bit is set if a Power-on Reset occurs. The bit is reset only by writing a logic zero to the flag. To make use of the Reset Flags to identify a reset condition, the user should read and then reset the MCUCSR as early as possible in the program. If the register is cleared before another reset occurs, the source of the reset can be found by examining the Reset Flags. Вотчдог не включён? Ещё, запитываете каким образом, стабилизатор и БП не слабенькие? оф: чем отлаживаете?
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 31 2008, 15:20
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
Цитата Как у Вас организован внешний сброс?
Чё к ресету подсоединено и как? К ресету кнопка, без резистора - никогда до этого ресеты не случались. В этом может быть причина? Включение пррываний генерирует помехи или просадки? Просто ща занят, подпаять нет времени... Песик выключен.
|
|
|
|
|
Aug 31 2008, 15:33
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(Зверюга @ Aug 31 2008, 18:20)  К ресету кнопка, без резистора - никогда до этого ресеты не случались. В этом может быть причина? Включение пррываний генерирует помехи или просадки? Просто ща занят, подпаять нет времени... да именно, об этом Вам и говорят установленные флаги. Попробуйте сначала исключить ресет а потом уже подумаем нащёт просадок. может ещё детектор питания (БОД) не так настроен. как появится время, резистор 1К к питанию и к ресет, конденсатор 10нан к ресету и к корпусу.
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|