Пока программатор подключен к компу и схеме, все работает как надо, скорость регулируется, циклы четкие, стабильные.
Когда я пробую без программатора, то начинается полная каша: скорость не регулируется, циклы не стабильны, похоже на то, что в какой то момент времени, абсолютно не предсказуемый, он останавливается не надолго, потом продолжается.
Еще очень интересное явление: когда подносишь палец к кнопкам, даже не касаясь ни кнопок, ни стола, цикл останавливается, убираю палец подальше - продолжается
Прежде чем отключать программатор, само собой, сначала я отключаю питание. Но я пробовал по-разному, нет результата.
Прошу вас, помогите.
Микроконтроллер ATmega8L-8PU, кварц - 4МГц.
Программа написана в AVR Studio 5, компилируется без ошибок.
Симулировал в Proteus, все работает без ошибок.
Прошивал через PonyProg, прошивается без ошибок.
С другими программами все нормально проходит.
Тут мой программатор.
Не знаю, что делать...
Код: Выделить всё
; Автор: ХХХ *
; Дата: 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 ; зациклить основной цикл
; ================


