Вс июн 10, 2012 20:25:42
; Автор: ХХХ *
; Дата: 10.06.2012 *
; Версия: н/д *
; Название файла: LEDspeed *
; Для AVR: ATmega8L-8PU *
; Тактовая частота: 2.4576мГц *
; ****************************************
; Выполняемые функции: Управление скоростью бегущего огня
; ================
.device ATmega8 ; модель микроконтроллера
.nolist ; не копировать включенный файл .include в текст листинга
.include "C:\Program Files\Atmel\AVR Studio 5.0\avrassembler\include\m8def.inc" ; описание микроконтроллера
.list ; вновь разрешить запись листинга
; ================
; ===============
; макрос для инициализации
.macro outi
ldi r16,@1
.if(@0 > 0x3F)
sts @0,r16
.else
out @0,r16
.endif
.endm
; ================
; ================
; Объявления
.def temp = r16 ; директива .def назначает регистру r16 имя temp
.def mark240 = r17
.def counter = r18
.def speed = r19
; ================
; ================
; Начало программы
.cseg ; директива .cseg определяет начало сегмента кодов
.org 0 ; начало первой строки программы
rjmp Init ; перейти к метке Init
; ================
; Инициализация стека (в AVR Studio 5 инициализируется по умолчанию)
; ldi temp, Ramend ; определение
; out SPL, temp ; верхушки стека
outi SPL, low(RAMEND) ; инициализация стека через макрос
outi SPH, high(RAMEND)
; ================
; ================
; Блок инициализации
Init:
ser temp ; заполнить регистр temp (пилотное число порта D: 0b11111111)
out DDRD, temp ; переводит все биты порта D на вывод (0b11111111)
ldi temp, 0b11111000 ; пилотное число порта В
out DDRB, temp ; перевести биты порта на вывод (не используются), бит 0, 1, 2 - на ввод
ldi temp, 0b00000001 ; при старте должен быть включен только светодиод PD0
out PortD, temp ; включить светодиод PD0
ldi temp, 0b00000111 ; порт PB0,PB1,PB2 - подтяжка, остальные не используются
out PortB, temp ; отключить подтягивающие резисторы порта B, кроме бита 0, 1, 2 (здесь две кнопки)
; ===================
; подблок конфигурации таймера
ldi temp, 0b00000101 ; частота таймера: СК(2.4576 МГц)/1024 (минимальная 2457600/1024 = 2400 Гц)
out TCCR0, temp ; задать конфтгурацию таймеру (регистру TCCR0)
; ===================
; подблок конфигурации счетных регистров и маркера
ldi mark240, 240 ; начальное значение маркера
ldi counter, 5 ; начальное значение счетчика количества равенств маркера со значением регистра таймера
ldi speed, 5 ; начальное значение времени задержки
; ===================
; ================
; Основное тело программы
Start:
sbic PinB, 1 ; кнопка уменьшения скорости PB1 нажата?
rjmp UpTest ; если кнопка не нажата, перейти к секции проверки состояния кнопки увеличения скорости UpTest
inc speed ; инкрементируем регистр speed (для замедления)
cpi speed, 11 ; сравниваем, задержка не должна быть более 1 сек. (1 единица = 0.1 сек, при частоте 2.4576 МГц)
brne ReleaseDown ; если нет, то перейти
dec speed ; если да, то декриментируем регистр (speed = 10, это максимально)
ReleaseDown:
sbis PinB, 1 ; кнопка уменьшения скорости PB1 нажата?
rjmp ReleaseDown ; если да, то оставаться в цикле
UpTest:
sbic PinB, 2 ; кнопка увеличения скорости PB2 нажата?
rjmp Timer ; если нет, то перейти
dec speed ; если да, декриминируем speed (для ускорения)
brne ReleaseUp ; если не равно 0, то перейти
inc speed ; если да, то инкриментируем регистр (speed = 0.1, это минимально)
ReleaseUp:
sbis PinB, 2 ; кнопка увеличения скорости PB1 нажата?
rjmp ReleaseUp ; если да, то оставаться в цикле
Timer:
in temp, TCNT0 ; загрузить содержимое регистра таймера в temp
cp temp, mark240 ; сравниваем с маркером
brne Start ; если не равны, возвращаемся к Start
subi mark240, -240 ; отнимает -240 от маркера (т.к. число "-240" отрицательное, получается, что мы ПРИБАВЛЯЕМ его к маркеру)
dec counter ; декриминируем значение регистра (счетчика)
brne Start ; если не равно 0, то перейти к Start
mov counter, speed ; перенести значения регистров
in temp, PortD ; считать содержимое прота В в регистр temp
lsl temp ; логический сдвиг значения регистра влево
brcc PC + 2 ; проверяем флаг С и пропускаем команду, если он сброшен
ldi temp, 0b00000001 ; сбрасываем в исходное состояние
out PortD, temp ; вывести содержимое регистра, т.е. включить светодиод
rjmp Start ; зациклить основной цикл
; ================
Вс июн 10, 2012 21:07:52
Вс июн 10, 2012 21:12:19
1 - выкинуть эту книжку.Vova777 писал(а):Программа не моя, взята из книжки.
Вс июн 10, 2012 21:16:24
...
rjmp Init
...
Вс июн 10, 2012 21:24:59
....смотря что считать "нормальным".....Vova777 писал(а):.....что тут не так?
Вс июн 10, 2012 21:27:29
ChipKiller писал(а):....смотря что считать "нормальным".....Vova777 писал(а):.....что тут не так?
приведенная программа пишется на Си за 3 минуты - причем без ошибок ....
Вс июн 10, 2012 21:29:00
Вс июн 10, 2012 21:38:57
... в данном случае к сожалениюVova777 писал(а):... а это к сожалению (или к счастью) ассемблер...
Вс июн 10, 2012 21:40:21
Вс июн 10, 2012 21:42:19
ChipKiller писал(а):... в данном случае к сожалениюVova777 писал(а):... а это к сожалению (или к счастью) ассемблер...
1 Стек инициализируется криво.....
2 Макрос outi используется только в 2 строках ?????
3 из-за обилия комментариев, код тяжело читать......
для обучения возьмите на сайте небольшую по размеру и исправную программу и пройдитесь по ней отладчиком - толку будет больше
Вс июн 10, 2012 21:53:47
;вместо
ser temp ; заполнить регистр temp (пилотное число порта D: 0b11111111)
out DDRD, temp
....
;можно записать
outi DDRD,0xFF ; 0b11111111=0xFF
Вс июн 10, 2012 21:59:05
Вс июн 10, 2012 22:01:18
ChipKiller писал(а):помочь можно, если понятно, что нужно получить ........
PS. смысл макроса outi - вместо двух строк - писать 1
- Код:
;вместо
ser temp ; заполнить регистр temp (пилотное число порта D: 0b11111111)
out DDRD, temp
....
;можно записать
outi DDRD,0xFF ; 0b11111111=0xFF
Вс июн 10, 2012 22:06:49
... скорее всего RESET висит в воздухе - подтяните его к + питания через резистор 10КОм. Если не трогали FUSE-bit, то кварц по-барабану - по умолчанию МК работает от встроенного генератора .....Почему с подключенным программатором к компу и к плате схема работает нормально?
Вс июн 10, 2012 22:10:24
ChipKiller писал(а):... скорее всего RESET висит в воздухе - подтяните его к + питания через резистор 10КОм. Если не трогали FUSE-bit, то кварц по-барабану - по умолчанию МК работает от встроенного генератора .....Почему с подключенным программатором к компу и к плате схема работает нормально?
Вс июн 10, 2012 22:42:50
Пн июн 11, 2012 10:24:17
; ================
.device ATmega8
.nolist
.include "C:\Program Files\Atmel\AVR Studio 5.0\avrassembler\include\m8def.inc"
.list
; ================
; ===============
; макрос
.macro outi
ldi r16,@1
.if(@0 > 0x3F)
sts @0,r16
.else
out @0,r16
.endif
.endm
; ================
; ================
; Объявления
.def temp = r16
.def mark240 = r17
.def counter = r18
.def speed = r19
; ================
; ================
; Начало программы
.cseg
.org 0
; ================
; Инициализация стека (в AVR Studio 5 инициализируется по умолчанию)
outi SPL, low(RAMEND) ; инициализация стека через макрос
outi SPH, high(RAMEND)
; ================
; ================
; Блок инициализации
Init:
ser temp
out DDRD, temp
ldi temp, 0b00000111 ; ЗДЕСЬ Я ИНВЕРТИРОВАЛ БИТЫ ЧИСЛА !!!
out DDRB, temp ; перевести биты порта на ввод (не используются), бит 0, 1, 2 - на вывод
ldi temp, 0b00000001
out PortD, temp
ldi temp, 0b00000111 ; порт PD0,PD1,PD2 - подтяжка, остальные не используются
out PortB, temp ; отключить подтягивающие резисторы порта B, кроме бита 0, 1, 2 (здесь две кнопки)
; ===================
; подблок конфигурации таймера
ldi temp, 0b00000101
out TCCR0, temp
; ===================
; подблок конфигурации счетных регистров и маркера
ldi mark240, 240
ldi counter, 5
ldi speed, 5
; ===================
; ================
; Основное тело программы
Start:
sbic PinB, 1
rjmp UpTest
inc speed
cpi speed, 11
brne ReleaseDown
dec speed
ReleaseDown:
sbis PinB, 1
rjmp ReleaseDown
UpTest:
sbic PinB, 2
rjmp Timer
dec speed
brne ReleaseUp
inc speed
ReleaseUp:
sbis PinB, 2
rjmp ReleaseUp
Timer:
in temp, TCNT0
cp temp, mark240
brne Start
subi mark240, -240
dec counter
brne Start
mov counter, speed
in temp, PortD
lsl temp
brcc PC + 2
ldi temp, 0b00000001
out PortD, temp
rjmp Start
; ================