Ассемблер (ASM) для AVR в вопросах и ответах
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А, хотя нет. Вам скользящее среднее нужно.
Самый просто вариант - с буфером. Но он затратный по памяти. Есть и другие, ищите.
Самый просто вариант - с буфером. Но он затратный по памяти. Есть и другие, ищите.
- Реклама
- pyzhman
- Друг Кота
- Сообщения: 7016
- Зарегистрирован: Вс июл 12, 2009 19:15:29
- Откуда: Ижевск
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А куда ее девать-то?ploop писал(а):затратный по памяти.
Docendo discimus
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ну это смотря как усреднять. По 16 отсчётам - одно, а по 1024 уже никакой МК не справится. Тут другой алгоритм нужен.
- xkp
- Опытный кот
- Сообщения: 781
- Зарегистрирован: Ср ноя 18, 2009 12:50:31
- Откуда: ковров
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Вот и ищу у васploop писал(а):Есть и другие, ищите.
R5VCH
Хотелки:
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Хотелки:
Спойлер
Аналоговый осциллограф С1-112, С1-118, другиене/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Пожалуйста: http://we.easyelectronics.ru/Theory/che ... filtr.html
Готовый код в конце, 2 строчки на Си.
Готовый код в конце, 2 строчки на Си.
- Реклама
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Всем привет! Добрался до 7 сегментников...
Набираю код как в статье тык и в протеусе выходит одна и та же ошибка. При копировании кода то же самое.
И если есть у кого по проще реализация динамической индикации то поделитесь пожалуйста)))
Набираю код как в статье тык и в протеусе выходит одна и та же ошибка. При копировании кода то же самое.
И если есть у кого по проще реализация динамической индикации то поделитесь пожалуйста)))
- Вложения
-
- ошибка.JPG
- (119.16 КБ) 524 скачивания
- zero648
- Вымогатель припоя
- Сообщения: 650
- Зарегистрирован: Пн июн 18, 2012 12:01:04
- Откуда: Челябинская область, Копейск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
В коде после sei нужно вставить примерно следующее:
...
out TIMSK,temp
sei
main:
...
rjmp main
.
service_T1COMPA: ;обработчик прерывания по совпадению OCR1A
in temp,SREG ;при входе сохраняем в стеке
push temp ;регистры temp, SREG
clr temp
...
В блоке main уже можно менять значения выводимые на индикатор.
...
out TIMSK,temp
sei
main:
...
rjmp main
.
service_T1COMPA: ;обработчик прерывания по совпадению OCR1A
in temp,SREG ;при входе сохраняем в стеке
push temp ;регистры temp, SREG
clr temp
...
В блоке main уже можно менять значения выводимые на индикатор.
- dr.doc
- Это не хвост, это антенна
- Сообщения: 1368
- Зарегистрирован: Вс мар 28, 2010 12:52:22
- Откуда: Беларусь
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Кстати, цифровой фильтр, приведенный на easyelectronics - хорошая вещь. Писал для однополупериодного выпрямителя, так можно добиться отсутствия дергания МЗР, причем без труда.
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Да, я тоже с ним экспериментировал (правда на ассемблер не перекладывал). Прост и эффективен.
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Реализовал на ассемблере, только до этого ничерта не знал про эти фильтры, и прочитав эту тему понял что изобрел. Бывает же...
- dr.doc
- Это не хвост, это антенна
- Сообщения: 1368
- Зарегистрирован: Вс мар 28, 2010 12:52:22
- Откуда: Беларусь
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А Вы попробуйте порядок повыше - отработка выхода заметно выше, а пульсации практически около 0.
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Подскажите как сделать счетчик. Только код не кидайте. А скажите куда копать.
По нажатию на кнопку увеличивает число и выводит на семисегментник
По нажатию на кнопку увеличивает число и выводит на семисегментник
Спойлер
Код: Выделить всё
.include "m8def.inc"
.DSEG
.def temp1=r16
.def temp2=r17
digit: .byte 2
.CSEG
ldi r16,high(RAMEND)
out SPH,r16
ldi r16,low(RAMEND)
out SPL,r16
reset:
sts digit+1,r16
ldi r16,0xff
out DDRD,r16
out DDRB,r16
ldi r16,(0<<DDC0)
out DDRC,r16
ldi r16,(1<<PC0)
out PORTC,r16
ldi r18,1 //число для вывода на 7 сегм
main: in r16,PINC
sbrc r16,0
rjmp main
rjmp decr
decr: mov r16,r18
inc r16 // увеличиваем его на 1
mov r18,r16
call display
rjmp main
decoder: ldi ZL,low(M*2)
ldi ZH,high(M*2)
add ZL,temp1
ldi temp2,0
adc ZH,temp2
lpm temp1,Z
ret
M:
; hgfedcba hgfedcba
.db 0b00111111,0b00000110 ;0,1
.db 0b01011011,0b01001111 ;2,3
.db 0b01100110,0b01101101 ;4,5
.db 0b01111101,0b00000111 ;6,7
.db 0b01111111,0b01101111 ;8,9
Delay:
ldi temp1,0
ldi temp2,4
Dll:
dec temp1
brne Dll
dec temp2
brne Dll
ret
display: ldi temp1,0b00111101
out PortB,temp1
lds temp1,digit
call decoder
out PortD,temp1
call Delay
ret
Последний раз редактировалось Gudd-Head Вт мар 25, 2014 15:29:36, всего редактировалось 1 раз.
Причина: Нарушение п.2.5 Правил Форума
Причина: Нарушение п.2.5 Правил Форума
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Вот так и делать:alexsaska писал(а):Подскажите как сделать счетчик.
По нажатию на кнопку увеличивает число и выводит на семисегментник
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- xkp
- Опытный кот
- Сообщения: 781
- Зарегистрирован: Ср ноя 18, 2009 12:50:31
- Откуда: ковров
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
По-моему что то в этом коде много лишнего... если нужно всего-то инкрементировать регистр по нажатию кнопки.
Если автору не надо примерно готовый код - спойлер не смотреть.
main:
;если кнопка при нажатии замыкает вывод pinc0 на массу (GND)
sbic pinc,0
rjmp main
inc r18
rcall displey
rjmp main
decoder:
***
Ну это касаемо основного цикла программы просмотром беглым взглядом.
Что касается таблицы "M:", тоже не правильно сделана. Не то что бы не правильно... Я делаю по-другому.
Если автору не надо примерно готовый код - спойлер не смотреть.
decind:
ldi zh,high(2*tabind)
ldi zl,low(2*tabind)
add zl,tmp
clr tmp
adc zh,tmp
lpm
mov tmp,r0
ret
;============
;= таблица символов для семисегментного индикатора =
;= 0123456789ABCDEF =
;============
tabind:
.dw 0b1111100111000000 ;1-0
.dw 0b1011000010100100 ;3-2
.dw 0b1001001010011001 ;5-4
.dw 0b1111100010000010 ;7-6
.dw 0b1001000010000000 ;9-8
.dw 0b1000001110001000 ;b-a
.dw 0b1010000110100111 ;d-c
.dw 0b1000111010000110 ;f-e
И да. В двойных байтах значения идут наоборот не как у автора 0,1;2,3... а 1,0;3,2. Ибо в двойном байте сначало идет старший (слева) байт, потом (справа) младший.
PS. не знаю как у вас но у меня студия ругается на call, заменил все на rcall. И еще у вас не правильная метка. У вас написано call displEy, а метка стоит displAy:
Если автору не надо примерно готовый код - спойлер не смотреть.
Спойлер
***main:
;если кнопка при нажатии замыкает вывод pinc0 на массу (GND)
sbic pinc,0
rjmp main
inc r18
rcall displey
rjmp main
decoder:
***
Что касается таблицы "M:", тоже не правильно сделана. Не то что бы не правильно... Я делаю по-другому.
Если автору не надо примерно готовый код - спойлер не смотреть.
Спойлер
необходимое значение в TMP (r16), результат там жеdecind:
ldi zh,high(2*tabind)
ldi zl,low(2*tabind)
add zl,tmp
clr tmp
adc zh,tmp
lpm
mov tmp,r0
ret
;============
;= таблица символов для семисегментного индикатора =
;= 0123456789ABCDEF =
;============
tabind:
.dw 0b1111100111000000 ;1-0
.dw 0b1011000010100100 ;3-2
.dw 0b1001001010011001 ;5-4
.dw 0b1111100010000010 ;7-6
.dw 0b1001000010000000 ;9-8
.dw 0b1000001110001000 ;b-a
.dw 0b1010000110100111 ;d-c
.dw 0b1000111010000110 ;f-e
И да. В двойных байтах значения идут наоборот не как у автора 0,1;2,3... а 1,0;3,2. Ибо в двойном байте сначало идет старший (слева) байт, потом (справа) младший.
R5VCH
Хотелки:
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Хотелки:
Спойлер
Аналоговый осциллограф С1-112, С1-118, другиене/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
-
Alexeyslav
- Друг Кота
- Сообщения: 4550
- Зарегистрирован: Чт май 05, 2011 21:26:34
- Откуда: Украина, Славутич
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Если задавать по .DB то порядок нормальный, по мере роста адреса. Только надо четко отслеживать чтобы количество байт в строке было кратно 2 иначе компилятор дополнит лишним нулем. В две строгие колонки соблюсти это условие не составляет проблем.
Насчет алгоритма. Если в кратце, то его надо разделить на две части: Реализацию самого счетчика и индикацию. Обе эти части можно делать сильно по разному, можно реализовать динамическую индикацию а можно статическую непосредственно контроллером или при помощи регистров сдвига вроде HC595.
Сам счетчик можно реализовать так(если надо наглядней): в бесконечном цикле выдерживаем паузу 10мс, считываем состояние вывода к которому подключена кнопка, сравниваем с предыдущим состоянием если оно равно 1 а текущее 0 то выполянем инкремент счетчика, иначе - ничего не делаем. Запоминаем считанное(в начале цикла, ЗДЕСЬ нельзя считывать кнопку заново!!! иначе чревато проблемами с дребезгом) состояние кнопки как предыдущее.
Инкремент счетчика. Если надо наглядно - то отводим на 1 знакоместо 1 байт, и начиная с младшего разряда прибавляем 1 если получилось число больше 9 то обнуляем этот разряд и инкрементируем ТОЧНО ТАК ЖЕ старший разряд - эти разряды можно каскадировать до тех пор пока память не закончится. для 3-4 разрядов удобно использовать для этих целей сами регистры, а еси больше надо то придется расположить в RAM.
Собственно на этом алгоритм счета закончен.
Дальше идет индикация. Если выбрали статическую - то сразу после отработки цикла берем по разрядно преобразуем цифру в ячейке каждого разряда в 7-сегментный код и выводим в регистр/порт.
Если же динамическая...
Тут все интересней, надо с задержкой сильно примерно 1мс(удобно использовать для этого прерывание от таймера работающего в режиме CTC):
1) погасить сегменты, 2) переключить на следующий разряд, 3) соответствующую разряду ячейку преобразовать с 7-сегментный код 4) вывести этот код на выводы сегментов. и ВСЁ.
Хоть в нашем варианте все будет работать без проблем, но по-хорошему на время выполнения алгоритма инкремента надо запрещать прерывания - иначе на вывод может уйти неконсистентное состояние счетчика. Собственно, в нашей программе на это п***ть - неконсистентным вывод будет достаточно редко и только в течение 1мс.
Правда у этого всего будет один недостаток - из-за подавления дребезга частота нажатий не может превышать 50Гц. В случае необходимости более высокой частоты счета нужны будут специальные кнопки и другие методы подавления дребезга. Например, настроить один из таймеров на счет от внешнего сигнала и подавать импульсы на отведенный для этого вывод МК, потом корректно обрабатывать событие переполнения таймера(счет старших разрядов, если разрядности таймера не хватит) и считывать при необходимости значение из таймера(обрати внимание на правильную последовательность считывания старшего/младшего разряда 16-бит таймера чтобы не получить неконсистентное состояние), производить преобразование целого числа в строку и выводить на индикатор.
Насчет алгоритма. Если в кратце, то его надо разделить на две части: Реализацию самого счетчика и индикацию. Обе эти части можно делать сильно по разному, можно реализовать динамическую индикацию а можно статическую непосредственно контроллером или при помощи регистров сдвига вроде HC595.
Сам счетчик можно реализовать так(если надо наглядней): в бесконечном цикле выдерживаем паузу 10мс, считываем состояние вывода к которому подключена кнопка, сравниваем с предыдущим состоянием если оно равно 1 а текущее 0 то выполянем инкремент счетчика, иначе - ничего не делаем. Запоминаем считанное(в начале цикла, ЗДЕСЬ нельзя считывать кнопку заново!!! иначе чревато проблемами с дребезгом) состояние кнопки как предыдущее.
Инкремент счетчика. Если надо наглядно - то отводим на 1 знакоместо 1 байт, и начиная с младшего разряда прибавляем 1 если получилось число больше 9 то обнуляем этот разряд и инкрементируем ТОЧНО ТАК ЖЕ старший разряд - эти разряды можно каскадировать до тех пор пока память не закончится. для 3-4 разрядов удобно использовать для этих целей сами регистры, а еси больше надо то придется расположить в RAM.
Собственно на этом алгоритм счета закончен.
Дальше идет индикация. Если выбрали статическую - то сразу после отработки цикла берем по разрядно преобразуем цифру в ячейке каждого разряда в 7-сегментный код и выводим в регистр/порт.
Если же динамическая...
Тут все интересней, надо с задержкой сильно примерно 1мс(удобно использовать для этого прерывание от таймера работающего в режиме CTC):
1) погасить сегменты, 2) переключить на следующий разряд, 3) соответствующую разряду ячейку преобразовать с 7-сегментный код 4) вывести этот код на выводы сегментов. и ВСЁ.
Хоть в нашем варианте все будет работать без проблем, но по-хорошему на время выполнения алгоритма инкремента надо запрещать прерывания - иначе на вывод может уйти неконсистентное состояние счетчика. Собственно, в нашей программе на это п***ть - неконсистентным вывод будет достаточно редко и только в течение 1мс.
Правда у этого всего будет один недостаток - из-за подавления дребезга частота нажатий не может превышать 50Гц. В случае необходимости более высокой частоты счета нужны будут специальные кнопки и другие методы подавления дребезга. Например, настроить один из таймеров на счет от внешнего сигнала и подавать импульсы на отведенный для этого вывод МК, потом корректно обрабатывать событие переполнения таймера(счет старших разрядов, если разрядности таймера не хватит) и считывать при необходимости значение из таймера(обрати внимание на правильную последовательность считывания старшего/младшего разряда 16-бит таймера чтобы не получить неконсистентное состояние), производить преобразование целого числа в строку и выводить на индикатор.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
xkp, Alexeyslav спасибо за помощь!!! Получилось
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Опять вопрос:( Допустим мне надо вывести число 258 на индикатор, т.е. мне нужно разбить его на 2,5 и 8 и вывести их по отдельности на индикатор? Или по другому это делается?
- dr.doc
- Это не хвост, это антенна
- Сообщения: 1368
- Зарегистрирован: Вс мар 28, 2010 12:52:22
- Откуда: Беларусь
Re: Ассемблер (ASM) для AVR в вопросах и ответах
convert BIN to BCD.
- Вложения
-
- То, что нужно.txt
- (1.14 КБ) 221 скачивание
Последний раз редактировалось dr.doc Ср мар 26, 2014 22:53:54, всего редактировалось 1 раз.
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
- xkp
- Опытный кот
- Сообщения: 781
- Зарегистрирован: Ср ноя 18, 2009 12:50:31
- Откуда: ковров
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
я использую простой алгоритм. 258 - это больше одного байта, а точнее 2 байта. Максимальное число из двух байтов это 65535. Исходя из этой цифры построен алгоритм. Назовем наше число "Х", а необходимые числа выводимые на индикатор IND0, IND1, IND2, IND3, IND4, где, IND0 это младший разряд индикатора - единицы, IND1 - десятки, IND2 - сотни, IND3 - тысячи, IND4 - десятки тысяч.
Если у вас только 3 разряда индикации то синие пропустить.
Берем наше число Х и делим его на 10000, результат в IND4. Остаток от Х теперь делим на 1000 - результат в IND3, остаток делим на 100 - IND2, остаток делим на 10 - IND1, и оставшийся остаток это IND0.
Если у вас только 3 разряда индикации то синие пропустить.
Берем наше число Х и делим его на 10000, результат в IND4. Остаток от Х теперь делим на 1000 - результат в IND3, остаток делим на 100 - IND2, остаток делим на 10 - IND1, и оставшийся остаток это IND0.
R5VCH
Хотелки:
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Хотелки:
Спойлер
Аналоговый осциллограф С1-112, С1-118, другиене/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ещё один готовый алгоритм:
Спойлер
Код: Выделить всё
;-------------------------------------------------------------------------------
; Декодирование 16-битного числа в десятичные цифры
; Число должно быть в X, в Y - указатель на память, куда сложить результат
; Число записывается в память справа налево, Y должен быть со смещением
; (он декрементируется), максимум 5 знаков.
;-------------------------------------------------------------------------------
word2dec:
clr r24 ; младшее число десятков
clr r25 ; старшее число десятков
w2d0:
sbiw XL,10 ; считаем количество десятков
brcs w2d1
adiw r24,1
rjmp w2d0
w2d1: ; Десятки посчитали. Забираем остаток
adiw XL,10
st -Y,XL ; Сохраняем его
movw XL,r24
or r24,r25 ; Если десятки остались,
breq w2d3 ; отправляем заново на переработку
rjmp word2dec
w2d3:
ret

