Перейти к содержанию

Не Работают Команды Сравнения


skef

Рекомендуемые сообщения

в схеме на базе ATMega8535 не работают команды сравнения (cpi,brge)

в такой же схеме на базе AT90S8535 все работает идеально

НА ЛЮБОЙ ЭЛЕМЕНТ НАЙДЕТСЯ МОЩНОСТЬ, КОТОРАЯ ЕГО СОЖЖЕТ

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Они то работают, просто Вы скорее всего флаги сбрасываете либо сами, либо в процесс сравнения вламывается прерывание и сбрасывает Ваши флаги. Давайте кусок кода, где все это происходит.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8535def.inc"

rjmp RESET ; Reset Handler

nop;rjmp EXT_INT0 ; IRQ0 Handler

nop;rjmp EXT_INT1 ; IRQ1 Handler

rjmp TIM2_COMP ; Timer2 Compare Handler

nop;rjmp TIM2_OVF ; Timer2 Overflow Handler

nop;rjmp TIM1_CAPT ; Timer1 Capture Handler

rjmp TIM1_COMPA ; Timer1 CompareA Handler

rjmp TIM1_COMPB ; Timer1 CompareB Handler

nop;rjmp TIM1_OVF ; Timer1 Overflow Handler

rjmp TIM0_OVF ; Timer0 Overflow Handler

nop;rjmp SPI_STC; ; SPI Transfer Complete Handler

nop;rjmp UART_RXC ; UART RX Complete Handler

nop;rjmp UART_DRE ; UDR Empty Handler

nop;rjmp UART_TXC ; UART TX Complete Handler

nop;rjmp ADC ; ADC Conversion Complete Interrupt Handler

nop;rjmp EE_RDY ; EEPROM Ready Handler

nop;rjmp ANA_COMP ; Analog Comparator Handler

reset:

ldi r16,255

out ddra,r16

out ddrc,r16

ldi r16,(0<<pb3)+(0<<pb4)+(0<<pb5)

out ddrb,r16

ldi r16,(1<<pb3)+(1<<pb4)+(1<<pb5)

out portb,r16

ldi r16,(1<<pb0)+(1<<pb1)+(1<<pb2)

out ddrb,r16

ldi r16,(1<<pd5)

out ddrd,r16

ldi r16,(1<<com1a0)

out tccr1a,r16

ldi r16,(1<<cs10)+(1<<cs12)

out tccr1b,r16

ldi r16,(1<<ocie1a)+(1<<ocie1b)+(1<<TOIE0)+(1<<ocie2)

out timsk,r16

ldi r16,high(9760)

out ocr1ah,r16

ldi r16,low(9760)

out ocr1al,r16

ldi r16,high(58560)

out ocr1bh,r16

ldi r16,low(58560)

out ocr1bl,r16

ldi r16,(1<<cs20)+(1<<cs21)+(1<<cs22);

out tccr2,r16

ldi ZH,High (table*2)

ldi ZL,Low (table*2)

ldi r16,81

out ocr2,r16

ldi r16,(1<<cs00)+(1<<cs01);

out tccr0,r16

ldi r16, high(RAMEND)

out SPH,r16

ldi r16, low(RAMEND)

out SPL,r16

sei

main:

rjmp main

najato:

ldi r18,0

reti

key1:

in r19, pinb

sbrc r23,0

rjmp key2

ldi r23,1

reti

key2:

in r22,pinb

ldi r23,0

cp r19,r22

breq najato

reti

TIM1_COMPA:

cli

in r16,ocr1ah

cpi r16,0b00100110

breq edge11s

cpi r16,0b00101001

breq edge30s

cpi r16,0b01110010

breq edge31s

cpi r16,0b01110110

breq edge50s

cpi r16,0b10111110

breq edge51s

reti

TIM1_COMPB:

cli

ldi r16,0

out porta,r16

out portc,r16

cpi r18,2

brge led

enter:

rjmp enter

led:

ldi r16,(1<<pb0)+(1<<pb1)+(1<<pb2)

out portb,r16

rjmp enter

edge11s:

inc r18

ldi r16,high(10736)

out ocr1ah,r16

ldi r16,low(10736)

out ocr1al,r16

reti

edge30s:

ldi r16,high(29280)

out ocr1ah,r16

ldi r16,low(29280)

out ocr1al,r16

reti

edge31s:

inc r18

ldi r16,high(30256)

out ocr1ah,r16

ldi r16,low(30256)

out ocr1al,r16

reti

edge50s:

ldi r16,high(48800)

out ocr1ah,r16

ldi r16,low(48800)

out ocr1al,r16

reti

edge51s:

inc r18

ldi r16,high(49776)

out ocr1ah,r16

ldi r16,low(49776)

out ocr1al,r16

reti

TIM0_OVF:

cli

in r19,pinb

sbrc r19,3

rjmp key1

sbrc r19,4

rjmp key1

sbrc r19,5

rjmp key1

reti

TIM2_COMP:

ldi r16,0

out tcnt2,r16

inc r20 ;увеличиваем р20, сравниваем с числом 24

cpi r20,24 ;если равно, уходим на метку load

breq load ;в этой подпрограмме загужается начало таблицы ;разрешение всех прерываний

inc ZL ;увеличение адреса и загрузка

lpm ;числа по этому адресу

mov r16,r0 ;пересылка в РОН r16 и далее в порт А (там сегменты)

out porta,r16

cpi r16,0 ;если 0, загрузить все снова

breq TIM2_COMP

reload:

inc ZL ;увеличение адреса и загрузка

lpm

mov r17,r0 ;пересылка в РОН r16 и далее в порт С (там ячейки)

cpi r17,0 ;если 0, загрузить все снова

breq reload

out portc,r17

reti

load: ;когда все значения в дисплее перебраны

ldi r20,0 ;("змейка2 описала круг), загружается начало

ldi ZH,High (table*2) ;(следующий круг)

ldi ZL,Low (table*2) ;

reti

table:

.db 0b10000000 ;a

.db 0b00000001 ;1

.db 0b10000000 ;a

.db 0b00000010 ;2

.db 0b10000000 ;a

.db 0b00000100 ;3

.db 0b10000000 ;a

.db 0b00001000 ;4

.db 0b01000000 ;b

.db 0b00001000 ;4

.db 0b00100000 ;c

.db 0b00001000 ;4

.db 0b00010000 ;d

.db 0b00001000 ;4

.db 0b00010000 ;d

.db 0b00000100 ;3

.db 0b00010000 ;d

.db 0b00000010 ;2

.db 0b00010000 ;d

.db 0b00000001 ;1

.db 0b00001000 ;e

.db 0b00000001 ;1

.db 0b00000100 ;f

.db 0b00000001 ;1

после каждого cpi и команды brge программа по заданным условиям не ветвится (просто идет дальше)

и еще вопросик... отличаются ли программно AT90S8535 и ATmega8535?

НА ЛЮБОЙ ЭЛЕМЕНТ НАЙДЕТСЯ МОЩНОСТЬ, КОТОРАЯ ЕГО СОЖЖЕТ

Ссылка на комментарий
Поделиться на другие сайты

Особенности хранения литиевых аккумуляторов и батареек

Потеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Эх, skef, skef. Я тебя в прошлой ветке уму-разуму пытался научить, а ты теперь здесь "вылез" с еще большей глупостью. <_< Судя по всему, так и не попытался понять мои объяснения. :angry::lol:

Еще больше наблудил RETI.

Смотри сюда. Уходя в прерывание требуется сохранять ВСЕ используемые на данный момент регистры и, самое главное, регистр SREG, чтобы при выходе восстановить не только счетчик команд, но и все используемые регистры и, самое главное, регистр SREG, чтобы программа встала, отряхнулась и, как ни в чем не бывало (касаемо прерывания), продолжила свои действия. Ты, при уходе в прерывание, не сохраняешь регистр SREG, в котором хранятся так необходимые тебе флаги для ветвления программы и не восстанавливаешь его при выходе. Ведь у тебя столько различных выходов из прерывания и вариантов SREG на выходе (попытка по-своему справиться со стеком, хотя я тебе давал рекомендации), что все нюансы учесть невозможно, даже отладчик ставит биты в XXXX, потому что не может сообразить, что уж там должно быть. Поэтому возвращаясь из прерывания, SREG "выглядит так, словно он носился на мотоцикле без шлема - весь растрепанный и взъерошенный" :lol: , потому что он столько условий и сравнений перенес за прерывание - жуть. И еще, следи за индексным регистром Z, не позволяй ему расти до бесконечности, чтобы не вывалиться за пределы массива, а это происходит. И давай, "причеши" алгоритмы и тексты прерываний по-человечески. Один вход - один выход. Все остальное - внутри.

И еще вопрос, что это за ловушка - после метки Led переход на зацикленную на себя enter?

Изменено пользователем Геннадий
Ссылка на комментарий
Поделиться на другие сайты

Секреты депассивации литиевых батареек FANSO EVE Energy

Самыми лучшими параметрами по энергоемкости, сроку хранения, температурному диапазону и номинальному напряжению обладают батарейки литий-тионилхлоридной электрохимической системы. Но при длительном хранении происходит процесс пассивации. Разберем в чем плюсы и минусы, как можно ее избежать или уменьшить последствия и как проводить депассивацию батареек на примере продукции и рекомендаций компании FANSO EVE Energy. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Led переход на зацикленную на себя enter - далее от программы ничего не требуется, но т.к.счетчик команд останавливать нельзя, я запретил прерывания и зациклил в этои enter.

А регистр Z не должен расти... после перебора всех значений в таблице, в него загружается начало таблицы.

насчет поведения регистров в прерывании...

я что, должен писать:

TIM2_COMP:

push sreg

push r17

push r18

..............

push r31

==========

reti

а потом что?

pop sreg

pop r17

pop r18

..............

pop r31

НА ЛЮБОЙ ЭЛЕМЕНТ НАЙДЕТСЯ МОЩНОСТЬ, КОТОРАЯ ЕГО СОЖЖЕТ

Ссылка на комментарий
Поделиться на другие сайты

SREG сохраняется в РОН, командами push и pop "его не возьмешь". Надо так:

in R6(любой свободный),SREG

=======================

out SREG,R6

Номер регистра на твое усмотрение.

И внимательнее с порядком работы со стеком. Первый пришел - последний ушел.

И все-таки, убери все reti в подпрограммах. Возвращайся из них в тело обработчика прерывания. Иначе логику программы сложно отследить, да и при стольких выходах нужно столько же восстановлений (хрен знает из какого места в данный момент программа выйдет из прерывания). Команда ret работает при вызове rcall (call). В твоем случае (переходы по условию) подпрограммы нужно заканчивать безусловным переходом - rjmp.

Ссылка на комментарий
Поделиться на другие сайты

.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8535def.inc"

rjmp RESET ; Reset Handler

nop;rjmp EXT_INT0 ; IRQ0 Handler

nop;rjmp EXT_INT1 ; IRQ1 Handler

rjmp TIM2_COMP ; Timer2 Compare Handler

nop;rjmp TIM2_OVF ; Timer2 Overflow Handler

nop;rjmp TIM1_CAPT ; Timer1 Capture Handler

rjmp TIM1_COMPA ; Timer1 CompareA Handler

rjmp TIM1_COMPB ; Timer1 CompareB Handler

nop;rjmp TIM1_OVF ; Timer1 Overflow Handler

rjmp TIM0_OVF ; Timer0 Overflow Handler

nop;rjmp SPI_STC; ; SPI Transfer Complete Handler

nop;rjmp UART_RXC ; UART RX Complete Handler

nop;rjmp UART_DRE ; UDR Empty Handler

nop;rjmp UART_TXC ; UART TX Complete Handler

nop;rjmp ADC ; ADC Conversion Complete Interrupt Handler

nop;rjmp EE_RDY ; EEPROM Ready Handler

nop;rjmp ANA_COMP ; Analog Comparator Handler

reset:

ldi r16,255

out ddra,r16

out ddrc,r16

ldi r16,(0<<pb3)+(0<<pb4)+(0<<pb5)

out ddrb,r16

ldi r16,(1<<pb3)+(1<<pb4)+(1<<pb5)

out portb,r16

ldi r16,(1<<pb0)+(1<<pb1)+(1<<pb2)

out ddrb,r16

ldi r16,(1<<pd5)

out ddrd,r16

ldi r16,(1<<com1a0)

out tccr1a,r16

ldi r16,(1<<cs10)+(1<<cs12)

out tccr1b,r16

ldi r16,(1<<ocie1a)+(1<<ocie1b)+(1<<TOIE0)+(1<<ocie2)

out timsk,r16

ldi r16,high(9760)

out ocr1ah,r16

ldi r16,low(9760)

out ocr1al,r16

ldi r16,high(58560)

out ocr1bh,r16

ldi r16,low(58560)

out ocr1bl,r16

ldi r16,(1<<cs20)+(1<<cs21)+(1<<cs22);

out tccr2,r16

ldi ZH,High (table*2)

ldi ZL,Low (table*2)

ldi r16,81

out ocr2,r16

ldi r16,(1<<cs00)+(1<<cs01);

out tccr0,r16

ldi r16, high(RAMEND)

out SPH,r16

ldi r16, low(RAMEND)

out SPL,r16

sei

main:

out sreg,r10

circle:

rjmp circle

rjmp main

TIM1_COMPA:

cli

in r10,sreg

in r16,ocr1ah

cpi r16,0b00100110

breq edge11s

cpi r16,0b00101001

breq edge30s

cpi r16,0b01110010

breq edge31s

cpi r16,0b01110110

breq edge50s

cpi r16,0b10111110

breq edge51s

ret_T1_COMPA

reti

TIM1_COMPB:

cli

ldi r16,0

out porta,r16

out portc,r16

cpi r18,2

brge led

enter:

rjmp enter

led:

ldi r16,(1<<pb0)+(1<<pb1)+(1<<pb2)

out portb,r16

rjmp enter

edge11s:

inc r18

ldi r16,high(10736)

out ocr1ah,r16

ldi r16,low(10736)

out ocr1al,r16

rjmp ret_T1_COMPA

edge30s:

ldi r16,high(29280)

out ocr1ah,r16

ldi r16,low(29280)

out ocr1al,r16

rjmp ret_T1_COMPA

edge31s:

inc r18

ldi r16,high(30256)

out ocr1ah,r16

ldi r16,low(30256)

out ocr1al,r16

rjmp ret_T1_COMPA

edge50s:

ldi r16,high(48800)

out ocr1ah,r16

ldi r16,low(48800)

out ocr1al,r16

rjmp ret_T1_COMPA

edge51s:

inc r18

ldi r16,high(49776)

out ocr1ah,r16

ldi r16,low(49776)

out ocr1al,r16

rjmp ret_T1_COMPA:

TIM0_OVF:

cli

in r10,sreg

in r19,pinb

sbrc r19,3

rjmp key1

sbrc r19,4

rjmp key1

sbrc r19,5

rjmp key1

ret_T0_OVF:

reti

key1:

in r19, pinb

sbrc r23,0

rjmp key2

ldi r23,1

rjmp ret_T0_OVF

key2:

in r22,pinb

ldi r23,0

cp r19,r22

breq najato

rjmp ret_T0_OVF

najato:

ldi r18,0

rjmp ret_T0_OVF

TIM2_COMP:

in r10,sreg

ldi r16,0

out tcnt2,r16

inc r20 ;увеличиваем р20, сравниваем с числом 24

cpi r20,24 ;если равно, уходим на метку load

breq load ;в этой подпрограмме загужается начало таблицы ;разрешение всех прерываний

inc ZL ;увеличение адреса и загрузка

lpm ;числа по этому адресу

mov r16,r0 ;пересылка в РОН r16 и далее в порт А (там сегменты)

out porta,r16

cpi r16,0 ;если 0, загрузить все снова

breq TIM2_COMP

ret_T2_comp:

reti

reload:

inc ZL ;увеличение адреса и загрузка

lpm

mov r17,r0 ;пересылка в РОН r16 и далее в порт С (там ячейки)

cpi r17,0 ;если 0, загрузить все снова

breq reload

out portc,r17

rjmp ret_T2_comp

load: ;когда все значения в дисплее перебраны

ldi r20,0 ;("змейка2 описала круг), загружается начало

ldi ZH,High (table*2) ;(следующий круг)

ldi ZL,Low (table*2) ;

rjmp ret_T2_comp

table:

.db 0b10000000 ;a

.db 0b00000001 ;1

.db 0b10000000 ;a

.db 0b00000010 ;2

.db 0b10000000 ;a

.db 0b00000100 ;3

.db 0b10000000 ;a

.db 0b00001000 ;4

.db 0b01000000 ;b

.db 0b00001000 ;4

.db 0b00100000 ;c

.db 0b00001000 ;4

.db 0b00010000 ;d

.db 0b00001000 ;4

.db 0b00010000 ;d

.db 0b00000100 ;3

.db 0b00010000 ;d

.db 0b00000010 ;2

.db 0b00010000 ;d

.db 0b00000001 ;1

.db 0b00001000 ;e

.db 0b00000001 ;1

.db 0b00000100 ;f

.db 0b00000001 ;1

вот... вроде все так.

и все-таки насчет сравнения - а разве флаги не обновляются по результатам операции?

так... стоп.

main:

out sreg,r10

circle:

rjmp circle

rjmp main

вот это явно ошибка.

когда надо СОХРАНЯТЬ и когда ВОССТАНАВЛИВАТЬ sreg???

Изменено пользователем skef

НА ЛЮБОЙ ЭЛЕМЕНТ НАЙДЕТСЯ МОЩНОСТЬ, КОТОРАЯ ЕГО СОЖЖЕТ

Ссылка на комментарий
Поделиться на другие сайты

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

В чем заключается перестройка. Переложить все основные функции на main. В прерываниях только поднимать флаги. Для этого выбери любой свободный регистр для флагов. Можешь взять для каждого флага отдельный регистр. Благо у тебя их много свободных остается. Далее, в прерывании поднимаешь бит регистра флагов и сразу выходишь. В main делаешь проверку битов флагов прерываний и если какой-нибудь поднят (установлен в 1) вызываешь соответствующую процедуру обработки, при выходе из которой в конце опустишь флаг, чтобы многократно не повторяться. Попробуй так написать программу. Глядишь и проблемы пропадут. Если что - обращайся помогу.

Ссылка на комментарий
Поделиться на другие сайты

najato:
ldi r18,0
rjmp ret_T0_OVF

Кто это вас так учил писать????? Если это подпрограма то выходить из неё надо командой RET. А если прерывание то RETI. И вызывать подпрограму лдя прерывания из основной програмы вручную можно но делают это очень редко в редких случаях... Научитесь использовать команду вызова подпрограмы а не скакать на метки!!! И если вы выскочили из обработки прерывания командой RJMP то как будете возвращаться назад??? Учиите АСЕМБЛЕР лучше!!!

Ссылка на комментарий
Поделиться на другие сайты

 wowa, это результат моих разъяснений. Результат коверканный, но имеющий право на жизнь. Дело в том, что skef устраивал всю обработку в прерывании, где проводил много ветвлений условными переходами на метки, расположенные ВНЕ тела обработчика прерывания, в которых были еще ветвления. И вот в результате этих условных переходов у него получалось несколько выходов из одного прерывания. Он конечно старался выходить через RETI (куча меток заканчивалась именно так). Согласись, такой вариант еще более нелеп. У него переполнялся стек и были еще некоторые глюки (указанные даже в названии). Вот я ему о попытался объяснить и не только в этой теме (был еще дубль, с другим названием). Даже najato является "целью" условного перехода из прерывания, а в таком случае возврат возможен только безусловным переходом обратно (в тело прерывания, а точнее в его конец), хотя бы для того, чтобы нормально завершить прерывание. Переформировать код в последовательный и удобочитаемый skef не захотел.

Кстати, после компилятора Си таких скачков (с метки на метку) просто тьма. И приходится поломать голову, чтобы разобраться в логике кода. 

Изменено пользователем Геннадий
Ссылка на комментарий
Поделиться на другие сайты

всем спасибо... замечания приняты и будут учтены при следующих работах.

а эту работу сдали.

НА ЛЮБОЙ ЭЛЕМЕНТ НАЙДЕТСЯ МОЩНОСТЬ, КОТОРАЯ ЕГО СОЖЖЕТ

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...