Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
02.07.2012, 15:32
|
|
Прохожий
Регистрация: 12.04.2008
Сообщений: 9
Сказал спасибо: 1
Сказали Спасибо 7 раз(а) в 7 сообщении(ях)
|
Синхронный ШИМ?
Доброго времени суток!
Возникла такая проблема:
Использую Attiny2313, задействованы оба таймера, ТС0 работает с шиной 1-Wire, TC1 - управляет двумя каналами симмисторного регулятора мощности.
Нужно независимо регулировать мощность в каждом канале, для этого в регистры OCR1A и OCR1B заносим время задержки для каждого канала, запускаем ТС1. При совпадении вызывается прерывание в котором включаем выход МК. При возникновении внешнего прерывания INT0 (от детектора нуля) выключаем выход МК. Таким образом, при минимальной задержке канал включается сразу после перехода напряжения через ноль (максимальная мощность), при максимальной задержке канал включается в самом конце полупериода напряжения, или вообще не включается, так как ТС не успевает досчитать до совпадения данных в регистрах TCNT1 и OCR1A(B) (минимальная мощность).
Вопрос 1:
При сбросе флагов от ТС1 в регистре TIFR сбрасываются флаги и от ТС0! Как это обойти?
То есть конструкция, типа
in temp1,TIFR
sbi temp1,(1‹‹OCF1A)
out TIFR,temp1
сбрасывает регистр флагов TIFR полностью.
также регистр ведет себя при записи в него $00
clr temp1
out TIFR,temp1
Адрес регистра TIFR - $38, поэтому команды CBI и SBI с ним не работают...
Вопрос 2:
Отказываемся от прерываний и работаем с выходами OC1A(B).
Для этого, так же загружаем в регистры OCR1A и OCR1B время задержки для каждого канала, выставляем биты COM1A(B) так, чтобы при совпадении канала включался выход МК, здесь все ясно.
А вот дальше то что?
Нужно при возникновении внешнего прерывания INT0 выключить выход МК. Но, поскольку выходы OC1A(B) работают как альтернативная функция порта, то по идее управление регистром PortB не работает.
Нашел datasheet описание флагов FOC1A(B) регистра TCCR1C, но как они работают не понял...
А может кто-то подскажет вообще другой алгоритм управления яркостью. Например ШИМ, но при этом он должен синхронизироваться по INT0...
Заранее благодарю за ответы и советы...
|
|
|
|
02.07.2012, 17:53
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 6,952
Сказал спасибо: 2,994
Сказали Спасибо 3,174 раз(а) в 2,154 сообщении(ях)
|
Re: синхронный ШИМ?
Сообщение от jyraf
|
in temp1,TIFR
sbi temp1,(1‹‹OCF1A)
out TIFR,temp1
сбрасывает регистр флагов TIFR полностью.
|
"sbi" не для этого. Как-то так:
Код:
|
in temp1,TIFR
andi temp1,(1‹‹OCF1A)
out TIFR,temp1 |
|
|
|
Сказали "Спасибо" ForcePoint
|
|
|
02.07.2012, 18:56
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,616
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: Синхронный ШИМ?
Сообщение от ForcePoint
|
andi temp1,(1‹‹OCF1A)
|
А может так:
Цитата:
|
andi temp1,~(1‹‹OCF1A)
|
Это если нужно сбросить бит. Если поднять - тогда:
Цитата:
|
ori temp1,(1‹‹OCF1A)
|
Я не ошибаюсь?
__________________
С уважением,
Vic / ut1wpr
|
|
|
|
02.07.2012, 20:35
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.06.2006
Адрес: Украина, Запорожье
Сообщений: 7,982
Сказал спасибо: 0
Сказали Спасибо 4,941 раз(а) в 2,370 сообщении(ях)
|
Re: Синхронный ШИМ?
jyraf,
там и одного ТС0 хватит с головой, только процесс должен быть синхронным, а тайм-слот - минимальным, в зависимости от задач 1-Wire. тогда все вращается вокруг ядра с анализом флагов. при выборе частоты кварца и величины тайм-слота, кратного мин. задержке в 1-Wire, помимо обработки датчика и управления регулировки мощности (50гц + Брезенхем) успевал динамическую индикацию и клавиатуру выводить/читать.
|
|
|
|
02.07.2012, 20:49
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
|
Re: Синхронный ШИМ?
Сброс флага в TIFR - запись единицы. Читать TIFR не надо. Иначе все сбросится.
ldi temp1,(1‹‹OCF1A)
out TIFR,temp1
|
|
|
Эти 2 пользователя(ей) сказали Спасибо kison за это сообщение:
|
|
|
03.07.2012, 14:18
|
|
Прохожий
Регистрация: 12.04.2008
Сообщений: 9
Сказал спасибо: 1
Сказали Спасибо 7 раз(а) в 7 сообщении(ях)
|
Re: Синхронный ШИМ?
Во первых всем спасибо за обсуждение, советы, ответы...
Немного комментариев:
- да, я немного погорячился с командой "sbi", спасибо kison на самом деле
ldi temp1,(1‹‹OCF1A)
out TIFR,temp1
чудесно работает...
- одного таймера для работы устройства не хватит, так как это не Master 1-Wire а Slave! То есть МК обрабатывает команды Reset, Presenс, $55, $4E, $BE, $F0... все это завязано на ТС0. А TC1 работает с выходной мощностью... Так проще и быстрее.
Вопрос решился, для тех кто будет копать в этом направлении опишу как я его решал.
- Почитал замечательную книгу господина Белова А.В. "Микроконтроллеры AVR в радтолюбительской практике". Это полное описание Attiny2313. Используя советы и рекомендации отказался от ШИМ и т.д. МК работает на частоте 8МГц, подгонять кварцами частоту под ШИМ не хочется, да и главное нужна синхронизация с синусоидой сетевого напряжения.
- Использовал ТС1 в режиме Normal, аппаратные ресурсы таймера, и выходы ТС1 OC1A(PB3) и OC1B(PB4).
Для этого:
1. Настраиваем переферию
; === Инициализация портов ввода-вывода ===============================================
outi DDRB, 0b00011000 ; B3 -› выход управления каналом 1 [выход 0]
outi PortB,0b00000000 ; B4 -› выход управления каналом 2 [выход 0]
; === Инициализация таймера/счетчика 1 ================================================
; Таймер используется для отсчета времени вкючения симмисторов
; Режим работы - Normal
out16 OCR1A,TFull ; записываем начальные установки времени
out16 OCR1B,TFull ; в оба канала ТС1
/* При частоте кварца 8МГЦ, предделителе ТС1=8 и времени полупериода сетевого напряжения = 10мс
Tfull=8000000/8/100+10=10010 ($271A), (+10 нужно для того, чтобы таймер считал немного больше чем 10мс, тогда при мощности 0% на выходе МК не будет даже коротких управляющих импульсов).
*/
sbrp TCCR1A,(3‹‹COM1A0) ; при совпадении включить каналы
sbrp TCCR1A,(3‹‹COM1B0) ;
/* Два чудесных флажка переключающие ногои МК на альтернативную функцию, теперь PB3 и PB4 выходы каналов А и В ТС1, причем если происходит совпадение данных в регистрах OCR1A(B) и TCNT1, то выходы включаются, OC1A(В)=1. То есть не нужно разрешать прерывания по совпадению, потом их обрабатывать сбрасывая ножки в 0...
*/
2. У нас есть замечательное внешнее прерывание INT1, на которое приходят сигналы от детектора нуля.
; === Инициализация внешних прерываний ================================================
; Прерывание INT0 используется для работы с сетью 1-Wire
; Прерывание INT1 синхронизирует работу регулятора мощности
sbrp MCUCR,(1‹‹ISC01) ; прерывания INT0(1-Wire) по спаду
sbrp MCUCR,(1‹‹ISC11) ; прерывания INT1(ZCD) по спаду
3. При переходе синусойды напряжения через 0, вызывается прерывание INT1. Его обработчик должен синхронизировать ТС1 и однозначно выключить оба канала регулятора мощности OC1A(В)=0!
; -------------------------------------------------------------------------
; Прерывание от детектора нуля
; -------------------------------------------------------------------------
Detect_zero: ;
pushr ; сохранить регистры в стек
push temp2 ;
clr16 TCNT1 ; сбросить ТС1
sbrp TCCR1B,(1‹‹CS11) ; перезапускаем ТС1 с предделителем 8
/* сброс ТС1 - это и есть синхронизация с сетевым напряжением, а вот запуск\перезапуск производится именно здесь для того, чтобы лампы каналов не мигали при первом включении напряжения питания
*/
outi TCCR1A,$A0 ; при совпадении выключить каналы
outi TCCR1C,$C0 ; эмулируем совпадение
outi TCCR1A,$F0 ; при совпадении включить каналы
/* А вот тут начинается самое интересное.
Если подходить классически (обработка прерываний по совпадению), то в этом месте нужно сначала сбросить флаги OCF1A(B) в регистре TIFR, а затем разрешить прерывания OCIE1A(B) в регистре TIMSK, с этим и была засада. Кроме того еще нужно сбросить выходы управления каналами (PB3 и PB4 = 0).
Что же сделал я...
В регистре TCCR1C есть два волшебных флага FOC1A и FOC1B, это флаги принудительного изменения состояния выходов OC1A и OC1B. При записи "1" в эти флаги выходы ТС1 переключаются в соответствии с установами битов COM1A(B) регистра TCCR1A. То есть для того чтобы однозначно выключить выходы каналов необходимо:
- сконфигурировать биты COM1A(B) так, чтобы при возникновении совпадения выходы выключились
outi TCCR1A,$A0 ; при совпадении выключить каналы
- принудительно изменить состояние выходов выключив их, для этого записываем "1" в соответствующие биты OCF1A(B)
outi TCCR1C,$C0 ; эмулируем совпадение
- ну и не забываем вернуть настройки битов COM1A(B) назад, чтобы при совпадении каналов выходы управления включались (PB3 и PB4 = 1)
outi TCCR1A,$F0 ; при совпадении включить каналы
*/
... ну и дальше по тексту ...
!!!ВНИМАНИЕ!!!
Этот кусок программы не работатет в эмуляторах AVRStudio и Proteus, в железе все прекрасно работает.
------------------------------------------------------------------
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 19:00.
|
|