помогите сделать диммер на авр

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
pesn
Родился
Сообщения: 16
Зарегистрирован: Вс ноя 13, 2011 13:29:22

помогите сделать диммер на авр

Сообщение pesn »

Всем привет! Очень нужна помощь... Нужно сделать светодиодный диммер на атмега16 на плате стк500. Собственно есть 8 светодиодов, кнопка и переменный резистор. Кнопкой нужно включать все светодиоды, а переменник нужен для того, чтобы плавно регулировать их яркость.

Кто-нибудь сможет помочь с написанием программы на ассемблере?
Аватара пользователя
jordan
Грызет канифоль
Сообщения: 271
Зарегистрирован: Чт апр 01, 2010 14:14:55

Re: помогите сделать диммер на авр

Сообщение jordan »

какой еще переменный резистор? 21 век на носу... ШИМ рулит, на шестнадцатой меги их аж 4, а вам я так понимаю один нужен для регулировки интенсивности свечения светодиодов. :kill:
pesn
Родился
Сообщения: 16
Зарегистрирован: Вс ноя 13, 2011 13:29:22

Re: помогите сделать диммер на авр

Сообщение pesn »

Именно! Можете помочь? Я просто совсем в этом не разбираюсь, а сделать очень нужно...
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Re: помогите сделать диммер на авр

Сообщение coredumped »

Лабораторная работа?
Все будет только лучше, в крайнем случае - хуже.
pesn
Родился
Сообщения: 16
Зарегистрирован: Вс ноя 13, 2011 13:29:22

Re: помогите сделать диммер на авр

Сообщение pesn »

coredumped, нет. Курсовой проект. Поможете?
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Re: помогите сделать диммер на авр

Сообщение coredumped »

Поможем. Что именно не получается? Для начала научитесь включать и выключать светодиоды.
1. разберитесь к какому порту подключены светодиоды
2. напишите инициализацию
Если знаний вообще 0, пишите, вечером кину скелетик программки с инициализацией портов-стека-прерываний для меги16.
Все будет только лучше, в крайнем случае - хуже.
pesn
Родился
Сообщения: 16
Зарегистрирован: Вс ноя 13, 2011 13:29:22

Re: помогите сделать диммер на авр

Сообщение pesn »

Я тут уже накидал примерный код. Не знаю, насколько правильно. Посмотрите во вложенном файле. Кто что думает по этому поводу?
Вложения
dimmer.asm
(2.57 КБ) 356 скачиваний
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Re: помогите сделать диммер на авр

Сообщение coredumped »

Вот примерчик инцнализации и запуска таймера0 в режиме Fast PWM. Это самый "правильный" метод регулирования яркости. Нужно просто занести нужное значение от 0 до 255 в регистр OCR0 и все. Все что осталось - это написать обработку нажатия кнопок (не забываем про устранение дребезга)
Светодиоды в этом примере поключены к порту A. Можете задавать вопросы, но остальное делайте сами, иначе ничему не научитесь.

Код: Выделить всё

.include "m16def.inc"

; Registers aliases - для удобства восприятия

.def   A      = r16   
.def   ctrl    = r17 ; здесь маска включенных светодиодов (0xff - включены все)
.def   bright   = r18 ; это яркость (скважность ШИМ)

.cseg
; Interrupt vectors
.org    0x0            ;Reset Vector
      rjmp    Reset

.org   INT0addr      ; External Interrupt Request 0
      reti
.org   INT1addr      ; External Interrupt Request 1
      reti
.org   OC2addr         ; Timer/Counter2 Compare Match
      reti
.org   OVF2addr      ; Timer/Counter2 Overflow
      reti
.org   ICP1addr      ; Timer/Counter1 Capture Event
      reti
.org   OC1Aaddr      ; Timer/Counter1 Compare Match A
      reti
.org   OC1Baddr      ; Timer/Counter1 Compare Match B
      reti
.org   OVF1addr      ; Timer/Counter1 Overflow
      reti
.org   OVF0addr      ; Timer/Counter0 Overflow
      rjmp   OVF0_int
.org   SPIaddr         ; Serial Transfer Complete
      reti
.org   URXCaddr      ; USART, Rx Complete
      reti   
.org   UDREaddr      ; USART Data Register Empty
      reti
.org   UTXCaddr      ; USART, Tx Complete
      reti
.org   ADCCaddr      ; ADC Conversion Complete
      reti
.org   ERDYaddr      ; EEPROM Ready
      reti
.org   ACIaddr         ; Analog Comparator
      reti
.org   TWIaddr         ; 2-wire Serial Interface
      reti
.org   INT2addr      ; External Interrupt Request 2
      reti   
.org   OC0addr         ; Timer/Counter0 Compare Match
      rjmp   OC0_int
.org   SPMRaddr      ; Store Program Memory Ready
      reti


Reset:
; set Stack Pointer to top of RAM
      ldi    A, high(RAMEND)
      out    SPH, A       
      ldi    A, low(RAMEND)
      out    SPL, A
; initialize consts
      clr      r0            ; r0 = 0
      clr      r1            
      dec      r1            ; r1 = 0xFF
; I/O setup
      out      DDRA, r1      ; set all PORTA lines as output (DDRA=0xFF)   
      out      PORTA, r0      ;

; timer0 setup       
      ldi      A,(1<<OCIE0)|(1<<TOIE0)   ; enable timer1 interrupts
      out      TIMSK, A

; clear timer0 counter            
      out      TCNT0, r0

; set 50% PWM
      ldi      bright, 0x7F
      out      OCR0, bright   

; set timer0 to Fast PWM mode
      ldi      A, (1<<WGM01)|(1<<WGM00)|(1<<CS01)
      out    TCCR0, A   ; Start timer0, prescaler=8

      sei               ; enable interrupts

      ser      ctrl      ; switch-on all LEDs


; main loop
loop:   nop
; здесь пишем остальной код - проверка нажатия кнопок, реакция на кнопки итд
      rjmp   loop


OVF0_int:
      in      r2, SREG    ; save status
      out      PORTA, ctrl   ; set all PA lines to ctrl
      out      SREG, r2   ; restore status
      reti

OC0_int:
      in      r2, SREG   ; save status
      out      PORTA, r0   ; set all PA lines to 0
      out      SREG, r2   ; restore status
      reti


Из особенностей здесь один момент - регистры, используемые в прерываниях не используются в качестве рабочих в основной программе. Это сделано для того, чтоб не сохранять их в стеке. Те в нашем примере регистр r2 не должен использоваться в основной программе - его предназначение - сохранение флагов при вызове обработчиков прерываний. Вообще, по-правильному нужно сохранять регистр флагов при вызове обработчика прерываний и регистры, которые он(обработчик) использует, если их изменение в основной программе не должно происходить. При выходе, соответственно, регистры восстанавливаются. Обычно для этого используют стек (команды push и pop). Но это не есть правило! Вы должны понимать, что делаете и для чего. Если регистров хватает, то нужно использовать их так, чтоб избегать использования RAM без особой нужды - это повысит эффективность программы.
Вот пример вызова обработчика прерывания с сохранением регистра флагов. Если флаги используются в основной программе (например переходы по условию), то сохранять их нужно обязательно, иначе обработчик прерывания может их изменить в самый неподходящий момент.
OC1B_int:
push r2 ; save r2 in stack
in r2, SREG ; save status reg in r2
push r16 ; save r16

.... обработчик

pop r16 ; restore r16
out SREG, r2 ; restore flags
pop r2 ; restore r2
reti
PS: использовать мегу16 для диммера - это расточительство. Для этого есть более дешевые tiny. Это так, мысли в слух. Для курсака конечно пофиг, а для реальной разработки - это экономическое преступление :shock:
Все будет только лучше, в крайнем случае - хуже.
pesn
Родился
Сообщения: 16
Зарегистрирован: Вс ноя 13, 2011 13:29:22

Re: помогите сделать диммер на авр

Сообщение pesn »

Просто у нас на кафедре есть модули STK500, там стоит мега 16) поэтому и курсач на меге 16.

Большое спасибо за ответ! Буду разбираться дальше!
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»