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

 
 
> Сохранение SREG, идут лишние посылки по UART
paskal
сообщение Apr 2 2010, 17:18
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 29-10-06
Из: Тула
Пользователь №: 21 769



У меня программа принимает некоторый пакет байт по UARTу, затем шлет ответ. И прием и отправку делаю по прерываниям. При этом отсылаемый пакет иногда дублируется. Если же в основной программе после разрешения прерывания передатчика вставить паузу не менеее длины посылки, то работает идеально.
Напрашивается вывод что в обработчике прерывания по передаче меняется SREG, и цикл ожидания по команде BRNE сваливается на передачу еще одного пакета.
Всвязи с этим чайницкий вопрос. А SREG в обработчике сохраняется? И если нет, то как его сохранить?
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
SasaVitebsk
сообщение Apr 2 2010, 18:34
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Если вы про Си, то сохраняется.
А вообще ничего не понятно. Ни компилятор не указали ни контроллер ни язык....
Высасываете предположения чисто из пальца.
Go to the top of the page
 
+Quote Post
paskal
сообщение Apr 2 2010, 19:01
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 29-10-06
Из: Тула
Пользователь №: 21 769



Цитата(SasaVitebsk @ Apr 2 2010, 21:34) *
Если вы про Си, то сохраняется.
А вообще ничего не понятно. Ни компилятор не указали ни контроллер ни язык....
Высасываете предположения чисто из пальца.

На ассемблере, среда - avrstudio, чип - mega128.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 2 2010, 19:17
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(paskal @ Apr 2 2010, 23:01) *
На ассемблере, среда - avrstudio, чип - mega128.

Ну например так
В начале программы.
.DEF SaveSREG =R(0...31)

А прерывании
in SaveSREG,SREG
..............................

при выходе

out SREG,SaveSREG

Но похоже дело в другом.
Но нужен код - выложите плиз

Сообщение отредактировал ILYAUL - Apr 2 2010, 19:21


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
V_G
сообщение Apr 3 2010, 01:23
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Цитата(ILYAUL @ Apr 3 2010, 06:17) *
.DEF SaveSREG =R(0...31)

А прерывании
in SaveSREG,SREG
..............................

при выходе

out SREG,SaveSREG


Если в прерывании меняется SREG, то дело именно в этом. Я во всех прерываниях сохраняю не только статусный регистр, но и пишу в стек сохраненное значение (на случай вложенных прерываний)

CODE
in SaveSREG,SREG
push SaveSREG
..............................

pop SaveSREG
out SREG,SaveSREG


Сообщение отредактировал V_G - Apr 3 2010, 01:27
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 3 2010, 13:55
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(V_G @ Apr 3 2010, 05:23) *
.........(на случай вложенных прерываний)


Не понял , а зачем? Во вложенном прерывании вы просто опять переписываете SREG в SaveSreg при возврате из него оно вернёт Вам предыдущий SREG, а уж выход из первого по счёту прерывания или подпрограммы - вернёт Вам начальный.
Зачем тратить стек и время? Тогда уж Push SREG ...... pop SREG

Цитата
Если в прерывании меняется SREG

Не спорю это одна из причин. Он обязан менятся , если только не просто вошли и тут же вышли. Поэтому и попросил код


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 3 2010, 17:11
Сообщение #7


кекс
******

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



Цитата(ILYAUL @ Apr 3 2010, 16:55) *
Не понял , а зачем? Во вложенном прерывании вы просто опять переписываете SREG в SaveSreg при возврате из него оно вернёт Вам предыдущий SREG, а уж выход из первого по счёту прерывания или подпрограммы - вернёт Вам начальный.


?! Это как так? В одну и ту же ячейку два раза записать разные значения, и вы надеетесь что потом сможете оба значения воcстановить?

Цитата
Тогда уж Push SREG ...... pop SREG

И что это за Push SREG? SREG в AVR находится в I/O space.
push/pop работает только с регистрами R0..R31.

V_G привел абсолютно верный пример для вложенных прерываний.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 3 2010, 21:34
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата
И что это за Push SREG? SREG в AVR находится в I/O space.
push/pop работает только с регистрами R0..R31.
Да "погорячился" конечно in и out

Попробывал в код приведённый ниже ,вставить код V_G дабы избавиться от
Код
ldi    temp,1<<RXCIE1|0<<UDRIE1|1<<RXEN1|1<<TXEN1
    sts UCSR1B,temp

И соответсвенно разрешил вложенное прерывание в данном случае , это стал приёмник.
Т.е , так как первый байт передачи пролетает мимо буфера передатчика сразу в сдвиговый регистр т.е передача начинается "мгновенно" и только 2- ой "застревает" в буфере , то по идее разрешив прерывание приёмника мы должны при передаче 2 байта уйти на обработку приемника , где прервыания запрещены флаг (I)=0 и затем вернутся в передатчик - не проконало .

CODE
;**************************************************
;* ;;/Передача битов команд;;* *
;**************************************************
USART1_UDRE:
push temp ; Заталкиваем в стек temp
in SaveSREG,SREG ; SREG
push count ; счётчик
push rab ; rab
;+ Запрещаем прерывание UDRE, что бы избавиться от двойной буферизации
ldi temp,1<<RXCIE1|0<<UDRIE1|1<<RXEN1|1<<TXEN1
sts UCSR1B,temp
;+ передатчика , иначе возникает ошибка при приёме данных.
ld temp,Y ;/ Получаем байт для отсылки
sbrc Flags,fl_ByteEND;- Проверяем, был отослан весь байт?
rjmp MoveTX ;/ Нет - продолжаем пересылку бит
cpi temp,ResetDS18 ;| Сравниваем - полученный новый байт c SF0
breq SendReset ;| Равно - на формирование RESET
MoveTX:
lsr temp ;| Сдвигаем temp
st Y,temp ;/ Возвращаем байт
brcc Resetrab ;| Проверяем флаг С
ldi rab,Full ;+ Установлен - выводим (1)
rjmp SendToDS
Resetrab:
mov rab,zero ;+ Сброшен - выводим (0)
SendToDS:
sts UDR1,rab ;| Загружаем данные
EndTX:
sbr Flags,fl_ByteEND
pop rab ; Выталкиваем из стека rab
pop count ; счётчик
out SREG,SaveSREG ; SREG
pop temp ; temp
reti

;**************************************************
;* ;;/Приём битов команд;;* *
;**************************************************
USART1_RXC:
push temp ; Заталкиваем в стек temp
in SaveSREG,SREG ; SREG
push count ; счётчик
push rab ; rab
;+ Разрешаем прерывание UDRE
ldi temp,1<<RXCIE1|1<<UDRIE1|1<<RXEN1|1<<TXEN1
sts UCSR1B,temp
ld rab,Y
lds temp,UDR1 ;+ Считываем данные
cpi temp,Full ;| Получена единица
breq WriteOneRX ;| Переходим на запись (1) в старш. бит
rjmp SaveDataDS16 ;| Нет - запись (0)
WriteOneRx:
sbr rab,1<<MsbOne ;-Устанавливаем (1) в старшем бите
SaveDataDS16:
st Y,rab ;+Записываем значение
mov count,SaveBitcount;/Загружаем количество бит
inc count ;| Прибавляем счётчик
cpi count,0x08 ;- Восемь бит обработано
breq CheckBufDS18 ;| Да - переходим на проверку счётчика байт
mov SaveBitcount,count;| Нет - сохраняем счётчик бит
rjmp EndRX ;+ И выходим из прерывания
CheckBufDS18:
cpi rab,ToConvTermo ;| Ищем команду ToConvTermo
brne ForwardCheck ;| Не она идём дальше
CheckPinRX: ;/ По идее конверт. должна закончиться до этой проверки,
sbis PIND,PIND2 ;/ но если на входе (0) конвертация не закончена
rjmp CheckPinRX ;/ Тогда - ждём
ForwardCheck:
cbr Flags,1<<fl_ByteEND;
clr SaveBitcount ;/ Очищаем счётчик бит
adiw Y,0x01 ;/ Добавляем адрес буфера
inc SaveBufCount ;/ Добавляем счётчик буффера
mov count,SaveBufCount;| Загружаем счётчик буфера
cpi count,Full ;| Сравниваем - это последний принимаемый байт
brne EndRX ;+ Нет - выходим из прерывания
clr SaveBufcount ;- Очищаем счётчик бит
ldi temp,0<<RXCIE1|0<<UDRIE1|0<<RXEN1|0<<TXEN1
sts UCSR1B,temp ;/ Запрещаем работу USART1
ldwi Y,DATADS18 ;+ загрузка в YH:YL адреса буфера DS18B20
sbr Flags,1<<fl_ReadyDS18 ;+ Устанавливаем флаг Данные готовы
EndRX:
pop rab ; Выталкиваем из стека rab
pop count ; счётчик
out SREG,SaveSREG ; SREG
pop temp ; temp
reti


Сообщение отредактировал rezident - Apr 5 2010, 14:09
Причина редактирования: Уменьшение видимого размера цитаты исходника.


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Apr 4 2010, 18:41
Сообщение #9


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Вы не поняли, так делать плохо:
Цитата(ILYAUL @ Apr 4 2010, 01:34) *
Код
USART1_UDRE:        
        push    temp; Заталкиваем в стек temp
        in    SaveSREG,SREG; SREG
        push    count; счётчик
        push    rab; rab
;+ Запрещаем прерывание UDRE, что бы избавиться от двойной буферизации
        ldi    temp,1<<RXCIE1|0<<UDRIE1|1<<RXEN1|1<<TXEN1
        sts    UCSR1B,temp
;+ передатчика , иначе возникает ошибка при приёме данных.

        pop    rab; Выталкиваем из стека rab
        pop    count; счётчик
        out    SREG,SaveSREG; SREG
        pop    temp; temp
        reti

Вот так нормально (и не надо никакие прерывания запрещать):
Код
        push    temp
        in    temp,SREG
        push    temp
        push    count
        push    rab

        pop    rab
        pop    count
        pop    temp
        out    SREG,temp
        pop    temp
        reti


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 4 2010, 20:14
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(demiurg_spb @ Apr 4 2010, 22:41) *
Вы не поняли, так делать плохо:


Я уже посчитал - V_G прав.

Есть у меня вот такие макросы их и подставил впредыдущем посте - не прокатило. Всё равно пришлось запрещать UDRE

Код
;***************************************
.macro    BeginInt
    push    Count
    push    ZH
    push    ZL
    push    rab
    push    temp
    in      SaveSREG,SREG
    push    SaveSREG
    push    CopySRAM
.endm
;***************************************
;-                 
;***************************************
.macro    EndInt
    pop    CopySRAM
    pop    SaveSREG
    out    SREG,SaveSREG
    pop    temp
    pop    rab
    pop    ZL
    pop    ZH
    pop    Count
.endm
;***************************************


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 5 2010, 05:44
Сообщение #11


Гуру
******

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



Цитата(ILYAUL @ Apr 4 2010, 23:14) *
Есть у меня вот такие макросы их и подставил впредыдущем посте - не прокатило.

Прежде чем выполнить команду "in SaveSREG,SREG" регистр SaveSREG желательно сохранить с стеке (как в примере у demiurg_spb), и соответственно восстановить этот регистр по окончанию прерывания.
Go to the top of the page
 
+Quote Post
V_G
сообщение Apr 5 2010, 06:24
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Цитата(Палыч @ Apr 5 2010, 16:44) *
Прежде чем выполнить команду "in SaveSREG,SREG" регистр SaveSREG желательно сохранить с стеке (как в примере у demiurg_spb), и соответственно восстановить этот регистр по окончанию прерывания.

В общем случае - да, но я лично регистр для сохранения статуса в основной программе не использую, только в обработчиках прерываний.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 5 2010, 06:59
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Но в случаях без вложенных прерываний волне возможно обойтись и in savesreg, sreg и соответствеено out .... Правильно ?


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 5 2010, 07:52
Сообщение #14


Гуру
******

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



Цитата(ILYAUL @ Apr 5 2010, 09:59) *
Но в случаях без вложенных прерываний волне возможно обойтись и in savesreg, sreg и соответствеено out .... Правильно ?
Т.е. Вы хотите обойтись без сохранения/восстановления SREG в прерываниях? Ни в коем случае!

Или: вопрос был о том, нужно ли всё-же сохранять регистр savereg? Если этот регистр предназначен исключительно для сохранения SREG и для других целей не используется нигде, то - да, можно его не сохранять; но в противном случае - сохранять/восстанавливать обязательно.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 5 2010, 10:58
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(Палыч @ Apr 5 2010, 11:52) *
Т.е. Вы хотите обойтись без сохранения/восстановления SREG в прерываниях? Ни в коем случае!

Или: вопрос был о том, нужно ли всё-же сохранять регистр savereg? Если этот регистр предназначен исключительно для сохранения SREG и для других целей не используется нигде, то - да, можно его не сохранять; но в противном случае - сохранять/восстанавливать обязательно.

Да имено так , я сохраняю в отдельном регистре , предназначенный именно под SREG и конечно для других целей его не использую.
В приведённом мною коде ( огрызок ) , нет ещё одного прерывания , которое используется в программе , но несмотря на то что , я не толкаю SAVESREG в стек , данные возвращаются всегда коректно. Поэтому и полемика.
Поэтому и не видел смысла пушить его. Хотя надо отметиь , что вложенных прерываний в программе нет.

Сообщение отредактировал ILYAUL - Apr 5 2010, 10:59


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post

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

 


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


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