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

 
 
> Простенькая программка измерения длительности импульса.
Зверюга
сообщение Aug 30 2008, 07:37
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563



Здравствуйте. Подкиньте пожалуйста примерчик на CodeVision для непрерывного измерения длительности импульса контроллером AVR.

Я так прикидываю, что нужно запускать по прерыванию с пина таймер, по следующему прерыванию останавливать, читать сколько натикало, сбрасывать и вновь запускать. Дискретность - максимально возможная для таймера в atmega32.

В интернете видел только готовые очень мудрые проекты, выдрать из которых суть сложновато, да и то для IAR и WinAVR.


Спасибо.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
rv3dll(lex)
сообщение Aug 30 2008, 08:00
Сообщение #2


Полное ничтожество
*****

Группа: Banned
Сообщений: 1 991
Регистрация: 20-03-07
Из: Коломна
Пользователь №: 26 354



Цитата(Зверюга @ Aug 30 2008, 11:37) *
Здравствуйте. Подкиньте пожалуйста примерчик на CodeVision для непрерывного измерения


так ты период померешь

если импульс гладкий ез промсечек надо после прерывания поменять в регистре статуса прерывания полярность
Go to the top of the page
 
+Quote Post
sKWO
сообщение Aug 30 2008, 08:30
Сообщение #3


Местный
***

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



Цитата(rv3dll(lex) @ Aug 30 2008, 11:00) *
если импульс гладкий ез промсечек надо после прерывания поменять в регистре статуса прерывания полярность

Ну, если и есть то можна сгладить простейшим интегратором - RC -фильтром подобрав тау под мин длит импульса.


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
Зверюга
сообщение Aug 30 2008, 12:00
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563



бр.... оговорился... мне период и нужен.
Не значю к чему эти разговоры про фильтры, без использования прерываний а просто через PINB.х у меня все импульсы от датчика Холла фиксируются без проблем, однако хотелось бы с использованием прерываний, чтобы в период между импульсами заниматься благородными задачами, а потом по импульсу лишь считывать сколько натикало.
Go to the top of the page
 
+Quote Post
sKWO
сообщение Aug 30 2008, 14:14
Сообщение #5


Местный
***

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



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


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
Зверюга
сообщение Aug 30 2008, 15:29
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563



Господа, слишком непонятно и поверхностно... Ни строчки поясняющго кода...

Я вот например запустил CodeVision Wisard и мне совершенно непонятно, как привязать внешнее прерывание к запуску и остановке таймера.

И еще - вопрос, возникший по ходу чем отличаются условия прерывания Low Level и Falling Edge? В первом случае на протяжени всего нуля будет висеть какой-то флаг? Если да, то как будет дело при Falling Edge?
Go to the top of the page
 
+Quote Post
sKWO
сообщение Aug 30 2008, 19:53
Сообщение #7


Местный
***

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



Цитата(Зверюга @ Aug 30 2008, 18:29) *
Я вот например запустил CodeVision Wisard и мне совершенно непонятно, как привязать внешнее прерывание к запуску и остановке таймера.

я тоже извиняюсь, только после именин крёсника.
Во первых про остановку таймера я ничего не говорил.
во вторых, режим захвата общеизвестен. чего уж тут обяснять.
зверюга, а при чём здесь помощник CodeVision ?
ну а как померять период?
зверюга , представьте себе ситуацию, когда Ваш счётчик сам себе считает. Ну и пускай себе считает, ведь правда? мы инициализируем периферию так, что бы обрабатывать прерывание по фронту или по спаду, как Вам уже удобно будет, на любителя. счётчик себе считает, ну и пускай.....
но тут приходит спад (Falling Edge) измеряемого сигнала и у нас возникает прерывание поскольку мы настроили прерывание по Falling Edge (ну так нам захотелось).
представим себе что счётчик считал себе и никто его не трогал. тут возникло наше прерывание. ну и тут остановки или запуска нету. в общем, когда происходит захват то состояние счётчика копируется в регистр захвата.
если это понятно, тогда обясню следующее
разница в счёте регистра захвата между первым прерыванием и вторым будет равна периоду Вашего измеряемого сигнала умноженную на частоту тактирования вашего счетчика и делённую на величину предделителя. я даже в таком состоянии немогу понять какой код Вы хотите увидеть?тут то писать нечего 07.gif


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
Зверюга
сообщение Aug 31 2008, 13:25
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 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.
Go to the top of the page
 
+Quote Post
sKWO
сообщение Aug 31 2008, 13:57
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 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 мкс. А если длительность импульса будет больше указанной величины?

А чё Вам мешает подсчитывать колличество переполнений, а в регистре захвата будете иметь значение счётчика на момент прихода следующего фронта?

о, всё придумано уже до меня ссылка.


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
Зверюга
сообщение Aug 31 2008, 14:13
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563



Цитата
ЖКИ графический, успеет? четыре милисекунды слишком мало.


Вы правы. Разрешил глобально прерывания, ЖКИ перестал выводить на экран))) Убрал все из обработчика прерываний, даже остановил таймер (TCCR1B=0x00;) - тоже не работает. Сам факт разрешеиня прерываий не дает работать ЖКИ.

Поставил #asm cli #endasm до начала обращения к ЖКИ и #asm sei #endasm после. Выясняется, что sei вызывает перезагрузку ЖКИ...

Что делать..



Цитата
о, всё придумано уже до меня ссылка.


Прочитано до Вас. Там по-видимому для WinAVR. По крайнй мере TIMSK |= (1 << TOIE1); переваривать не хочет, TOIE1 не знает.

Так все-таки - куда точно ставить разрешение прерываний? Поставил перед void main() - ЖКИ не перегружается но и проргамма не работает...
Go to the top of the page
 
+Quote Post
sKWO
сообщение Aug 31 2008, 14:31
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 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 (;;).
На моменте отладки в прерывании переполнения таймера запретите прерывания, выведите надпись, и разрешите перед выходом.


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
Зверюга
сообщение Aug 31 2008, 14:53
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 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
Прикрепленные файлы
Прикрепленный файл  New_libs_s65_v0_1_.3.rar ( 111.05 килобайт ) Кол-во скачиваний: 26
 
Go to the top of the page
 
+Quote Post
sKWO
сообщение Aug 31 2008, 15:18
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 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.

Вотчдог не включён?

Ещё, запитываете каким образом, стабилизатор и БП не слабенькие?

оф: чем отлаживаете?


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post
Зверюга
сообщение Aug 31 2008, 15:20
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563



Цитата
Как у Вас организован внешний сброс?

Чё к ресету подсоединено и как?


К ресету кнопка, без резистора - никогда до этого ресеты не случались. В этом может быть причина? Включение пррываний генерирует помехи или просадки? Просто ща занят, подпаять нет времени...

Песик выключен.
Go to the top of the page
 
+Quote Post
sKWO
сообщение Aug 31 2008, 15:33
Сообщение #15


Местный
***

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



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

да именно, об этом Вам и говорят установленные флаги.
Попробуйте сначала исключить ресет а потом уже подумаем нащёт просадок. может ещё детектор питания (БОД) не так настроен.
как появится время, резистор 1К к питанию и к ресет, конденсатор 10нан к ресету и к корпусу.


--------------------
нельзя недооценивать предсказуемость глупости
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 16:57
Рейтинг@Mail.ru


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