реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> ATmega 16L проблема с UART
ProfessorBraz
сообщение Apr 17 2008, 11:31
Сообщение #1





Группа: Новичок
Сообщений: 9
Регистрация: 17-04-08
Пользователь №: 36 821



Выручай всезнающий Олл!

ATmega 16L проблема с UART, а именно после посылки всего, когда буфер уже пустой возвращается из интерапта на начало программы (фактически рестарт). Код прерывания
Код
ISR(USART0_UDRE_INTERRUPT)
{
    uint8_t temp_tail;
    
    if ( USART0_TX_Head != USART0_TX_Tail)                            
    {
        temp_tail = (USART0_TX_Tail + 1) & USART_TX_BUFFER_MASK;    
        USART0_TX_Tail = temp_tail;                                    
        USART0_UDR = USART0_TX_Buffer[temp_tail];                
    }
    else                                                       {                                                    
        USART0_UCSRB &= ~(1<<USART0_UDRIE);                            
        USART0_Enable_Int_Status = 1;
    }
}


Что я делаю не так. При просмотре в Студии в режиме ассемблега, видно что в переходе на прерывание все пакуется в стек, потом также аккуратно распаковывается, и возвращается по команде RTI, но почемуто в старт? help.gif

Може кто с таким эффектом сталкивался?
Go to the top of the page
 
+Quote Post
galjoen
сообщение Apr 17 2008, 11:51
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(ProfessorBraz @ Apr 17 2008, 15:31) *
видно что в переходе на прерывание все пакуется в стек, потом также аккуратно распаковывается, и возвращается по команде RTI, но почемуто в старт? help.gif

Не понял - вы увидели, что правильный адрес возврата в стеке лежит, а возвращается в 0? Или адрес возврата никто в стек и не клал? Что значит "в переходе на прерывание"?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 17 2008, 11:52
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



ИМХО, стек переполнился.
Go to the top of the page
 
+Quote Post
galjoen
сообщение Apr 17 2008, 11:54
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(Палыч @ Apr 17 2008, 15:52) *
ИМХО, стек переполнился.

Переопустошился (или как это будет по русски?).
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 17 2008, 12:01
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Все-таки переполнился.
Возможность зануления адреса возврата есть только на этой строке:

USART0_TX_Tail = temp_tail;


После линковки создается отчет по расходу памяти. Посмотрите сколько памяти данных у Вас занято?

(все что остается - отдается под стек, я не позволяю себе оставлять под стек меньше 256 байт).
Go to the top of the page
 
+Quote Post
ProfessorBraz
сообщение Apr 17 2008, 12:09
Сообщение #6





Группа: Новичок
Сообщений: 9
Регистрация: 17-04-08
Пользователь №: 36 821



Вот это скорость ответов на форуме! Супер!

К теме
Код
239:              USART0_Enable_Int_Status = 1;
+000002D1:   E081        LDI     R24,0x01         Load immediate
+000002D2:   93800167    STS     0x0167,R24       Store direct to data space
+000002D4:   91FF        POP     R31              Pop register from stack
+000002D5:   91EF        POP     R30              Pop register from stack
+000002D6:   919F        POP     R25              Pop register from stack
+000002D7:   918F        POP     R24              Pop register from stack
+000002D8:   900F        POP     R0               Pop register from stack
+000002D9:   BE0F        OUT     0x3F,R0          Out to I/O location
+000002DA:   900F        POP     R0               Pop register from stack
+000002DB:   901F        POP     R1               Pop register from stack
+000002DC:   9518        RETI                     Interrupt return


Занятость:
Data: 383 bytes (37.4% Full)

Чем может переполниться стек, если программа только получает и отсылает по 5-7 Байт? help.gif
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 17 2008, 12:22
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(ProfessorBraz @ Apr 17 2008, 15:09) *
Чем может переполниться стек, если программа только получает и отсылает по 5-7 Байт? help.gif
Так Вы в Студии и проконтролируйте стек: состояние стека и содержимое его когда вошли в прерывание, и когда выходите (перед RTI). Должно быть одним и тем же.
Go to the top of the page
 
+Quote Post
ProfessorBraz
сообщение Apr 17 2008, 12:32
Сообщение #8





Группа: Новичок
Сообщений: 9
Регистрация: 17-04-08
Пользователь №: 36 821



Цитата(Палыч @ Apr 17 2008, 16:22) *
Так Вы в Студии и проконтролируйте стек: состояние стека и содержимое его когда вошли в прерывание, и когда выходите (перед RTI). Должно быть одним и тем же.


указатель стека при входе и выходе не отличаются, короче. сколько запаковывается, столько же и распаковывается. Содержания стека я в студии не нашел. Может подскажешь, палычь, где оно в студии зарыто? 07.gif
Go to the top of the page
 
+Quote Post
galjoen
сообщение Apr 17 2008, 12:35
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(Палыч @ Apr 17 2008, 16:22) *
Так Вы в Студии и проконтролируйте стек: состояние стека и содержимое его когда вошли в прерывание, и когда выходите (перед RTI). Должно быть одним и тем же.

+1
И регистры должны то-же значение иметь, и адрес возврата в стеке д.б.
Вы в прерывание как входите? М.б. вы просто адрес возврата в стек не кладёте? Надо при отладке call/rcall команду на таблицу прерываний делать.
Go to the top of the page
 
+Quote Post
ProfessorBraz
сообщение Apr 17 2008, 12:45
Сообщение #10





Группа: Новичок
Сообщений: 9
Регистрация: 17-04-08
Пользователь №: 36 821



Цитата(galjoen @ Apr 17 2008, 16:35) *
+1
И регистры должны то-же значение иметь, и адрес возврата в стеке д.б.
Вы в прерывание как входите? М.б. вы просто адрес возврата в стек не кладёте? Надо при отладке call/rcall команду на таблицу прерываний делать.

Опа?! А вот с этого места по подробнее. Я всю жизнь думал, что при вызове прерывания адрес возврата сохраняется автоматически в стек. Если это не так, то как это делается и в каком месте. Я же не знаю в какой момент прерывание произойдет. Где этот код распологать? crying.gif
Go to the top of the page
 
+Quote Post
galjoen
сообщение Apr 17 2008, 13:11
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(ProfessorBraz @ Apr 17 2008, 16:45) *
Опа?! А вот с этого места по подробнее. Я всю жизнь думал, что при вызове прерывания адрес возврата сохраняется автоматически в стек.

Правильно думали.
Цитата(ProfessorBraz @ Apr 17 2008, 16:45) *
Если это не так, то как это делается и в каком месте. Я же не знаю в какой момент прерывание произойдет. Где этот код распологать? crying.gif

Это только для отладки. А как у вас прерывание от USART при отладке вызывается?

А чтоб стек проконтролировать - надо ОЗУ начиная с адреса указателя стека посмотреть.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 17 2008, 14:51
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(ProfessorBraz @ Apr 17 2008, 15:09) *
Занятость:
Data: 383 bytes (37.4% Full)
Чем может переполниться стек, если программа только получает и отсылает по 5-7 Байт? help.gif
Действительно, обработчик прерывания, фрагмент кода которого Вы привели использует 9 байт стека. Но стек также использует и основная программа: для адресов возврата из вызываемых подпрограмм, для размещения локальных переменных и массивов, передачи параметров процедурам и функциям... Разные трансляторы используют стек по-разному. Я плохо знаком с WinAVR, и не могу сказать - что со стеком делает он... Но, во всех трансляторах (ИМХО) самые прожорливые до памяти функции - printf, scanf и им подобные. Используете ли Вы подобные процедуры? Есть ли в Вашей программе большие локальные массивы?
Цитата(ProfessorBraz @ Apr 17 2008, 15:32) *
Содержания стека я в студии не нашел. Может подскажешь, палычь, где оно в студии зарыто?
Стек распалагается в памяти - для просмотра можно использовать окно Memory.
Цитата(ProfessorBraz @ Apr 17 2008, 15:45) *
Я же не знаю в какой момент прерывание произойдет. Где этот код распологать?
Делать искуственный вызов процедуры прерывания из программы не надо - достаточно "пошевелить" флаги - само произайдёт. Кстати, Вы ведь умудрились увидеть как-то вот это
Цитата(ProfessorBraz @ Apr 17 2008, 14:31) *
При просмотре в Студии в режиме ассемблега, видно что в переходе на прерывание все пакуется в стек, потом также аккуратно распаковывается, и возвращается по команде RTI, но почемуто в старт?
Как? Ну, так сделайте это же ещё раз с контролем стека.
P.S. Последняю цитата, может быть, говорит только о том, что Вы увидели в окне команды push/pop/reti? Тогда, как Вы определили, что именно по reti этого обработчика программа попала на нулевой адрес?
Go to the top of the page
 
+Quote Post
ProfessorBraz
сообщение Apr 18 2008, 06:58
Сообщение #13





Группа: Новичок
Сообщений: 9
Регистрация: 17-04-08
Пользователь №: 36 821



Переход осуществляется на адресс указанный в стеке. Странно только,что команда RTI ситает из стека 2 байта (0х20 0хЕ8) а переходит на 0хЕ8. Но такого адресса 0х20Е8 или 0хЕ820 все равно нет. В стеке все нормально, до переполнения ему еще очень долеко, там всего 38 байт. wacko.gif
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 18 2008, 08:03
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(ProfessorBraz @ Apr 18 2008, 09:58) *
Странно только,что команда RTI ситает из стека 2 байта (0х20 0хЕ8) а переходит на 0хЕ8.
Возможно, Вы не учитываете то, что Stack Pointer указывает на свободную ячейку: содержимое стека - выше. Т.е., если возврат на 0х00Е8, то в ячейке +1 должен быть 00, в ячейке +2 должно быть Е8.
Отчего всё же Вы решили, что на адрес 0 попадаете по reti из этого обработчика?
Go to the top of the page
 
+Quote Post
ProfessorBraz
сообщение Apr 18 2008, 08:20
Сообщение #15





Группа: Новичок
Сообщений: 9
Регистрация: 17-04-08
Пользователь №: 36 821



Цитата(Палыч @ Apr 18 2008, 12:03) *
Отчего всё же Вы решили, что на адрес 0 попадаете по reti из этого обработчика?

потому-что после reti программа переходит вот сюда
Код
+000000E4:   E081        LDI     R24,0x01         Load immediate
+000000E5:   93800184    STS     0x0184,R24       Store direct to data space
+000000E7:   CFFF        RJMP    PC-0x0000        Relative jump


теперь это Е7.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 13:35
Рейтинг@Mail.ru


Страница сгенерированна за 0.03231 секунд с 7
ELECTRONIX ©2004-2016