Didro 0 10 июня, 2012 Опубликовано 10 июня, 2012 (изменено) · Жалоба Добрый день, работаю с AT90CAN32. В основной программе обнаружил странную ошибку и в процессе выяснения обстоятельств получил вот такой пример, её иллюстрирующий: #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include "twi_master.h" unsigned char sendbuf[2] = {0b0011011<<1, 0xB4}; int main(void) { CLKPR = 0x80; CLKPR = 0x00; DDRB = 0xFF; DDRE |= (1<<PE2); sei(); TWI_Master_Initialise(); TWI_Start_Transceiver_With_Data(sendbuf, 2); unsigned char cntr=1; while(1) { if (fint) {fint = 0; TWI_Start_Transceiver_With_Data(sendbuf, 2); } //_delay_us(30); если раскомментировать эту строку //__asm__ __volatile__ ("ldir25, 0x61" ::); //или если раскомментировать эту строку, то проблема себя не проявляет volatile unsigned char tvar2876; tvar2876 = 0x61; if (tvar2876 != 0x61) { PORTB = tvar2876; PORTE|=1<<2;_delay_us(200);PORTE&=~(1<<2);_delay_us(200); } } return 0; } Реализация функций работы с TWI взяты из AppNote315 (файлы TWI_Master.h и TWI_Master.c, приложены: TWI_Master.h.txt TWI_Master.c.txt). Проблема заключается в том, что на PORTB выводится число 0х61 - т.е. срабатывает сравнение tvar2876 != 0x61, хотя очевидно, что такого быть не должно. Имя переменной tvar2876 выбрано случайным (специально, чтоб не думалось, что эта переменная где-то объявлена как external в других модулях). Делаю следующий вывод по asm-листингу: AVR_Transmission.lss.txt регистр r24, участвующий в операции сравнения меняется где-то в TWI-функциях (побочный эффект). В чем может быть проблема ? Ранее с таким не сталкивался. Компилировал AVR Studio 4 (Winavr2010aug), AVR Studio 6. Оптимизации выключены -O0 Спасибо Изменено 10 июня, 2012 пользователем IgorKossak [codebox] для длинного кода!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 10 июня, 2012 Опубликовано 10 июня, 2012 · Жалоба Ага меняется , он сохраняется только в прерывании . Во всех других функциях его не заталкивают в stack. Но больше всего меня напрягло вот это Вход: push r29 push r28 Выход: pop r0 pop r0 pop r0 pop r0 pop r28 pop r29 5ca: 08 95 ret Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 10 июня, 2012 Опубликовано 10 июня, 2012 · Жалоба Но больше всего меня напрягло вот это А что именно тут напрягает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 10 июня, 2012 Опубликовано 10 июня, 2012 · Жалоба А что именно тут напрягает? pop r0 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 10 июня, 2012 Опубликовано 10 июня, 2012 · Жалоба pop r0 Там же сразу после PUSH rcall .+0 rcall .+0 Но зачем оно надо я хз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 10 июня, 2012 Опубликовано 10 июня, 2012 · Жалоба Studio интерпретирует команду rcall 0 в RCALL PC-0x00EC - с любой точки на reset. Но там похоже IAR Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 10 июня, 2012 Опубликовано 10 июня, 2012 · Жалоба Но зачем оно надо я хз.Самый быстрый, короткий и атомарный способ зарезервировать на стеке 2 байта. Studio интерпретирует команду rcall 0Там команда rcall .+0, а это несколько другое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 11 июня, 2012 Опубликовано 11 июня, 2012 · Жалоба Самый быстрый, короткий и атомарный способ зарезервировать на стеке 2 байта. Там команда rcall .+0, а это несколько другое. А зачем , этот резерв . Смысл? Да я понимаю , что это несколько другое. Studio принимает и такое rcall .0 плюс перед 0 категорически отказывается принимать. Но результат тот же - перезагрузка . Только зачем тогда столько pop r0 , может существует обратная иструкция rcall .-0 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kool 0 12 июня, 2012 Опубликовано 12 июня, 2012 · Жалоба Насколько я помню, в этих аппнотах (вернее, в реализации) была проблема с тем, что если вызвать 2 сеанса передачи последовательно один за другим, то программа генерирует старт-условие на линии не дожидаясь завершения формирования стопа от предыдущего сеанса. Связано это с тем, что прерывание по приему TWI co статусом "stop received" приходит сразу как только обнаружен фронт на SDA ( при SCL=1), а не после фронта + tимп. Поэтому нужно после событие стопа на линии подождать tимп, а затем пробывать начать новую передачу. (уже подзабыл, чему должно быть равно tимп - 1/2 или 1/4 такта) З.Ы. Извиняюсь за немного сумбурное объяснение Update: Извините, не сразу вник в суть проблемы. Вы говорите, что регистр r24, участвующий в операции сравнения меняется где-то в TWI-функциях (побочный эффект). Но там кроме r24 есть еще и Y+50. Может, у Вас просто память где-то портится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться