Перейти к содержанию
    

Не работает умножение на микроконтроллере

Здравствуйте!

Микроконтроллер не выполняет умножение, если в качестве множителей стоят переменные. Вот код:

long x, y;

x=15;

y=x*2;

indicate(y); ///отображение числа y на семисегментном экране.

В результате отображаетс не 30, а 15, то есть вместо операции y=x*2 выполнилась операция x=y;

Если множители типа int, умножение так же не работает, вот код:

int x, y;

x=15;

y=x*2;

indicate(y); ///отображение числа y на семисегментном экране.

В результате отображается нуль.

Операция умножения работает, только если множители заданы числами:

long y;

y=15*2;

indicate(y); ///отображение числа y на семисегментном экране.

В этом случае отображается число 30, как и должно быть.

В чём может быть проблема?

Cпасибо.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Операция умножения работает, только если множители заданы числами:

long y;

y=15*2;

Это не умножение работает, а препроцессор. И забивает по месту заранее сосчитанную константу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это не умножение работает, а препроцессор. И забивает по месту заранее сосчитанную константу.

А почему может не умножать микроконтроллер?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему может не умножать микроконтроллер?

 

А с чего вы взяли, что контроллер не умножает?

 

А если так

volatile int x, y, z;

x= 15;
z = 2;

y = x * z;
indicate(y); ///отображение числа y на семисегментном экране.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А с чего вы взяли, что контроллер не умножает?

 

А если так

volatile int x, y, z;

x= 15;
z = 2;

y = x * z;
indicate(y); ///отображение числа y на семисегментном экране.

Так то же не работает, в результате умножения получается нуль.

 

Не, лучше подробнее код, а то так ничего не понятно.

#include "pic18f4520.h"

 

int x, y, z;

void indicate(int value);

 

void main(void)

{

x=15;

z=3;

y=x*z;

indicate(y); ///индикация на ЖК экране.

}

 

void indicate(int value)

{

..... ////подпрограмма отображения символа на экране.

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Коллеги, проблему удалось решить.

В начале программы, после строки include "pic18F4520.h" я написал настройку конфигурационного регистра:

 

#ifdef MPLAB_ICD

__CONFIG(4, STVREN & LVPDIS & XINSTDIS & DEBUGEN);

#else

__CONFIG(4, STVREN & LVPDIS & XINSTDIS & DEBUGDIS);

#endif

 

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

Всем спасибо за советы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как разрешение или запрет поддержки ICD может повлиять на работу умножителя, боюсь, никому не понятно. Эта поддержка требует некоторых ресурсов контроллера - пара ног, 256 слов на верхушке программной памяти да чуток ОЗУ и стека.

Другие ограничения при отладке с ICD расписаны в документации, но не помню, чтобы там поминался какой-то "расширенный набор команд". (у PIC18F4520 набор команд точно такой же как у остальных PIC18, и все команды благополучно доступны с ICD)

 

ЗЫЖ симулятор МПЛаба прекрасно симулирует умножитель.

ЗЗЫЖ для y=x*2 компилятор наверняка не стал заморачиваться с умножителем и заменил умножение сдвигами.

ЗЗЗЫЖ скорее всего Ваша проблема связана с проказами компилятора (а ПРО - такой проказник), но тогда её можно решить медитацией над результатами компиляции, а не телепатическим сеансом.

Если у Вас действительно ПРО, и относительно старый, то

- сначала стОит сравнить сорцы с полученными ассемблерными листингами и заглянуть в мап-файл;

- не стОит это делать в присутствии людей, которые думают, что Вы не умеете ругаться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ЗЫЖ симулятор МПЛаба прекрасно симулирует умножитель.

Симулировал он действительно прекрасно, но при прошивке программы в контроллер умножение не работало.

ЗЗЫЖ для y=x*2 компилятор наверняка не стал заморачиваться с умножителем и заменил умножение сдвигами.

Умножение не работало с разными числами. Проверял сгенерированный ассемблерный код, там был код умножения, а не сдвига.

её можно решить медитацией над результатами компиляции

Ассемблерный код, сгенерированный компилятором, я могу только посмотреть, но не менять. Вы знаете способ изменить этот ассемблерный код перед созданием hex файла? (кроме использования ассемблерной вставки в С - коде)

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как разрешение или запрет поддержки ICD может повлиять на работу умножителя, боюсь, никому не понятно. Эта поддержка требует некоторых ресурсов контроллера - пара ног, 256 слов на верхушке программной памяти да чуток ОЗУ и стека.

 

Так вот, может стека как раз и не хватало?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хайтек PICC фтопку, он буйный. Был и будет.

Расскажите это на форуме Микрочипа. Почему-то у всех, кто имел категоричность гнать пургу на компилятор, особенно по подобным поводам, обнаруживались кривые руки...

 

Ассемблерный код, сгенерированный компилятором, я могу только посмотреть, но не менять. Вы знаете способ изменить этот ассемблерный код перед созданием hex файла? (кроме использования ассемблерной вставки в С - коде)

Его не надо менять. Вы его приведите, посмотрим. Дебаггер Вы не используете?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Расскажите это на форуме Микрочипа. Почему-то у всех, кто имел категоричность гнать пургу на компилятор, особенно по подобным поводам, обнаруживались кривые руки...

Поглядим. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Симулировал он действительно прекрасно, но при прошивке программы в контроллер умножение не работало.

hex в контроллер заливался тот же самый или с поддержкой ICD?

Умножение не работало с разными числами. Проверял сгенерированный ассемблерный код, там был код умножения, а не сдвига.

Я говорил про описанный Вами случай x*2. Здесь компилятор оставит умножение только при отключённой оптимизации.

Ассемблерный код, сгенерированный компилятором, я могу только посмотреть, но не менять. Вы знаете способ изменить этот ассемблерный код перед созданием hex файла? (кроме использования ассемблерной вставки в С - коде)

Если очень хочется, то можно скомпилить в ассемблерные листинги, поковыряться, а потом из них собрать hex.

Касательно умножений (и остальной арифметики) - они живут в библиотеках, отлажены и вылизаны, сорцы функций доступны. Если есть подозрение, ничто не мешает включить эти сорцы в проект и убедиться, что они работают как задумано.

Так вот, может стека как раз и не хватало?

Вряд ли. Линкер использование стека отслеживает и при возможности переполнения ругается. Я бы в мап-файл заглянул, не накосячил ли линкер с расположением секций.

ТС не показал содержимое indicate(), но сомневаюсь, что там можно выбрать хотя бы хардварный стек. Если таки удалось, то это повод задуматься о замене контроллера на более разумный без таких ограничений - 31-уровневый стек - просто издевательство над полётом фантазии.:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...