Вы не вошли.
Я только что вернулся из Крыма, надеюсь, к понедельнику вернусь к работе.
Вне форума
2 Liv
Доброго времени суток!
В той самой первой программе, что светодиодом моргала, был обработчик прерываний по переполнению ТС0
Там в этом обработчике идет оперирование переменной LedTmr для организации программного таймера мигания светодиодом.
Мне нужно сделать похожую вещь, только таких переменных у меня две. Два программных таймера с разными временами задержки.
Можно ли это сделать? Я что-то не уразумею как. Тут с одной переменной было просто: загрузили, проверили на ноль, если ноль, вышли, если нет, то декремент, сохранение нового значения и все по-новой. А как с двумя?
......There is someone in my head, but it's not me.......
Вне форума
а если 20 светодиодов ?
в атмеле 20 таймеров нету..
я как то делал.... но проект дома.
вроде было так.
1) таймер на сравнение, все светики вкл.
2)пишем в него код, соотв минимальной задержке(светик1).
3) генерирует прерывание, гасим светик1,
4) пишем код, разность от кода для светика2 и светика1.
4)генерирует прерывание, гасим светик2,
5) и тд
Отредактировано Jaxon (21.09.2006 18:43:48)
Вне форума
Так я же постил вариант программы с двумя светодиодами:
https://rh.adsh.org.ua/viewtopic.php?pid=22203#p22203
Если же речь идет о самой старой программе, то её можно переделать так:
;----------------------------------------------------------------------------
;Программа мигания светодиодом
;Микроконтроллер: AT90S2313
;Частота кварца: 10 МГц
;----------------------------------------------------------------------------
.include "2313def.inc" ;подключаем файл описания регистров
;----------------------------------------------------------------------------
;Константы:
.equ LED1_DEL = 76 ;значение задержки в интервалах таймера 0
.equ LED2_DEL = 56 ;значение задержки в интервалах таймера 0
;----------------------------------------------------------------------------
;Определение портов:
.equ LEDS_PORT = PORTB ;светодиод будет на порту B
.equ LED1_PIN = PB0 ;светодиод 1 подключен к выводу PB0
.equ LED2_PIN = PB1 ;светодиод 2 подключен к выводу PB1
;----------------------------------------------------------------------------
;Глобальные регистровые переменные:
.def temp = r16 ;временный регистр temp
;----------------------------------------------------------------------------
.DSEG ;сегмент данных, будем описывать переменные в ОЗУ
Led1Tmr: .byte 1 ;программный таймер светодиода 1 (1 байт)
Led2Tmr: .byte 1 ;программный таймер светодиода 2 (1 байт)
;----------------------------------------------------------------------------
.CSEG ;дальше идет программа, переходим в сегмент кода
;----------------------------------------------------------------------------
;Векторы прерываний:
.org 0 ;по адресу 0 вектор сброса
rjmp Init ;переход на основную программу
.org OVF0addr ;по адресу OVF0addr вектор прерывания по
rjmp Timer ;переполнению таймера 0
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;Программа начинает выполняться отсюда:
;Здесь пишем всякую инициализацию, которая должна
;выполняться один раз при старте программы.
Init: ldi temp,RAMEND ;константа RAMEND определена в 2313def.inc
out SPL,temp ;инициализируем стек
;Настройка портов:
ldi temp,0xFF ;загружаем в temp FF
out DDRB,temp ;настраиваем порт B на вывод
out DDRD,temp ;настраиваем порт D на вывод
;Инициализация переменных:
ldi temp,LED_DEL
sts LedTmr,temp ;загружаем в переменную значение LED_DEL
;Настройка оборудования:
ldi temp,(1<<CS02) ;предделитель таймера CK/256
out TCCR0,temp ;записываем в регистр TCCR0
ldi temp,(1<<TOIE0) ;бит TOIE0 равен единице, остальные нули
out TIMSK,temp ;разрешаем прерыв. по переполн. таймера 0
sei ;общее разрешение прерываний
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;Основной цикл программы:
;То, что написано в этом цикле, будет выполняться
;до бесконечности:
Main: lds temp,Led1Tmr ;загружаем в temp переменную Led1Tmr
tst temp ;проверяем значение
brne NoDeal1 ;если не ноль, то все пропускаем
rcall Toggle1 ;если ноль, то вызываем Toggle1
ldi temp,LED1_DEL ;и
sts Led1Tmr,temp ;перезагружаем Led1Tmr
NoDeal1: lds temp,Led2Tmr ;загружаем в temp переменную Led2Tmr
tst temp ;проверяем значение
brne NoDeal2 ;если не ноль, то все пропускаем
rcall Toggle2 ;если ноль, то вызываем Toggle2
ldi temp,LED2_DEL ;и
sts Led2Tmr,temp ;перезагружаем Led2Tmr
NoDeal2: rjmp Main ;цикл
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;Всё, дальше идут всякие подпрограммы.
;----------------------------------------------------------------------------
;Подпрограмма переключения состояния светодиода 1:
Toggle1: sbis LEDS_PORT,LED1_PIN ;проверяем состояние порта светодиода
rjmp On1 ;если был выключен, переход на включение
Off1: cbi LEDS_PORT,LED1_PIN ;выключение светодиода
rjmp TglRet1 ;переход на ret
On1: sbi LEDS_PORT,LED1_PIN ;включение светодиода
TglRet1: ret
;----------------------------------------------------------------------------
;Подпрограмма переключения состояния светодиода 2:
Toggle2: sbis LEDS_PORT,LED2_PIN ;проверяем состояние порта светодиода
rjmp On2 ;если был выключен, переход на включение
Off2: cbi LEDS_PORT,LED2_PIN ;выключение светодиода
rjmp TglRet2 ;переход на ret
On2: sbi LEDS_PORT,LED2_PIN ;включение светодиода
TglRet2: ret
;----------------------------------------------------------------------------
;Обработчик прерывания таймера 0:
;Таймер 0 имеет разрядность 8 бит, т.е. переполнение происходит
;каждые 256 тактов. Учитывая то, что предделитель таймера
;мы запрограммировали на CK/256, то таймер будет переполняться
;каждые 65536 периодов частоты кварца. Если частота кварца
;10 МГц (период 0.1 мкс), то период переполнений таймера равен
;6.5536 мс. Это значение, умноженное на число, загружаемое в
;LedTmr даст время полупериода мигания светодиода.
Timer: push temp ;сохранение регистра temp
in temp,SREG ;temp <- SREG
push temp ;сохранение SREG
lds temp,Led1Tmr ;загружаем в temp переменную Led1Tmr
tst temp ;проверяем значение
breq Ovf1 ;если ноль, ничего не делаем
dec temp ;иначе temp - 1
sts Led1Tmr,temp ;сохраняем новое значение
Ovf1: lds temp,Led2Tmr ;загружаем в temp переменную Led2Tmr
tst temp ;проверяем значение
breq Ovf2 ;если ноль, ничего не делаем
dec temp ;иначе temp - 1
sts Led2Tmr,temp ;сохраняем новое значение
Ovf2: pop temp ;восстановление SREG
out SREG,temp ;SREG <- temp
pop temp ;восстановление регистра temp
reti ;выход из обработчика и разрешение прерываний
;----------------------------------------------------------------------------
извиняйте, если что не так, правил на ходу. Но эта старая программа написана в дурном стиле. Лучше делайте на основе новой по ссылке выше.
Отредактировано Liv (21.09.2006 17:46:10)
Вне форума
У меня есть та, что новее. Но мне все же хотелось бы так как вы сейчас написали. Я все пишу для того контроллера управления питанием. (долго не брался, снова начал). Мне кажется там с двумя процессами не получиться. Дело в том, что идет управление одним объектом, просто в разных случаях нужны разные задержки. У меня была мысль сделать так, как Jaxon предложил. Но что-то не понравилось.
Спасибо за помощь, буду дальше ковырять.
......There is someone in my head, but it's not me.......
Вне форума
Тут по ходу возник вопрос по прерываниям, возможно нужно побольше порыться "в бумагах", но может, кто то кратко объяснит? Итак,вопос.. Как известно у АВР фиксировананая иерархия приорететов прерываний, допустим, что контроллер находится внутри обработчика прерывания, скажем, по INT0 (достаточно длинном). В это время наступает условие преывания, к примеру по перепаду(или он два раза переключился за это время) от ANA_COMP, получается, что оно будет пропущено?, или как?
Отредактировано Vasil (21.09.2006 21:41:15)
Вне форума
Дело в том, что идет управление одним объектом, просто в разных случаях нужны разные задержки.
Так в чем проблема? В разных случаях загружайте один и тот же программный таймер разными константами.
Вне форума
Тут по ходу возник вопрос по прерываниям, возможно нужно побольше порыться "в бумагах", но может, кто то кратко объяснит? Итак,вопос.. Как известно у АВР фиксировананая иерархия приорететов прерываний, допустим, что контроллер находится внутри обработчика прерывания, скажем, по INT0 (достаточно длинном). В это время наступает условие преывания, к примеру по перепаду(или он два раза переключился за это время) от ANA_COMP, получается, что оно будет пропущено?, или как?
выполняеться, которое выполнялось, потом переходит по приоритету
Вне форума
Как известно у АВР фиксировананая иерархия приорететов прерываний
Приоритетов прерываний у AVR нет вообще.
допустим, что контроллер находится внутри обработчика прерывания, скажем, по INT0 (достаточно длинном). В это время наступает условие преывания, к примеру по перепаду (или он два раза переключился за это время) от ANA_COMP, получается, что оно будет пропущено?, или как?
Когда начинает выполнятся обработчик прерывания, все другие прерывания автоматически запрещаются. Если Вы хотите, чтобы при обработке прерывания обслуживались другие прерывания, поставьте в начале обработчика команду разрешения прерываний "sei".
Вне форума
[ Сгенерировано за 0.060 сек, 9 запросов выполнено - Использовано памяти: 629.92 Кбайт (Пик: 680.29 Кбайт) ]