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

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

Сообщение pesn »

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

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

Сообщение jordan »

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

Сообщение pesn »

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

Сообщение coredumped »

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

Сообщение pesn »

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

Сообщение coredumped »

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

Сообщение pesn »

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

Сообщение 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:
Все будет только лучше, в крайнем случае - хуже.
Родился
Сообщения: 16
Зарегистрирован: Вс ноя 13, 2011 13:29:22

Сообщение pesn »

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

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

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