Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Тема закрыта

ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 20:25:42

Написал программу "Бегущая дорожка", там управляется скорость дорожки двумя кнопками. Программа не моя, взята из книжки.
Пока программатор подключен к компу и схеме, все работает как надо, скорость регулируется, циклы четкие, стабильные.

Когда я пробую без программатора
, то начинается полная каша: скорость не регулируется, циклы не стабильны, похоже на то, что в какой то момент времени, абсолютно не предсказуемый, он останавливается не надолго, потом продолжается.
Еще очень интересное явление: когда подносишь палец к кнопкам, даже не касаясь ни кнопок, ни стола, цикл останавливается, убираю палец подальше - продолжается :shock: . Легкое касание пальцем кварца тоже отражается на светодиодах :? .
Прежде чем отключать программатор, само собой, сначала я отключаю питание. Но я пробовал по-разному, нет результата.
Прошу вас, помогите. :dont_know:

Микроконтроллер ATmega8L-8PU, кварц - 4МГц.
Программа написана в AVR Studio 5, компилируется без ошибок.
Симулировал в Proteus, все работает без ошибок.
Прошивал через PonyProg, прошивается без ошибок.
С другими программами все нормально проходит.

Тут мой программатор.
Не знаю, что делать... :cry:
Код:
; Автор:  ХХХ                            *
; Дата:  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            ; зациклить основной цикл
; ================
Последний раз редактировалось Vova777 Вс июн 10, 2012 22:04:24, всего редактировалось 1 раз.

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:07:52

может все дело в ножке GND программатора?

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:12:19

Vova777 писал(а):Программа не моя, взята из книжки.
1 - выкинуть эту книжку.
2 - стек в вашей программе не инициализируется

PS. Чтобы не лепить на ровном месте кучу ошибок - рекомендую начать изучение программирования с CVAVR. В сети доступна книжка Лебедева "CodeVision AVR пособие для начинающих" ИМХО лучшее для новичка. В качестве справочника можно использовать книги Лебедева "Микроконтроллеры AVR ....."

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:16:24

со стеком я понял, это из-за инструкции:
Код:
...
rjmp Init
...

Я ее убирал, не помогало. Книжка нормальная, это я наверное, во всем виноват :facepalm: . Макрос и инициализацию стека я сам дописал, потому что без этого вообще ничего не шло. Да и так смотрю не особо помогает...
Помогите разобраться с этой программой, что тут не так?

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:24:59

Vova777 писал(а):.....что тут не так?
....смотря что считать "нормальным".....
приведенная программа пишется на Си за 3 минуты - причем без ошибок ....

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:27:29

ChipKiller писал(а):
Vova777 писал(а):.....что тут не так?
....смотря что считать "нормальным".....
приведенная программа пишется на Си за 3 минуты - причем без ошибок ....

а это к сожалению (или к счастью) ассемблер...
а я кстати, неплохо могу на Delphi писать.

Но я хочу знать ассемблер. Помогите разобраться, где там в коде ошибка?

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:29:00

Почему когда программатор подключен к компу она работает нормально?

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:38:57

Vova777 писал(а):... а это к сожалению (или к счастью) ассемблер...
... в данном случае к сожалению

1 Стек инициализируется криво.....
2 Макрос outi используется только в 2 строках ?????
3 из-за обилия комментариев, код тяжело читать......

для обучения возьмите на сайте небольшую по размеру и исправную программу и пройдитесь по ней отладчиком - толку будет больше

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:40:21

А может дело не в программе?

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:42:19

ChipKiller писал(а):
Vova777 писал(а):... а это к сожалению (или к счастью) ассемблер...
... в данном случае к сожалению

1 Стек инициализируется криво.....
2 Макрос outi используется только в 2 строках ?????
3 из-за обилия комментариев, код тяжело читать......

для обучения возьмите на сайте небольшую по размеру и исправную программу и пройдитесь по ней отладчиком - толку будет больше

мне пока сложно с этим, может скажете как надо?
макрос - да, только в двух строках..

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:53:47

помочь можно, если понятно, что нужно получить ........

PS. смысл макроса outi - вместо двух строк - писать 1

Код:
;вместо
ser temp              ; заполнить регистр temp (пилотное число порта D: 0b11111111)
out DDRD, temp
....
;можно записать
outi DDRD,0xFF ; 0b11111111=0xFF
 

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 21:59:05

Видимо дело не в программе :dont_know: . Почему с подключенным программатором к компу и к плате схема работает нормально? легкое касание пальцем кварца также не дает никакого результата. Когда отключаю программатор от компа все-это начинается. Замечу, что другие программы, тоже "бегущие огни", например, но без управления, работает нормально с отключенным программатором, а эта почему то не хочет.

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 22:01:18

ChipKiller писал(а):помочь можно, если понятно, что нужно получить ........

PS. смысл макроса outi - вместо двух строк - писать 1

Код:
;вместо
ser temp              ; заполнить регистр temp (пилотное число порта D: 0b11111111)
out DDRD, temp
....
;можно записать
outi DDRD,0xFF ; 0b11111111=0xFF
 

спасибо, я учту это на будущее, я не знал, я думал он только для инициализации стека нужен :facepalm:

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 22:06:49

Почему с подключенным программатором к компу и к плате схема работает нормально?
... скорее всего RESET висит в воздухе - подтяните его к + питания через резистор 10КОм. Если не трогали FUSE-bit, то кварц по-барабану - по умолчанию МК работает от встроенного генератора .....

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 22:10:24

ChipKiller писал(а):
Почему с подключенным программатором к компу и к плате схема работает нормально?
... скорее всего RESET висит в воздухе - подтяните его к + питания через резистор 10КОм. Если не трогали FUSE-bit, то кварц по-барабану - по умолчанию МК работает от встроенного генератора .....

проверил - нет, там у меня все нормально, через 10 КОм подключено.
можете даже схему посмотреть тут.
другая похожая программа работает нормально, но она намного проще, чем эта.

Re: ATmega8L-8PU, не понятная проблема в программе.

Вс июн 10, 2012 22:42:50

Маленькая плата с двумя кнопками управления у меня соединена через разъем и шлейф с платой программатора. Когда я ее отключаю, циклы стабильны. В чем дело то? Там все спаяно нормально, между дорожками и контактами почистил, тем более что МК реагирует на нажатия кнопок, когда она подключена. Может дребезг контактов? Опять же, не объясняет, почему все работает с подключенным программатором к компу. Может два разных шлейфа индуктивно взаимодействуют между собой? Но чему там взаимодействовать то? Там ток маленький и тем более постоянный, провода изолированы. Хотя может для МК этого достаточно :dont_know:

Не понятно ничего, короче.

Re: ATmega8L-8PU, не понятная проблема в программе.

Пн июн 11, 2012 10:24:17

Я нашел причину, все устранил. Объясните, почему теперь когда биты порта кнопок (PortB) стоят на вывод, все работает как надо? Разве на кнопках не нужно делать ввод? Кнопки подключены к порту B, а вторым концом к GND.
Код:
; ================
.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           
; ================


вот фотки этого монстра:
Вложения
DSC00552.JPG
(112.93 KiB) Скачиваний: 1074
DSC00551.JPG
(112.41 KiB) Скачиваний: 956
DSC00550.JPG
(110.07 KiB) Скачиваний: 1023
Тема закрыта