svip Опубликовано 5 октября, 2007 Поделиться Опубликовано 5 октября, 2007 Помогите разобраться с таймерами в мк. Например атмега16 как задать время работы таймера и по его прерыванию что либо выполнить??? например нужно с частотой 1 герц посылать единицу на ногу контроллера. Как это реализовать? Обрыл уже весь поиск, но тольком ничего найти не могу 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
YurkaM Опубликовано 5 октября, 2007 Поделиться Опубликовано 5 октября, 2007 (изменено) http://forum.cxem.net/index.php?showtopic=...st&p=186361 Моргалка светодиодом 1Гц на Tiny2313. Используется прерывания таймера1 по совпадению. Там токо для АТмеги по-другому указатель стека устанавливается (в 2313 он однобайтный, а в МЕге 2-х байтный) Надо так : ldi tmpa,high(ramend) out SPH,tmpa ldi tmpa,low(ramend) out SPL,tmpa И на конфигурацию портов не обращай внимания - это от конкретного девайса остались. Тебе главное на вывод включить ногу на которой висеть светодиод будет Изменено 5 октября, 2007 пользователем YurkaM 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
20% скидка на весь каталог электронных компонентов в ТМ Электроникс!Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!Перейти на страницу акции Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
Zer Опубликовано 5 октября, 2007 Поделиться Опубликовано 5 октября, 2007 Дитай даташит лучше! Устанавливаем режим работы таймера. * В регистр счетчика заносим опр. константу. Разрешаем прерывания и запискаем таймер. При переполнении управление передаётся по определённому адресу. Там и пишешь, какие действия надо сделать. Дальше, при необходимости(в зависимости от режима работы таймера), либо reti, либо переходим к *. Подробнее только в даташите. Там-же вся адресация. 0 Пока в груди моей бьётся мотор, надежда есть на чистый бензин... Ссылка на комментарий Поделиться на другие сайты Поделиться
Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторовОбязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей. Подробнее>>Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
svip Опубликовано 5 октября, 2007 Автор Поделиться Опубликовано 5 октября, 2007 Да я на асме полный баран на си пытаюсь писать в cvavr А даташит перечитал, все равно не пойму. Может кто модет привести рабочий пример(того же мигания всетодиодом) на си c описанием всего. Буду очень благодарен 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
YurkaM Опубликовано 5 октября, 2007 Поделиться Опубликовано 5 октября, 2007 Вот оно!... - развращают людей эти высокоуровневые языки! Не имея представления о матчасти пытаются что-то писать. Привыкли, что на все случаи есть какая-нить функция или чужая готовая библиотека. Неправильно это ИМХО! Уж чего-чего, а моргнуть светодиодом надо уметь на асме написать. Устанавливаем режим работы таймера. * В регистр счетчика заносим опр. константу. Разрешаем прерывания и запискаем таймер.При переполнении управление передаётся по определённому адресу. Там и пишешь, какие действия надо сделать. Если это прерывание по переполнению, то надо не забыть каждый раз грузить константу в регистр счетчика 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
tex Опубликовано 6 октября, 2007 Поделиться Опубликовано 6 октября, 2007 По переполнению таймера. На Си никаких прерываний разрешать не нужно, нужно лишь запустить таймер, после переполнения в регистре флагов прерываний(TIFR) появится флаг. По появлению этого флага зажечь светодиод, затем очистить флаг, опять ждем переполнение затем гасим светодиод очищаем флаг, и так по циклу. А для перемены частоты, делаем прерывание по совпадению таймера с содержимым регистра OCR(меняя ее содержимое меняем частоту). Datasheet рулит... 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
YurkaM Опубликовано 7 октября, 2007 Поделиться Опубликовано 7 октября, 2007 По переполнению таймера. На Си никаких прерываний разрешать не нужно, нужно лишь запустить таймер, после переполнения в регистре флагов прерываний(TIFR) появится флаг. По появлению этого флага зажечь светодиод, затем очистить флаг, опять ждем переполнение затем гасим светодиод очищаем флаг, и так по циклу. Сильно! И как предлагаешь отслеживать появление флага, не разрешив прерывания?? Тупо сидеть в цикле и читать его пока не появиться? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
wowa Опубликовано 7 октября, 2007 Поделиться Опубликовано 7 октября, 2007 (изменено) Ну зачем же так !! Именно в CVAVR после написания функции типа interrupt [TIM0_OVF] void timer0_ovf_isr(void){ // что делать при прерывании.... } чтобы это заработало надо ещё разрешить на пример так: TIMSK=0x01; иначе ничего никуда нещитает... А для полноты картины нужно ещё и таймер настроить например так вот: TCCR0=0x03; TCNT0=0x00; OCR0=0x00; Изменено 7 октября, 2007 пользователем wowa 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
YurkaM Опубликовано 7 октября, 2007 Поделиться Опубликовано 7 октября, 2007 (изменено) Да я на асме полный баран на си пытаюсь писать в cvavrА даташит перечитал, все равно не пойму. Может кто модет привести рабочий пример(того же мигания всетодиодом) на си c описанием всего. Буду очень благодарен Человек просил рабочий пример. Я дал на асме (см п.2). Человек не понимает асм, просит на Си. Ну дык помогите! - делов то на 2 минуты, не фиг тут намёками всякими рассусоливать, дайте конкретный текст от и до, который можно скомпилировать и получить результат. А svip "будет очень благодарен" Изменено 7 октября, 2007 пользователем YurkaM 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
wowa Опубликовано 7 октября, 2007 Поделиться Опубликовано 7 октября, 2007 Хорошо. Вот кусок рабочий. У меня работает на доске с внутриним генератором на 1 Мгц. #include <mega16.h> int i = 0; // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void)[size="2"][/size] { if(i == 0){ PORTA=0x00; i = 1; } else { PORTA=0xff; i = 0; } } void main(void) { // Port A Output PORTA=0x00; DDRA=0xFF; PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0x00; // Set timer 0 - изменяя эти параметры можно покрутить скорость. TCCR0=0x03; TCNT0=0x00; OCR0=0x00; // Timer ON TIMSK=0x01; // Global enable interrupts #asm("sei") while (1) { // Place your code here }; } 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
svip Опубликовано 7 октября, 2007 Автор Поделиться Опубликовано 7 октября, 2007 Спасибо огромное, выручили, теперь буду разбираться и прикручивать к своему устройству 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
YurkaM Опубликовано 7 октября, 2007 Поделиться Опубликовано 7 октября, 2007 (изменено) И чё? получим период 1сек?? Я в Си не силён, по этому выскажу лишь некоторые мысли категонично ничего не заявляя // Set timer 0 - изменяя эти параметры можно покрутить скорость.TCCR0=0x03; TCNT0=0x00; OCR0=0x00; 1) С данными параметрами получим прерывания с частотой 61,035... Гц, т.е моргать будет около 30Гц. 2) TCCR0 сильно "крутить" не стоит, менять можно только младшие 3 разряда 3) как ни "крути" TCCR0 без подзагрузки TCNT0 при каждом прерывании, можно получить лишь 5 вариантов частоты (ну кварц один и тот же естеств-но) 4) каким образом может повлиять OCR0, если прерывания по переполнению? PS: wowa, у всех выпускаемых сейчас AVR (насчет 8-ножек не скажу точно...) если в порт PINx писать 1, когда он сконфиг-ан как выход, то получим инверсию вывода. Поэтому твой кусок: { if(i == 0){ PORTA=0x00; i = 1; } else { PORTA=0xff; i = 0; } } можно заменить на: { PINA=0xff; } И всё! Изменено 7 октября, 2007 пользователем YurkaM 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
svip Опубликовано 7 октября, 2007 Автор Поделиться Опубликовано 7 октября, 2007 получается если частота кварца на контроллере 4 MHz то при TCCR0=0b00000100; (частоту делим на 256) получаем частоту срабатывания 15625 герц. Но вот например в cvavr пишу так interrupt [TIM0_OVF] void timer0_ovf_isr(void) { if (j==15625) { if(i == 0){ PORTD=0x00; i = 1; } else { PORTD=0xff; i = 0; } j=0; }else j++; } то не получаю мигания в 1 герц, а если сравнивать j==30 то примерно 1 герц получается. В чем тут проблема и как можно расчитать срабатывание на определенную частоту? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
YurkaM Опубликовано 7 октября, 2007 Поделиться Опубликовано 7 октября, 2007 (изменено) TCCR0=0b00000100 - это делитель тактовой для таймера, но чтобы таймер переполнился он должен тикнуть 256 раз (8 битный если), т.е. тактовую таймера (4МГц/256) надо еще раз разделить на 256. И получим 61Гц. Всё срастается. (За период должно быть 2 прерывания - вкл и выкл) Кстати на таймере T0 при кварце 1МГц можно получитть прерывания 264мск при самом большом делителе (1024). 1 секунду без дополнительной переменной никак не получишь. Тем более при 4МГц Изменено 7 октября, 2007 пользователем YurkaM 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
wowa Опубликовано 7 октября, 2007 Поделиться Опубликовано 7 октября, 2007 Да я собственно с частотой на одну секунду незаморачивался... Для этого нужен ещё делитель как правильно заметили выше.. Я тут просто показал как обслуживать прерывания.... Я так понял что тут нешло работать с прерываниями.. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
svip Опубликовано 7 октября, 2007 Автор Поделиться Опубликовано 7 октября, 2007 да. все разобрался. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
svip Опубликовано 7 октября, 2007 Автор Поделиться Опубликовано 7 октября, 2007 Еще возник вопрас. как использовать 1 и 2 таймеры??? на нулевом организовал вывод синусоиды, но нужно же мне еще управлять амплитудой. вот думаб на 1 и 2 таймерах сделать. TCCR1A=0b00000100; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; так прописал (может чего не дописал? подскажите) конструкция вида interrupt [TIM1_OVF] void timer1_ovf_isr(void) { koef++; } не работает. подсказывает мне что-то что так использовать нельзя. насколько я знаю что при переполнении первого таймер в регистрах TCNT1H, TCNT1L мы получаем какое то значение (что за значение не знаю.) 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
wowa Опубликовано 7 октября, 2007 Поделиться Опубликовано 7 октября, 2007 (изменено) Блин ну так ведь нельзя !!!! У вас есть прекрасный гайд на начало програмы (CVAVR) !!! Начните с того что начнёте новый проект ни накликайте себе тайиеры так как надо!!!! И вообще НАДО учить асемблер чтобы знать как это работает в С. Я вот например очень много писал на С и С++ и после того как понадобилось написать на мегу - сначала выучил асемблер.. Всего то взяло времени 24 часа... Просто пройти команды и поонять что ккая делает и потом изучить регистры управления а на конец посмотреть на примеры чужие... А так вот спрашивать каждый вопрос неизучив материала - могут ведь и неответить.. Что потом будете делать??? #include <mega16.h> // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Place your code here } // Timer 1 overflow interrupt service routine interrupt [TIM1_OVF] void timer1_ovf_isr(void) { // Place your code here } // Timer 2 overflow interrupt service routine interrupt [TIM2_OVF] void timer2_ovf_isr(void) { // Place your code here } // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port A initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00; DDRA=0x00; // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x00; TCNT0=0x00; OCR0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: On // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // INT2: Off MCUCR=0x00; MCUCSR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x45; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // Global enable interrupts #asm("sei") while (1) { // Place your code here }; } Так вот такой код мене сгенерировал гайд в нём наставлены все три таймеры на прерушение при перетечении... Думаю что вас заинтересует рядок с // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x45; Дальше пляшите от даташита... Изменено 7 октября, 2007 пользователем wowa 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
svip Опубликовано 7 октября, 2007 Автор Поделиться Опубликовано 7 октября, 2007 да в визарде уже разобрался. так и сгенерил. почему спрашиваю, так потому что 0 и 2 таймеры работают отллично, но вот первыё не хочет. interrupt [TIM1_OVF] void timer1_ovf_isr(void) { if (j==0) {j=1;} else if (j==1) {j=0;} } TIMSK=0x45; так и стоит, вот только TCCR1B=0b00000100; задал делитель частоты. (у вас в примере нули.) но не выполняется изменение состояния j вот и подумал что еще где то нужно что-то прописать 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
svip Опубликовано 9 октября, 2007 Автор Поделиться Опубликовано 9 октября, 2007 с таймерами разобрался, за что огромное Вам спасибо. Может кто посоветует какую нибуть книжку (скачать) по программированию avr на си??? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
svip Опубликовано 16 октября, 2007 Автор Поделиться Опубликовано 16 октября, 2007 подскажите как юзать таймер не по переполнению а по сравнению??? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
wowa Опубликовано 16 октября, 2007 Поделиться Опубликовано 16 октября, 2007 Нет у меня на работе CVAVR немогу показать - для этого надо наставить счётчик в правильный режим и задать число для сравнения в регистр... 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
svip Опубликовано 16 октября, 2007 Автор Поделиться Опубликовано 16 октября, 2007 (изменено) вот скрин визарда. что тут нужно установить? у меня щас по перепелнению стоит так: TCCR2=0b00000001; interrupt [TIM2_OVF] void timer2_ovf_isr(void) // 61 тиканье в секунду { тут у меня перебор 61 элемента массива синусоиды. получается чито период равен 1 секунде. 1 герц если ставлю так if (bb==20) { то получается 1 тиканье за 20 секунд - 0,05 герца bb=0; }else bb++; а мне нужно 0,12 герц синус получить если bb==8 то получается 0,125 герц. а нужно точно 0,12 поэтому и нужно выполнять по сравнению а не по переполнению } Изменено 16 октября, 2007 пользователем svip 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
wowa Опубликовано 16 октября, 2007 Поделиться Опубликовано 16 октября, 2007 Ну так там ведь английским языком написано!!!! Compare Match Interript !!!!! А то OverFlow Intrrupt выключить!!! И ещё поищи в хелпу куда записать с чем проверять.. И ещё - проверять можеш только на целое без минуса!!! Должно быть тип переменной CHAR !!! если тебе надо 0,12 - то надо значить всё в 100 раз делать быстрее ну или считать коэфициент для таймера на переполнение... Что я думаю будет намного проще.. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
HOT ICE Опубликовано 16 октября, 2007 Поделиться Опубликовано 16 октября, 2007 (изменено) TCCR0=0b00000100 - это делитель тактовой для таймера, но чтобы таймер переполнился он должен тикнуть 256 раз (8 битный если), т.е. тактовую таймера (4МГц/256) надо еще раз разделить на 256. И получим 61Гц. Всё срастается. (За период должно быть 2 прерывания - вкл и выкл)Кстати на таймере T0 при кварце 1МГц можно получитть прерывания 264мск при самом большом делителе (1024). 1 секунду без дополнительной переменной никак не получишь. Тем более при 4МГц Приветю.Вот не могу понять что мне записывать В TCCR0 если мне нужна задержка 1 минуту? Если не сложно напишите пожалуйста всё формулы для вычесления этих значений,и что куда записывать.У меня частота 12000000 Изменено 16 октября, 2007 пользователем HOT ICE 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.