|
Сохранение SREG, идут лишние посылки по UART |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Apr 2 2010, 19:01
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 29-10-06
Из: Тула
Пользователь №: 21 769

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

Профессионал
    
Группа: Свой
Сообщений: 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
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Apr 3 2010, 13:55
|

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

|
Цитата(V_G @ Apr 3 2010, 05:23)  .........(на случай вложенных прерываний) Не понял , а зачем? Во вложенном прерывании вы просто опять переписываете SREG в SaveSreg при возврате из него оно вернёт Вам предыдущий SREG, а уж выход из первого по счёту прерывания или подпрограммы - вернёт Вам начальный. Зачем тратить стек и время? Тогда уж Push SREG ...... pop SREG Цитата Если в прерывании меняется SREG Не спорю это одна из причин. Он обязан менятся , если только не просто вошли и тут же вышли. Поэтому и попросил код
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Apr 3 2010, 17:11
|

кекс
     
Группа: Свой
Сообщений: 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 привел абсолютно верный пример для вложенных прерываний.
|
|
|
|
|
Apr 3 2010, 21:34
|

Профессионал
    
Группа: Свой
Сообщений: 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
Причина редактирования: Уменьшение видимого размера цитаты исходника.
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Apr 4 2010, 18:41
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Apr 4 2010, 20:14
|

Профессионал
    
Группа: Свой
Сообщений: 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 ;***************************************
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Apr 5 2010, 10:58
|

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

|
Цитата(Палыч @ Apr 5 2010, 11:52)  Т.е. Вы хотите обойтись без сохранения/восстановления SREG в прерываниях? Ни в коем случае!
Или: вопрос был о том, нужно ли всё-же сохранять регистр savereg? Если этот регистр предназначен исключительно для сохранения SREG и для других целей не используется нигде, то - да, можно его не сохранять; но в противном случае - сохранять/восстанавливать обязательно. Да имено так , я сохраняю в отдельном регистре , предназначенный именно под SREG и конечно для других целей его не использую. В приведённом мною коде ( огрызок ) , нет ещё одного прерывания , которое используется в программе , но несмотря на то что , я не толкаю SAVESREG в стек , данные возвращаются всегда коректно. Поэтому и полемика. Поэтому и не видел смысла пушить его. Хотя надо отметиь , что вложенных прерываний в программе нет.
Сообщение отредактировал ILYAUL - Apr 5 2010, 10:59
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|