anton2488 Опубликовано 30 апреля, 2015 Поделиться Опубликовано 30 апреля, 2015 (изменено) UPD Прошу прощения, нашлась ошибка, производился декремент постоянного регистра. Изучаю авр и столкнулся с непреодолимой для меня проблемой. Простая программа АЦП>програмный делитель>шим. Регистр, в котором постоянно хранится число сдвигов для деления всё время сбрасывается в 0, при этом при этом установленный бит в порте не сбрасывается(сделал для проверки). Не важно, записан ли регистр в РЕСЕТ или в прерывании через кнопку, всё равно происходит сброс. Как такое может быть? Это происходит при моделировании в Протеусе, в симуляторе сброса нет, правда я не знаю как там вызывать прерывания, просто переставляю курсор. Сторожевой таймер вроде отключён и програмно и в протеусе. Что я делаю не так? Помогите новичку. .def temp1=r16 .def temp2=r17 .def div1=r18 .def div2=r19 .cseg .org 0x0000 rjmp RESET reti//1 rjmp vol//2 reti//3 reti//4 reti//5 reti//6 reti//7 rjmp adcpwm reti//9 reti//10 reti//11 reti//12 reti//13 reti//14 reti//15 RESET: ldi r16, (0<<WDRF)// остановка ст. таймера. out MCUSR, r16 ; Write logical one to WDCE and WDE ; Keep old prescaler setting to prevent unintentional Watchdog Reset in r16, WDTCR ori r16, (1<<WDCE)|(1<<WDE) out WDTCR, r16 ; Turn off WDT ldi r16, (0<<WDE) out WDTCR, r16 ldi temp1,0b00000011 out ddrb,temp1 ldi temp1,0b00011000 out portb,temp1 ldi temp1,0b11000011 out tccr0a,temp1 ldi temp1,0b00000001 out tccr0b,temp1 ldi temp1,0b00100001//УСТАНОВЛЕН СДВИГ ВЛЕВО out admux,temp1 ldi temp1,0b11101111 out adcsra,temp1 ldi temp1,0b00000000 out adcsrb,temp1 ldi temp1,0b00000000 out mcucr,temp1 ldi temp1,0b00100000 out gimsk,temp1 ldi temp1,0b00011000 out pcmsk,temp1 ldi div1,3// запись коэф деления в постоянный регистр sei start: rjmp start adcpwm:// прерывание АЦП--------------------------------------------- in temp1,adcl in temp2,adch mov div2,div1 // запись коэф. деления из постоянного рег во временный tst div2//деление breq zap l1: lsr temp2 ror temp1 dec div1 brne l1 zap://запись в шим out ocr0a,temp2 out ocr0b,temp2 reti VOL://прерывание кнопки---------------------------------------------------- ldi div1,3// запись коэф деления в постоянный регистр sbi portb,1//индикатор прерывания reti Изменено 30 апреля, 2015 пользователем anton2488 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
COKPOWEHEU Опубликовано 30 апреля, 2015 Поделиться Опубликовано 30 апреля, 2015 А где инициализация стека? Регистры SPH:SPL не иницилизированы, откуда возникает переполнение стека и сброс контроллера. 0 Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз. Часть моих наработок. Ссылка на комментарий Поделиться на другие сайты Поделиться
20% скидка на весь каталог электронных компонентов в ТМ Электроникс!Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!Перейти на страницу акции Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
Геннадий Опубликовано 30 апреля, 2015 Поделиться Опубликовано 30 апреля, 2015 (изменено) По конкретнее можно? Какой регистр "постоянно сбрасывается"? div1 в прерывании? К замечаниям COKPOWENEU добавлю, что заходя в прерывания нужно сохранять в стеке, используемые регистры, а выходя из прерывания - восстанавливать. Не забывайте и про регистр состояния SREG. Иначе логика хода программы после выполнения прерывания может поменяться. Это по организации и "хорошему тону". А по существу, Вы используете регистр div1. Заходя в прерывание, копируете его и проверяете на нулевое значение его копию div2, а уменьшаете (декрементируете) почему-то div1. Естественно, после трех прерываний Ваш регистр будет иметь значение 0. Изменено 30 апреля, 2015 пользователем Геннадий 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
anton2488 Опубликовано 30 апреля, 2015 Автор Поделиться Опубликовано 30 апреля, 2015 А где инициализация стека? Регистры SPH:SPL не иницилизированы, откуда возникает переполнение стека и сброс контроллера. в авр студио 5 и 6 не нужно инициализировать, всё само. По конкретнее можно? Какой регистр "постоянно сбрасывается"? div1 в прерывании? К замечаниям COKPOWENEU добавлю, что заходя в прерывания нужно сохранять в стеке, используемые регистры, а выходя из прерывания - восстанавливать. Не забывайте и про регистр состояния SREG. Иначе логика хода программы после выполнения прерывания может поменяться. Это по организации и "хорошему тону". А по существу, Вы используете регистр div1. Заходя в прерывание, копируете его и проверяете на нулевое значение его копию div2, а уменьшаете (декрементируете) почему-то div1. Естественно, после трех прерываний Ваш регистр будет иметь значение 0. всё верно, я перепутал и декременировал регистр div1 где должно постоянно хранится значение, в этом и была проблема. Про сохранение регистров не слышал. Чем это вызвано? Каким образом прерывание может изменить значение регистров, если с ними не работают в прерывании. Но идея хороша, можно сэкономить регистр. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
COKPOWEHEU Опубликовано 30 апреля, 2015 Поделиться Опубликовано 30 апреля, 2015 Точно "само"? Вообще-то это было бы неправильное поведение. Покажите скомпилированный hex-файл. Насчет прерываний - речь не о конкретном а об общем случае. А там возможны хотя бы операции сравнение, инкремента/декремента и прочие, влияющие на SREG. Представьте если такое прерывание возникнет между cp и breq. То, что шанс возникновения такой ошибки мал только усугубляет ситуацию: труднее найти ошибку. Ну и прерывание часто использует те же регистры, что и основная программа, а чтобы они друг другу не мешали, при входе и выходе в прерывание делают пары push/pop. Плюс не надо запоминать какое прерывание с какими регистрами работает. Например, в прерывании надо инкременировать содержимое ячейки 0x0100 ОЗУ. ANY_INT: push r16 ;сохраняем r16 in r16,SREG push r16 ;сохраняем SREG lds r16,0x0100 ;какие-то полезные действия inc r16 sts 0x0100,r16 pop r16 ;восстанавливаем SREG out SREG,r16 pop r16 ;восстанавливаем r16 reti 0 Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз. Часть моих наработок. Ссылка на комментарий Поделиться на другие сайты Поделиться
Геннадий Опубликовано 1 мая, 2015 Поделиться Опубликовано 1 мая, 2015 COKPOWEHEU все уже объяснил. В обработчике прерывания нужно сохранять/восстанавливать только используемые в этом прерывании регистры и SREG, чтобы при возвращении из прерывания все эти регистры содержали те же значения, что и при входе в прерывание. Тогда основная программа будет выполняться по принципу "как ни в чем не бывало". Это гарантирует логику основного цикла без изменений (последствий прерываний). А чтобы не забивать стек излишними сохранениями я, например, сохраняю SREG в свободном регистре младшей группы R3-R15, т.к. они редко используются. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
anton2488 Опубликовано 1 мая, 2015 Автор Поделиться Опубликовано 1 мая, 2015 (изменено) Точно "само"? Вообще-то это было бы неправильное поведение. Покажите скомпилированный hex-файл. Насчет прерываний - речь не о конкретном а об общем случае. А там возможны хотя бы операции сравнение, инкремента/декремента и прочие, влияющие на SREG. Представьте если такое прерывание возникнет между cp и breq. То, что шанс возникновения такой ошибки мал только усугубляет ситуацию: труднее найти ошибку. Ну и прерывание часто использует те же регистры, что и основная программа, а чтобы они друг другу не мешали, при входе и выходе в прерывание делают пары push/pop. Плюс не надо запоминать какое прерывание с какими регистрами работает. Например, в прерывании надо инкременировать содержимое ячейки 0x0100 ОЗУ. Спасибо, по sreg дельное замечание, могли бы возникнуть проблемы. контроллер тини45 :020000020000FC :100000000FC0189518951895189518951895189566 :1000100035C0189518951895189518951895189530 :1000200000E004BF01B5086101BD00E001BD03E0CF :1000300007BB08E108BB03E80ABD01E003BF01E21A :1000400007B90FEE06B900E003B928E07894B39B36 :100050000CC0B49B01C0FBCFB49BFECF2830B9F3DA :1000600040FD01C023954395F2CFB39BFECF2223E1 :1000700071F340FF01C02A954A95E9CF04B115B14B :10008000322F332361F0169507953A95E1F740FF3B :1000900006C0612F502F66955795050F161F19BD85 :0400A00018BD1895DA :00000001FF Сейчас возникла друга проблема. Пытаюсь перенести программу на мегу48 ldi temp1,0b01100000 out admux,temp1 пишет ошибку Error 1 Operand 1 out of range: 0x7c каким образом вносить данные в эти регистры если in и out не работают с этими адресами? тут случайно банк памяти не нужно переключать? А, нашёл <a name="#top">lds r2, $FF00 ; Загрузить в r2 содержимое SRAM по адресу $FF00 add r2, r1 ; Сложить r1 с r2 sts $FF00, r2 ; Записать обратно Изменено 1 мая, 2015 пользователем anton2488 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Геннадий Опубликовано 1 мая, 2015 Поделиться Опубликовано 1 мая, 2015 Пишите sts admux,temp1. Она более "дальнобойная". 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
anton2488 Опубликовано 1 мая, 2015 Автор Поделиться Опубликовано 1 мая, 2015 Пишите sts admux,temp1. Она более "дальнобойная". А есть другие команды, которыми можно записать? Я сейчас не могу записать единицу в 6 бит, который запускает цап. ldi temp1,0b11101111 sts adcsra,temp1 а записывается 0b10101111 В чем может быть причина, и как записать бит? В тини всё нормально записывается. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
COKPOWEHEU Опубликовано 1 мая, 2015 Поделиться Опубликовано 1 мая, 2015 :020000020000FC :100000000FC0189518951895189518951895189566 :1000100035C0189518951895189518951895189530 :1000200000E004BF01B5086101BD00E001BD03E0CF :1000300007BB08E108BB03E80ABD01E003BF01E21A :1000400007B90FEE06B900E003B928E07894B39B36 :100050000CC0B49B01C0FBCFB49BFECF2830B9F3DA :1000600040FD01C023954395F2CFB39BFECF2223E1 :1000700071F340FF01C02A954A95E9CF04B115B14B :10008000322F332361F0169507953A95E1F740FF3B :1000900006C0612F502F66955795050F161F19BD85 :0400A00018BD1895DA :00000001FF Как и следовало ожидать, записи в SPH:SPL нет. Должно быть что-то вроде 0FE5 0DBF 01E0 0EBF (ldi r16,5F | out 0x3D,r16 | ldi r16,0x01 | out 0x3E,r16 где 0x3D=SPL, 0x3E=SPH, 0x015F=RAMEND). То есть стек все-таки не инициализирован. Сейчас возникла друга проблема. Пытаюсь перенести программу на мегу48 ldi temp1,0b01100000 out admux,temp1 пишет ошибку Error 1 Operand 1 out of range: 0x7c Рекомендую такой код .macro uout .if @0<0x40 out @0,@1 .else sts @0,@1 .endif .endm .macro uin .if @1<0x40 in @0,@1 .else lds @0,@1 .endif .endm Использование вместо обычных in / out ldi temp1,0b01100000 uout admux,temp1 0 Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз. Часть моих наработок. Ссылка на комментарий Поделиться на другие сайты Поделиться
anton2488 Опубликовано 1 мая, 2015 Автор Поделиться Опубликовано 1 мая, 2015 А где смотреть нужно? Вот я добавил инициализацию стека. Но указатель стека и раньше и сейчас указывает на то же значение 0x015F :020000020000FC :100000000FC0189518951895189518951895189566 :1000100039C018951895189518951895189518952C :1000200001E00EBF0FE50DBF00E004BF01B50861A0 :1000300001BD00E001BD03E007BB08E108BB03E828 :100040000ABD01E003BF01E207B90FEE06B900E007 :1000500003B928E07894B39B0CC0B49B01C0FBCFDC :10006000B49BFECF2830B9F340FD01C023954395E2 :10007000F2CFB39BFECF222371F340FF01C02A953C :100080004A95E9CF04B115B1322F332361F01695AB :1000900007953A95E1F740FF06C0612F502F66950E :0C00A0005795050F161F19BD18BD1895C7 :00000001FF Спасибо, макросы попробую. Для регистров выше 0x40 требуется sts, в даташите указаны какие то адреса в скобках 0x20 (0x40) EEDR что они означают? Не знаете почему не устанавливается бит ADSC запуска ацп в adcsra на меге48? Даже не знаю куда копать, в даташите о особых условиях запуска ничего не нашёл. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Геннадий Опубликовано 1 мая, 2015 Поделиться Опубликовано 1 мая, 2015 Может весь листинг посмотрим? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
anton2488 Опубликовано 1 мая, 2015 Автор Поделиться Опубликовано 1 мая, 2015 (изменено) ATmega48P .def temp1=r16 .def temp2=r17 .cseg .org 0x0000 rjmp RESET reti//1 reti//2 reti//3 reti//4 reti//5 reti//6 reti//7 reti//8 reti//9 reti//10 reti//11 reti//12 reti//13 reti//14 reti//15 reti//16 reti//17 reti//18 reti//19 reti//20 reti//21 rjmp adcpwm reti//23 reti//24 reti//25 reti//26 RESET: ldi r16, high(RAMEND); Main program start out SPH,r16 ; Set Stack Pointer to top of RAM ldi r16, low(RAMEND) out SPL,r16 ldi temp1,0b00000000 out ddrb,temp1 ldi temp1,0b11100000 out ddrd,temp1 ldi temp1,0b00000000 out ddrc,temp1 ldi temp1,0b00000000 out portb,temp1 ldi temp1,0b00000000 out portc,temp1 //timer ldi temp1,0b10100011 out tccr0a,temp1 ldi temp1,0b00000001 out tccr0b,temp1 //adc ldi temp1,0b00100000//УСТАНОВЛЕН СДВИГ ВЛЕВО sts admux,temp1 ldi temp1,0b00000000 sts adcsrb,temp1 ldi temp1,0b10101111//инициализация без запуска цап sts adcsra,temp1 ldi temp1,0b11101111//инициализация с запуском цап sts adcsra,temp1 sei start: rjmp start adcpwm://запись из цап в шим lds temp1,adcl lds temp2,adch sbi portd,7// проверка прерывания out ocr0a,temp2 reti Изменено 1 мая, 2015 пользователем anton2488 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Геннадий Опубликовано 2 мая, 2015 Поделиться Опубликовано 2 мая, 2015 Reti//21 лишняя строка в таблице векторов и таблица длиннее на один вектор. Именно на строке reti//21 должен находиться вектор прерывания по окончанию преобразования. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
anton2488 Опубликовано 2 мая, 2015 Автор Поделиться Опубликовано 2 мая, 2015 (изменено) Reti//21 лишняя строка в таблице векторов и таблица длиннее на один вектор. Именно на строке reti//21 должен находиться вектор прерывания по окончанию преобразования. Помогло! Дурацкая ошибка. Непонятно, почему бит adsc не загорается в симуляторе, из-за этого пошёл не в том направлении. Есть ли возможность в симуляторе эмитировать прерывания по цап, чтобы проверять вектора? Простая установка флагов ничего не даёт. Изменено 2 мая, 2015 пользователем anton2488 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Геннадий Опубликовано 2 мая, 2015 Поделиться Опубликовано 2 мая, 2015 Я Студией не пользуюсь, подсказать по ее симулятору не могу. Увы. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
COKPOWEHEU Опубликовано 2 мая, 2015 Поделиться Опубликовано 2 мая, 2015 По идее должно быть при выставлении ADIF ну и глобального прерывания. 0 Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз. Часть моих наработок. Ссылка на комментарий Поделиться на другие сайты Поделиться
anton2488 Опубликовано 3 мая, 2015 Автор Поделиться Опубликовано 3 мая, 2015 (изменено) Опять какая то странная ситуация возникла(мега48п) clr r16 out EEARH, r16 out EEARL, r16 sbi eecr,0 in div1,eedr Error 1 Undefined symbol: EEARH вот прямо из даташита копировал ; Set up address (r18:r17) in address register out EEARH, r18 out EEARL, r17 ; Start eeprom read by writing EERE sbi EECR,EERE ; Read data from Data Register in r16,EEDR с EEARL всё нормально работает Изменено 3 мая, 2015 пользователем anton2488 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Геннадий Опубликовано 3 мая, 2015 Поделиться Опубликовано 3 мая, 2015 Из какого даташита? У Меги48 какой размер EEPROM? Посмотрите внимательно... Нет у нее EEARH (он ей не нужен). 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
anton2488 Опубликовано 3 мая, 2015 Автор Поделиться Опубликовано 3 мая, 2015 Да, уже увидел, не думал что у меги так мало может быть. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Геннадий Опубликовано 3 мая, 2015 Поделиться Опубликовано 3 мая, 2015 Это EEPROM, RAM больше. Да и Мега эта кастрированная в два раза от родоначальника. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.