Светодиоды c пиксельной адресацией WS2812B

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Начало тут.

Сделал для 2313. Тактовая частота 20МГц. Выход PB4. Потом можно переделать на таймер 0 и там будет нужная Вам нога, СКАЗОЧНИК. Есть возможность присобачить на PB4?

20МГц наверняка даст возможность выдвигать биты в цикле (может и 16 хватит). Но пускай пока для каждого бита свой код. Главное проверить работоспособность.

На линию выкидывает 100 байт начиная с адреса 0x60.
Спойлер

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

.equ eTOP=0x18 //предел счетчика для 20МГц
.equ eBit1=0xF //длительность единичного импулься для лог1
.equ eBit0=0x08
//---------------------------------------
.def zero=R1

.def buf=R16

.def Bit1 =R17
.def Bit0 =R18
.def SbrosFlag=R19

.def Chislo=R20

//-----------------
.macro SetBit
	out TIFR,SbrosFlag
	//sbrc chislo,@0
	out OCR1BL,bit1
	sbrs chislo,@0
	out OCR1BL,bit0
.endm

.Macro WaitFlag//ждем когда сбросится счетчик
		in BUF,TIFR			
		ANDi buf,1<<TOV1
		breq PC-2
.endm
//---------------------

 .org 0

rjmp RESET ; Reset Handler
reti//rjmp EXT_INT0 ; IRQ0 Handler
reti//rjmp PCINT0 ; PCINT0 Handler
reti//rjmp TIM0_OVF ; Timer0 Overflow Handler
reti//rjmp EE_RDY ; EEPROM Ready Handler
reti//rjmp ANA_COMP ; Analog Comparator Handler
reti//rjmp TIM0_COMPA ; Timer0 CompareA Handler
reti//rjmp TIM0_COMPB ; Timer0 CompareB Handler
reti//rjmp WATCHDOG ; Watchdog Interrupt Handler
reti//rjmp ADC ; ADC Conversion Handler
;

//--------------------------------------------

RESET:  //
ldi buf,low(RAMEND)
out SPL, buf
//ldi buf,High(RAMEND)
//out SPH,buf

//константы
ldi buf,0
mov zero,buf
ldi Bit1,eBit1 //значение для передачи 1
ldi Bit0,eBit0//0
ldi SbrosFlag,1<<TOV1

//Настройка таймера 1
Ldi buf,eTop         //Предел счета
out OCR1AH,zero
out OCR1AL,buf

         


//настройка порта
ldi buf,1<<PB4
out DDRB,buf
//cbi PORTB,1<<PB3 //на всякий случай выключить порт



//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

//Функция вывод ОЗУ на диоды
//изначально таймер должен быть обязательно в нормальнром режиме и выключен

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//**************************************************8
ldi Xl,low(100) //счечтик отправленных байт
ldi XH,High(100)

ldi Zl,low(0x60) //адрес откуда считывать данные
ldi ZH,High(0x60)



out TCNT1h, zero  //установить счетчик чуть меньшим значение верха
ldi buf,eTop-2
out TCNT1l,buf

//*************************
//Занести ноль в старшой буфер
out OCR1BH,zero
//переключение выхода

ld chislo,Z+
//ldi chislo,0x55
SetBit 7
		

//------------------------------------------
// понеслась
LDI buf,(1<<WGM10)|(1<<WGM11)|(1<<COM1B1)|(0<<COM1B0)
out TCCR1A,buf
LDI buf,(1<<WGM13)|(1<<WGM12)+1
out TCCR1B,buf
//______________________

		WaitFlag
		
Cicle:		
		SetBit 6
		WaitFlag
		
		SetBit 5
		WaitFlag
		
		SetBit 4
		WaitFlag
		

		SetBit 3
		WaitFlag
		
		SetBit 2
		WaitFlag
		

		SetBit 1
		WaitFlag
		
		SetBit 0
		WaitFlag
		
		
SBIW X,1
breq Stop
		ld chislo, Z+
		
		SetBit 7
		WaitFlag
		 

		rjmp Cicle

//таймер стоп 
Stop:
		out TCCR1B,zero
		out TCCR1A,zero
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
loop:

	rjmp loop


Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

А где сам массив данных то в ОЗУ??? Или я не понимаю чего-то... :dont_know:

На РВ4 подпаяю сейчас. )
Станислав
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Ну вы уж сами туда чего-нибудь "насувайте". Можно же собственно из ФЛЕШ выдвигать.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

еЛКИ. я со своими тормозными мозгами туда буду еще два часа думать, как чего засунуть. Мне все время регистров хватало и с памятью раза два всего дело имел.

Есть массив типа такого:

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

DATA:	.db 0b11111111, 0b11111111, 0b00000000, 0b00000000, 0b11111111, 0b11111111	; 1,2
		  	.db 0b11111111, 0b00000000, 0b11111111, 0b00000000, 0b11111111, 0b00000000	; 3,4
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 5,6
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 7,8
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 9,10
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 11,12
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 13,14
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 15,16
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 17,18
Он во флеше. Как я его так быстренько с 0х60 адреса насую? :oops: :oops: :oops:

Простите, что я такой тупой... ((( Но программирование мне тяжко дается. :facepalm:
Станислав
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Команды ld chislo, Z+ в двух местах замените на lpm chislo, Z+ . В Z загрузите не 0x60, а DATA*2 (двойное значение метки). В Х фактическое количество байт. Вроде так, если не затупил. Будет сразу читать из флеша и озу не надо.

Помните, я в железе не проверял. Самому интересно что вышло, и не факт что заработает. Хотя в протеусе вроде все правильно.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Так оно из Флеша будет за 3 такта читать, а из ОЗУ вроде за 2....
Станислав
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Но и частота 20МГц ,а не 16. Смысл - команды, что-то меняющие, должны это сделать , чтобы счетчик не успел досчитать до Топа, так как после этого пойдет следующий бит. В данном случае 0x18 или 25 тактов. А вот когда 16 МГц было - только 20 тактов и вроде все работало в симуляторе. Вся привязка к таймеру, быстрее можно делать, но это ничего не даст.

По-моему как-то тупо объяснил.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Да, работает ваш алгоритм. ) Только я его все равно не понимаю.

Однако, добавил библиотеки вверху, а то ругаться начал на неопределенные выражения всякие. Сменил чтение из ОЗУ с адреса 0х60 на чтение из Флеша по метке.
Добавил и сам массив в самом низу.


Одно исправление, не 100 элементов массива, а 54 (ну у меня изначально он был на 54 байта ИЛИ 18 светодиодов). И вывод на три светодиода. Т.к. остальные у меня не распаяны.

Работает хорошо. Даже, как мне показалось, лучше чем мой вариант. Но... это к сожалению не мой... (((
Спойлер

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



	.include "tn2313def.inc"



.equ eTOP=0x18 //предел счетчика для 20МГц
.equ eBit1=0xF //длительность единичного импулься для лог1
.equ eBit0=0x08
//---------------------------------------
.def zero=R1

.def buf=R16

.def Bit1 =R17
.def Bit0 =R18
.def SbrosFlag=R19

.def Chislo=R20







//-----------------
.macro SetBit
   out TIFR,SbrosFlag
   //sbrc chislo,@0
   out OCR1BL,bit1
   sbrs chislo,@0
   out OCR1BL,bit0
.endm

.Macro WaitFlag//ждем когда сбросится счетчик
      in BUF,TIFR         
      ANDi buf,1<<TOV1
      breq PC-2
.endm
//---------------------

 .org 0

rjmp RESET ; Reset Handler
reti//rjmp EXT_INT0 ; IRQ0 Handler
reti//rjmp PCINT0 ; PCINT0 Handler
reti//rjmp TIM0_OVF ; Timer0 Overflow Handler
reti//rjmp EE_RDY ; EEPROM Ready Handler
reti//rjmp ANA_COMP ; Analog Comparator Handler
reti//rjmp TIM0_COMPA ; Timer0 CompareA Handler
reti//rjmp TIM0_COMPB ; Timer0 CompareB Handler
reti//rjmp WATCHDOG ; Watchdog Interrupt Handler
reti//rjmp ADC ; ADC Conversion Handler
;

//--------------------------------------------

RESET:  //
ldi buf,low(RAMEND)
out SPL, buf
//ldi buf,High(RAMEND)
//out SPH,buf

//константы
ldi buf,0
mov zero,buf
ldi Bit1,eBit1 //значение для передачи 1
ldi Bit0,eBit0//0
ldi SbrosFlag,1<<TOV1

//Настройка таймера 1
Ldi buf,eTop         //Предел счета
out OCR1AH,zero
out OCR1AL,buf

         


//настройка порта
ldi buf,1<<PB4
out DDRB,buf
//cbi PORTB,1<<PB3 //на всякий случай выключить порт



//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

//Функция вывод ОЗУ на диоды
//изначально таймер должен быть обязательно в нормальнром режиме и выключен

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//**************************************************8
ldi Xl,low(54) //счечтик отправленных байт
ldi XH,High(54)

ldi ZH, high (DATA*2) 
ldi ZL, low (DATA*2)



out TCNT1h, zero  //установить счетчик чуть меньшим значение верха
ldi buf,eTop-2
out TCNT1l,buf

//*************************
//Занести ноль в старшой буфер
out OCR1BH,zero
//переключение выхода

lpm chislo, Z+
//ldi chislo,0x55
SetBit 7
      

//------------------------------------------
// понеслась
LDI buf,(1<<WGM10)|(1<<WGM11)|(1<<COM1B1)|(0<<COM1B0)
out TCCR1A,buf
LDI buf,(1<<WGM13)|(1<<WGM12)+1
out TCCR1B,buf
//______________________

      WaitFlag
      
Cicle:      
      SetBit 6
      WaitFlag
      
      SetBit 5
      WaitFlag
      
      SetBit 4
      WaitFlag
      

      SetBit 3
      WaitFlag
      
      SetBit 2
      WaitFlag
      

      SetBit 1
      WaitFlag
      
      SetBit 0
      WaitFlag
      
      
SBIW X,1
breq Stop
      lpm chislo, Z+
      
      SetBit 7
      WaitFlag
       

      rjmp Cicle

//таймер стоп 
Stop:
      out TCCR1B,zero
      out TCCR1A,zero
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
loop:

   rjmp loop




   ;----------------------- ВЫВОД НА СВЕТОДИОДЫ --------------------------------------------------


	DATA:	.db 0b11111111, 0b00000000, 0b00000000, 0b00000000, 0b11111111, 0b00000000	; 1,2
		  	.db 0b00000000, 0b00000000, 0b11111111, 0b00000000, 0b11111111, 0b00000000	; 3,4
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 5,6
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 7,8
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 9,10
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 11,12
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 13,14
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 15,16
			.db 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000	; 17,18
		

Есть еще одна изюминка... У меня вариант не на один порт микроконтроллера, а на любые из 8 бит, и хоть все сразу. Т.к. мне надо было выводить сразу на четыре ленты.

Добавлено after 2 minutes 24 seconds:
Еще бы сделать сдвиг этого всего, чтобы цвета перемещались по ленте... )))
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Боюсь, что параллельно выдавать не потянет МК. Только зачем Вам так? Соедините их в одну линию. 200 последовательных диодов 6мс требуют времени на обновление, это долго?

Алгоритм могу пояснить.

А сдвиг - надо просто все оформить ввиде подпрограммы и вызывать ее инициализировать Z новым адресом.
Однако, добавил библиотеки вверху,
У меня Атмел студио 6. Он их сам подключает.

_______

UPD: Я таблицу то векторов от Атмеги оставил.!!!
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Я пользуюсь студией 4,19. Если посоветуете перейти на 6ю, то перейду. Однако, говорят, она более навороченная и сложная.

Алгоритм не плохо бы хорошо прокомментировать и украсивить. ))) Тогда будет понятен. Можно и так разобраться, однако, за пояснения все равно спасибо и не откажусь.

У меня тянет МК делать так, без прерываний в тупом главном цикле, т.к. мне больше от него ничего не надо, но и дергать может всем портом сразу или любым количеством битов из порта.
Зачем мне это нужно? ))) Тут уже шли у меня мутки и споры по поводу того, можно ли параллелить 4 таких светодиодных ленты на один вывод. Ну и не решился я... Хоть и не большой ток им нужен.
Мне же нужно увеличить пиксель. И поэтому пиксель на моем "экране" состоит из 4х светодиодов таких. Всего таких пикселей 18.

Теперь, если сказать, что можно было все это сделать последовательно и просто кучу светодиодов обновлять информацию, то сколько же мне в одной ТИНИ2313 понадобится памяти для этого?
Так у меня всего 18 пикселей (светодиодов) и 54 байта информации.
А в другом случае у меня 72 светодиода (при этих же пикселях), но последовательно и уже 216 байт информации... Вот и проблема, чем больше в линии светодиодов последовательно, тем больше байт выводить, хоть и быстро. А у меня 4 светодиода всегда светятся одинаково, тогда зачем увеличивать память? :)

Добавлено after 2 minutes 59 seconds:
Z_h_e писал(а):А сдвиг - надо просто все оформить ввиде подпрограммы и вызывать ее инициализировать Z новым адресом.
Вот это я в голове очень хорошо представляю. Даже примерно, как сделать сдвиг по адресу, чтобы каждый раз следующий был. Я не могу сообразить, как сделать так, чтобы те элементы, которые пропустил в итоге становились в самый конец! Чтобы круг замкнулся! :roll:
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

А я не понял, что у Вас 4 ленты одно и тоже светят. Думал что Вы хотите одновременно на 4 ленты разное выдавать.

Алгоритм такой.
Вы же видели, что для данных светодиодов 1 и 0 передаются с одинаковым периодом, но разной скважностью. Т.е. чистой воды ШИМ.
Таймер выдает аппаратный ШИМ (поэтому просто так ногу не сменить, она же жестко к таймеру привязана). Пока таймер формирует один период ШИМ, программа успевает его перенастроить на следующий период, нужной скважностью. Вот и все.
Я пользуюсь студией 4,19. Если посоветуете перейти на 6ю, то перейду.
Советую пользоваться тем, что нравится.
украсивить
Попробую, но не сегодня наверное.
СКАЗОЧНИК писал(а):Чтобы круг замкнулся!
Наверное самый простой метод, это держать две подряд таблицы во флеш. Если место есть, то чего мудрить?
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Z_h_e писал(а):Наверное самый простой метод, это держать две подряд таблицы во флеш. Если место есть, то чего мудрить?
Тоже вариант, почему-то пока не сказали, даже не подумал об этом. :dont_know:
Z_h_e писал(а):Пока таймер формирует один период ШИМ, программа успевает его перенастроить на следующий период
О! Вот теперь идея ясна. ))) Спасибо.
Z_h_e писал(а):Советую пользоваться тем, что нравится.
Почему так? Может я уже в прошлом веке торчу?... Просто привык к старому.

З.Ы. Я где-то вычитал, что тайминги у этих светодиодов не такие уж очень жесткие... И они первую часть периода принимают жестко, а хвост (остаток) можно и подзатянуть в разумных приделах, но не превышая время сброса (однако не более 10 мкс). Что я и сделал в своей реализации. Что тоже работает, хотя, может это и коряво.
Поэтому заново пересмотрю вашу идею. Да, жаль, что ШИМ аппаратный. :roll:
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

СКАЗОЧНИК писал(а):Почему так? Может я уже в прошлом веке торчу?...
Там такой же ассемблер и никакого интеллектуального и актуализированного ввода текста или как он там называется. Может у меня просто выключено и я не знаю :))) , потому что на Си когда пишешь, половину сам за тебя дописывает.
СКАЗОЧНИК писал(а):Я где-то вычитал, что тайминги у этих светодиодов не такие уж очень жесткие...
По логике вроде так и должно быть. Фронт - начало передачи бита, затем нужная длительнось высокого уровня и вроде бы держи низкий сколкько хочешь, лишь бы до резета не дотянуть. Но ДШ указывает допуск 150нс как на высокий уровень, так и на низкий.
Да, жаль, что ШИМ аппаратный. :roll:
Дык вся идея и была на аппаратном ШИМ и не надо никакие тайминги считать.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

В сети есть еще методы реализации на аппаратном SPI и UART. :roll:
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Была мысль и на UART. Только мне показалось, что если передавать одним кадром один бит, то слишком быстро для UART, а дробить например на 5 бит не захотелось думать. UART еще инвертировать надо. Решил с ШИМом попробовать.

А SPI даже не думал. Читать же надо, я кажется с ним на работал.

-------
Я думал что светодиоды нужны для полочек. Не думали их использовать в этой ипостаси? Они так просто упростят Вашу задачу, как программно, так и аппаратно.
Последний раз редактировалось Z_h_e Чт окт 20, 2016 20:02:56, всего редактировалось 1 раз.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

А на СТМ32 вообще прямой доступ к памяти используют... в наглую. :kill: :))) Жаль АВР это не умеют. Ничего, скоро и тех возьмем. Еще бы мозги не сопротивлялись... :?
Станислав
Друг Кота
Аватара пользователя
Сообщения: 15607
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Уважаемый Z_h_e предложил вариант на таймере:
http://radiokot.ru/forum/viewtopic.php? ... 3#p2893993
однако...
когда ранее прсматривал варианты исполнения мне такое решение показалось не слишком практичным...
не столько из-за применения аппаратно-зависимой привязки к выводам МК, склько из-за невозможности вписаться во время даташита...
размышлялось примерно так:
всего допустимо 20 циклов при 16МГц
с учетом реакции на прерывание надо минимум возможного
причем здесь вариант для 1-байтового Т/С1 (тини45)! в другом случае потребно 2 байта для перезагрузки
ocr1 !
ежли прерывание, то тело его обработчика

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

   rol tmp_dat ; 1 сдвиг следующего бита
   brcs trs_1 ; 1-нет/2-да анализ следующего бита на 1
   out ocr1a,tsl0 ; 1 загрузка слота 0
   rjmp ands_slts ; 2 переход на анализатор исчерпания бит
trs_1:
   out ocr1a,tsl1 ; 1 загрузка слота 1
ands_slts:
   dec cntb ; 1 счетчик текущих бит - 1
   brne prolg ; 1-нет/2-да проверка исчерпания счетчика текущих бит
   ldi cntb,8 ; 1 перезагрузка при исчерпании
   sbiw r25,1 ; 2 счетчик байт массива -1
   brbs Z,end_mass_tr ; 1-нет/2-да проверка на завершение массива
   ld tmp_dat,x+ ; 2 если еще есть байт загружаем в буфер вывода
prolg:
   reti ; 4 примерно 16 тактов при максимальной длине = запас в 4 такта...
end_mass_tr:
 stop t_c1 ; здесь уже время не существенно
   reti ;

если используем программное ожидание, то ставится фрагмент

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

wait:
  ; засада - TIFR за пределами области прямоанализируемых бит портов,
	;  значит нужен еще один временный регистр...
		in tmpf,TIFR ; 1
		sbrs tmpf,TOV1 ; 1-нет/2-да
	rjmp wait ; 2
	  ldi tmpf,(1<<TOV1) ; 1
		out TIFR,tmpf ; 1 сброс флага TIFR.TOV1
;	и дальше повтор вышеприведенного
	 rol tmp_dat ; 1 сдвиг следующего бита
   brcs trs_1 ; 1-нет/2-да анализ следующего бита на 1
   out ocr1a,tsl0 ; 1 загрузка слота 0
   rjmp ands_slts ; 2 переход на анализатор исчерпания бит
trs_1:
   out ocr1a,tsl1 ; 1 загрузка слота 1
ands_slts:
   dec cntb ; 1 счетчик текущих бит - 1
   brne prolg ; 1-нет/2-да проверка исчерпания счетчика текущих бит
   ldi cntb,8 ; 1 перезагрузка при исчерпании
   sbiw r25,1 ; 2 счетчик байт массива -1
   brbs Z,end_mass_tr ; 1-нет/2-да проверка на завершение массива
   ld tmp_dat,x+ ; 2 если еще есть байт загружаем в буфер вывода
prolg:
   rjmp wait ; 2 примерно 19 тактов при максимальной длине = запас в 1 такта...
end_mass_tr:
 stop t_c1 ; здесь уже время не существенно
тоесть при применении аппаратного таймера в некоторых случаях обработки время исполнения программы критически совпадает с периодом самого таймера, что не есть хорошо для частоты системного генератора менее 16МГц (0.0000000625секунды/такт).
Единственное преимущество более верное соответствие времени слотов 1 и 0.
:dont_know:
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Прямой доступ не пробовал. Но делал фазовый ШИМ (диммер) без участия программы. Т.е. приходит импульс детектора фазы на вход МК, таймеры сами его обрабатывают и выдают нужный сигнал. Программа туда совсем не вмешивается, кроме инициализации и смены режима. Это я еще затупил, сделал на двух таймерах, а оказалось можно сделать на одном. Есть верить одному форумчанину, у него вроде получилось.

Но я что-то пока подзабил на STM32, надо бы конечно вернуться к нему. У меня еще STM8 валяется.

Добавлено after 9 minutes 28 seconds:
BOB51 писал(а):причем здесь вариант для 1-байтового Т/С1 (тини45)! в другом случае потребно 2 байта для перезагрузки
ocr1 !
2313 позволяет работать с таким алгоритмом на 8битном таймере. Но 2 байта не требуется для перезагрузки ocr1, если не трогать буферный старший байт таймера1. А я его не трогаю.
BOB51 писал(а):с учетом реакции на прерывание надо минимум возможного
Никаких прерываний не получится, нету времени на них. Хотя я не считал, что-то мне это подсказывает.

А я Ваш код и не видел, BOB51. Смотреть не вникая - смысла нет. Разбирать чего-то уже голова не варит. Очень даже может быть Ваша идея значительно лучше моей. Меня приятно удивили существование таких светодиодов, петух меня клюнул и я решил попробовать реализовать данный алгоритм.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

А вы видели сколько они на Али стоят? :)
Станислав
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Ну я же купил их где-то :). Видел.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Ответить

Вернуться в «Периферия»