Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2017-дек-16 15:52

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: Неверно транслируется код
СообщениеДобавлено: 2015-апр-15 17:58 
Не в сети
Аватара пользователя

Зарегистрирован: 2013-июн-21 15:27
Сообщения: 76
Откуда: Новосибирск
Работаю в последней версии CodeMaster-ARM с МК 1986ВЕ91Т. В проекте есть процедуры для "засыпания" программы на определённый период, реализованы с помощью таймера Timer1, работающего на частоте 20 МГц. SetTmr_x01us() задаёт момент начала задержки и её длительность, а WaitTmr() "усыпляет" программу до момента прерывания от таймера. Первая процедура имеет 2 параметра: основная длительность задержки с точностью 100 нс и "компенсация накладных расходов" (положительные значения уменьшают задержку с шагом 50 нс, отрицательные увеличивают). Вот исходный код:

Код:
void SetTmr_x01us(unsigned short int t, short int d)
{ // Запуск задержки на (t/10) мкс (НЕ МЕНЬШЕ 5 мкс!!!)
  MDR_TIMER_TypeDef* TMR1 = MDR_TIMER1;
  register int n;
// ---------------------------------------------------------------------------
  TMR1->STATUS = 0;                 // сброс событий таймера TIMER1
  TMR1->CNTRL  = 0;                 // выкл. TIMER1
//  TMR1->PSG    = 0;                 // 20 (10) МГц
  TMR1->CNT    = 0;                 // начальное значение счетчика
  n            = (t << 1) - 33 - d; // может оказаться < 0
  TMR1->ARR    = (n <= 0)? 1 : n;   // ограничение снизу: ARR >= 1
#ifdef SAFE_SYNCH
  TMR1->CCR1   = (n > 75)? n - 75 : n + 5;
#endif // #ifdef SAFE_SYNCH
  pBitPls(o_IndTim,iDark);          // индикация задержки                  (U)
  TMR1->CNTRL = TimerMode           // счет вверх до ARR
              | TIMER_CNTRL_CNT_EN; // вкл. TIMER1
  sSet(isTime,0);                   // сброс флага ожидания до прерывания от TIMER1
#ifdef SAFE_SYNCH
  TMR1->IE    = (1 << TIMER_STATUS_CCR_REF_EVENT_Pos)// разр.прерывание по совпадению с CCRi
              | TIMER_IE_CNT_ARR_EVENT_IE;           // разр.прерывание по достижению ARR
#else
  TMR1->IE    = TIMER_IE_CNT_ARR_EVENT_IE; // разр.прерывание по достижению ARR
#endif // #ifdef SAFE_SYNCH
} // end of SetTmr_x01us()
// ===========================================================================
void WaitTmr(void)
{ // Ожидание запущенной задержки
  while (!sGet(isTime))
  {                        // ждать установки флага ожидания по прерыванию от TIMER1
#pragma asm
        WFI                // спать до очередного прерывания
#pragma endasm
  } // end of while (!sGet(isTime))
  sSet(isTime,0);          // сброс флага ожидания
  pBitSet(o_IndTim,iDark); // сброс индикации задержки                     (.)
} // end of WaitTmr()


Всё это нормально работало, но в один не прекрасный момент я вдруг заметил, что не получается точно настроить одну из задержек, где корректирующее значение оказалось отрицательным.
Вот строка вызова процедуры:

Код:
SetTmr_x01us(TiInt2, dOutIz);

где в h-файле задано TiInt2 = 72, dOutIz = -3

вот как это выглядит в выходном файле препроцессора (файл *.i):

Код:
SetTmr_x01us(72, (-3));


тут вроде всё правильно. А вот что получается на выходе С-транслятора (файл *.src):

Код:
;000554      SetTmr_x01us(TiInt2, dOutIz);        // синхронизация цикла опроса
   MOVS            R0,#72
   MVN             R1,#2
   BLF             SetTmr_x01us


видно, что тут значение -3 превратилось в +2. Я пробовал менять значения и выяснил, что положительные числа транслируются правильно, а для отрицательных транслятор вместо -N пишет +(N-1).
Почему?

_________________
Странник


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неверно транслируется код
СообщениеДобавлено: 2015-апр-15 18:29 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1039
Откуда: Тула
Эксперимента ради, попробуйте добавить ключевое слово signed в определение знаковых переменных.
Код:
void SetTmr_x01us(unsigned short int t, signed short int d)
{ ...
  register signed int n;
}

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неверно транслируется код
СообщениеДобавлено: 2015-апр-16 09:09 
Не в сети

Зарегистрирован: 2010-авг-30 19:12
Сообщения: 381
В данном случае использована инструкция загрузки с инверсией
Цитата:
MVN R1,#2


вот описание
Цитата:
MVN{S}{cond} Rd, Operand2
Инструкция MVN считывает значение второго операнда Operand2, производит его
побитную инверсию, после чего помещает результат в регистр Rd.

-3 в hex и двоичном представлении (сократил до байта) 0xFD 11111101b
что соответствует побитному инвертированию числа 2 0x02 00000010b
так что вроде все логично.

_________________
О сколько нам открытий чудных
Готовит просвященья дух,
И опыт - сын ошибок трудных ... (Пушкин)

Пергаменты не утоляют жажду ("Фауст",Гете)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неверно транслируется код
СообщениеДобавлено: 2015-апр-16 16:30 
Не в сети
Аватара пользователя

Зарегистрирован: 2013-июн-21 15:27
Сообщения: 76
Откуда: Новосибирск
Спасибо!
Действительно, я не обратил внимания на то, что там MVN, а не MOV.
Но тогда ещё более непонятно... Собственно, я полез в результаты трансляции потому, что никак не получалось точно настроить одну из задержек. Она была меньше, чем нужно, я ставил отрицательную коррекцию, чтобы чуть увеличить, а получалось ещё меньше... Ладно, буду разбираться, в чём ещё там может быть дело...

_________________
Странник


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неверно транслируется код
СообщениеДобавлено: 2015-апр-17 10:18 
Не в сети

Зарегистрирован: 2010-авг-30 19:12
Сообщения: 381
Может быть проблема в интерпретации знаковых-беззнаковых чисел.Если сбои идут именно при отрицательных значениях.
Например стоит по умолчанию int как беззнаковое.
тогда
Код:
n = (t << 1) - 33 - d; // может оказаться < 0 [b]!!!! здесь может быть сбой[/b]
  TMR1->ARR    = (n <= 0)? 1 : n;   // ограничение снизу: ARR >= 1 // ограничение снизу: ARR >= 1

будет сбоить.
И еще хочу обратить внимание. TMR1->ARR - 16 разрядный. поэтому n используется не целиком а только младшая часть.

_________________
О сколько нам открытий чудных
Готовит просвященья дух,
И опыт - сын ошибок трудных ... (Пушкин)

Пергаменты не утоляют жажду ("Фауст",Гете)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неверно транслируется код
СообщениеДобавлено: 2015-апр-17 20:00 
Не в сети
Аватара пользователя

Зарегистрирован: 2013-июн-21 15:27
Сообщения: 76
Откуда: Новосибирск
Да, спасибо. Я помню, что счётчики 16-разрядные, и именно поэтому параметры процедуры описаны как unsigned short int (длительность) и short int (коррекция). Впрочем, при используемых в данном случае значениях всё даже в один байт входит.
Умолчание для целых - судя по генерируемому коду - знаковое.
Мало того, в других местах программы эта же процедура ведёт себя правильно как с положительной, так и с отрицательной коррекцией, а вот именно в этом месте (обработчик прерывания ExtInt2) что-то не так, хотя раньше работало и тут, и вроде я эту процедуру давно уже не менял (ну, кроме разве что корректирующей константы -33, учитывающей "накладные расходы" внутри самой процедуры - эта константа уточнялась по результатам калибровки; кстати, в процессе калибровки выяснилось, что длительность генерируемой задержки зависит от заданного значения и от частоты HCLK не совсем линейно, вероятно сказываются какие-то особенности схемы таймера).
Что касается основной проблемы, то, скорее всего, что-то важное я упустил в самом обработчике ExtInt2, и это как-то влияет на таймер. Пока разбираюсь...

_________________
Странник


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Bing [Bot] и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB