Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите новичку выловить ошибку[avr], Первая программа под МК, ищу ошибку 
:(
    Опции темы
Drakeman
Дата 17.3.2014, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.3.2014

Репутация: нет
Всего: нет



Здравствуйте все! Изучаю самостоятельно Си для МК. Пишу первую программу, моргать светодиодом скучно и не интересно мне да и пройдено уже в примерах, поэтому сразу решил создавать под интересующую меня тему - промоборудование. Сам электрик, электроника хобби, хотя мб и получу соотв. образование в будущем)) Суть проблемы такова(среда Atmel Studio 6.1, МК ATmega16), в дебагере код прошагивается нормально, эмулирую на портах нажатие кнопок, реагирует как задумано, но когда запускаю цикл, спустя некоторое время, даже без дергания ножек в переменные записывается черти-что(в какой момент это происходит не могу выловить). Программа под станок для изготовления сетки рабица, код базовый, то есть требует доработки, добавки функций, но дальше идти нет смысла, пока не выловил ошибку. Повторюсь нуждаюсь именно в помощи по вылавливанию ошибки, мне не нужно "запустить станок", поэтому советы а-ля "опрос кнопок бредовый", или "лучше напиши такой вот код" не воспринимаются как говорится "как есть", почему бредово, чем этот код лучше, я благодарен буду любым советам, подсказкам, но главное для меня понять где ошибка в том, что уже мною написано. Главное для меня - научиться писать, поэтому акцентируйте на моих косяках в понимании операторов, алгоритма и т. д.
Примерный алгоритм:
Вводим число, сколько витков проволоки навить.
вводится число кнопками +10 и +1, то есть ст. и мл. разряд увеличиваем(макс 99).
запускаем старт цикла, идет запуск двигателя навивки, считывается кол-во оборотов и сравнивается с заданым.
при выравнивании чисел идет остановка гл. двигателя, идет опрос концевиков гильетины и запускается двигатель гильетины.
после обрезки проволоки гильетина расходится и цикл повторяется.

Пока проблема возникает еще в холостом режиме, готовности к вводу числа, опроса кнопок и т. д.

П. С. В железе тоже опробовано, всё аналогично, возможно нужно разобраться где запрещать прерывания, но знаний не хватает, да и мб ошибаюсь. МК без кварца юзаю, фьюзы по дефолту, пока рано с этим разбираться. Код закомментирован обильно, но на укр. языке, если будет требование посижу перепишу всё. Датчик оборотов бесконтактный расчитывается(без дребезга) и без необходимости отслеживания направления вращения. Проект полностью тут:
http://webfile.ru/02104dfb5ba36588e4dc88027fbe9fa7

П. П. С. Критику воспринимаю нормально, так что можно и резко, лишь бы по сути проблемы. Время роли не играет, у кого есть минутка, скачайте, гляньте, вдруг что бросится в глаза, но ждать могу сколько угодно, паралельно возможно и буду пытаться писать иначе тот же алгоритм)
PM MAIL   Вверх
Romikgy
Дата 17.3.2014, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 3
Всего: 146



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

main();//Вихід в гол. функцію
 нельзя!!! 
ибо вы переполняете через время стек и программа идет лесом...


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Drakeman
Дата 17.3.2014, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.3.2014

Репутация: нет
Всего: нет



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

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

ISR (INT2_vect)
Сюда повешен датчик витков, срабатывает по лог.1.

Rozklad (char Temp)
В функции раскладывается введенное или отсчитанное по датчику число витков на разряды для вывода на табло(ввод в переменные разрядов десяток и единиц). Вначале проверяется наличие флажка ошибки и наличия отсчитанных витков. Если присутствует ошибка, то функция не выполняется, чтобы не убрать сообщение о ней с табло. Дальше, идет проверка отсчета и ввода заданого числа на =0, если обе переменных по нулям, то есть не введено число ни с датчика, ни с клавы, то выводится код готовности "St" на табло. Дальше раскладывается на десятки и единицы введенные числа с записью в соотв. переменные, когда идет отсчет с датчика, то вывод заданого невозможен.

Error (CodErr1,CodErr2)
От этой планировал отказаться, так как по сути она не нужна, но пока она записывает в переменные разрядов индикатора коды ошибок и проверяет не нажата ли кнопка "Меню", для отключения ошибок. Включает светодиод аварии при флажке ошибки. зацикливается пока на кнопке меню не будет пойман лог.1, то есть попытка отключения ошибки, если лог1 пойман, переходит в Vvod.

int Vvod(int Temp2)
Опрос кнопок. В первом IFе проверка флажка ошибки, если было перенаправление с предыдущей функции, проверяются переменные кол-ва опросов включенной и выключенной кнопки, то есть защита от дребезга контактов кнопки, если насчитает 10 раз "ON", флаг ошибки обнуляется, в противном случае возврат в функцию ошибки, то есть ложное срабатывание кнопки "Меню".
Else, то есть если в IF-е код ошибки не обнаружен, проверяется переменная "Данные", если там не ноль, то число раскладывается на десятки и единицы, чтобы к ним добавлять +1 старшего или младшего разряда.
Дальше в свиче опрашиваются кнопки, в зависимости от кода кнопки из соотв. переменной.
1 кнопка(флаг 0)
вход в меню, то есть опрос кнопок ввода десятков и единиц, плюс выход из меню и ею же отключается ошибка, но на это код выше предусмотрен, планировал потом обьединить их, пока забил.
2 кнопка(флаг 1)
прибавка +1 к десяткам к введенному числу витков
3 кнопка(флаг 2)
прибавка +1 к единицам к введенному числу витков
Этих две кнопки закомментированы неплохо, не вижу смысла дублировать тут.
4 кнопка(флаг 3)
кнопка запуска рабочего цикла, если данные введены, ошибок нет, то при нажатии на неё запускается цикл работы исполнительных механизмов.

Start ()
Тут вроде всё понятно, закомментировано и в доп. разъяснении не нуждается.

Compile ()
функция сравнения отсчитанных витков с введенными данными, включения двигателей и опрос концевиков,тоже не вижу смысла объяснять вроде закомментировано нормально, а кода кот наплакал.

Пины:
Порт А
Пины 0, 1, 2, 3 - кнопки управления.
Пин 4 Светодиод аварии(ошибки).
Пин 7 светодиод готовности к работе.
Порт В
все пины на сегменты индикаторов, кроме пина 2(так как точка на индикаторах не используется один пин свободен на порте, освободил от цифр INT2), там опрос внешних прерываний(счетчик витков).
Порт D
Пин 0 привод двигателя гильетины, прямая полярность(сжатие).
Пин 1 включение двигателя гильетины в обратной полярности(расхождение ножей).
Пины 2 и 3 концевики положения гильётины.
Пины 4 и 5 на аноды индикаторов.
Пин 7 главный привод.

Накатал простыню, ибо не нашел спойлера... smile 
PM MAIL   Вверх
xvr
Дата 19.3.2014, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Ваша функция Vvod рекурсивно вызывает саму себя. При этом условия вызова весьма и весьма развесистые. По первому взгляду на код я не могу утверждать, что рекурсия бесконечная (при каких то данных), но и не могу утверждать обратного. Могу только утверждать, что она довольно глубокая. Стек не переполнился?

PM MAIL   Вверх
Drakeman
Дата 19.3.2014, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.3.2014

Репутация: нет
Всего: нет



За наводку спасибо, попытаюсь разобраться, как это определить в интерфейсе компилятора, но встречный вопрос, как на практике этого избегать? Break, continue какой-то другой оператор, как грамотно избегать этого? Не обязательно разжевывать, просто скажите каким способом Вы посоветовали бы этого избегать, а я погуглю и по непоняткам уже уточнять буду...
PM MAIL   Вверх
xvr
Дата 19.3.2014, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(Drakeman @  19.3.2014,  16:20 Найти цитируемый пост)
 как на практике этого избегать?

На практике не использовать рекурсию там, где она не нужна. IMHO вам нужен простой цикл

PM MAIL   Вверх
Drakeman
Дата 19.3.2014, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.3.2014

Репутация: нет
Всего: нет



Попробую переписать, но всё же, как понять, что именно в стеке дело, гугл не помогает, есть возможность глянуть в студии именно его переполнение в симе?
PM MAIL   Вверх
Drakeman
Дата 20.3.2014, 01:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.3.2014

Репутация: нет
Всего: нет



Все-равно не помогает, избавился от вызовов функций, по стеку ничего не нашел, фз как за ним следить в симуляторе. Ладно, похоже надо всё переписывать по-другому, потом поумнев уже разобрать этот. Как бы Вы писали такой алгоритм, хотя бы структурно обрисуйте, разложение числа для вывода и сам вывод на 7-сегм. у нас есть, нужен ввод с кнопок(при чем матричная клава тут лишняя, всего 4 кнопки хватает, мб и меньше...), отсчет по ИНТ2, старт работы до выравнивания этих двух чисел.
Цитата

На практике не использовать рекурсию там, где она не нужна. IMHO вам нужен простой цикл

Циклы бывают разные...

П. С. Интересно, а возможно настроить таймер на работу от инт2 и сброс по совпадению?..

Это сообщение отредактировал(а) Drakeman - 20.3.2014, 01:57
PM MAIL   Вверх
xvr
Дата 20.3.2014, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(Drakeman @  20.3.2014,  01:53 Найти цитируемый пост)
Как бы Вы писали такой алгоритм, хотя бы структурно обрисуйте,
  • Во первых сделал бы отдельныю процедуру для ожидания нажатия кнопки (любой).
  • Во вторых не делал бы разложения числа витков на единицы/десятки на каждое нажатие кнопки, а так бы его и хранил (отдельно единицы, отдельно десятки). По выходу из функции собирал в конечный счетчик
  • Упростил схему вызовов функций друг из друга, уж очень у вас это сейчас запутанно сделано
  • В прерывании не должно быть вызовов никаких функций, используемых в остновной части программы (функция Error в TIMER0_COMP_vect)
  • Вывод данных на индикатор сделал бы отдельной процедурой (или несколькими), а не присваиваниями в Rozrjad1/2 по всему коду
  • Убрал по максимуму глобальные переменные, используемые для передачи данных между функциями, по возможности локализовал бы их так, что бы использовались они только в 1й функции, а устанавливались в другой (но тоже в единственном экземпляре).
  • Все манипуляции с битами портов убрал бы в функции (или макросы), сейчас очень сложно понять, что и где делается.
  • Если у вас есть несколько глобальных состояний системы, которые влияют на всё (как у вас сейчас сделано с Warning, ON, OFF), то из них надо сделать State Machine. Но похоже у вас они на самом деле не являются такими уж глобальными, а текущее их частое использование обусловленно плохой структурированностью программы.
Для начала сделайте п1.
Как то так -
Код

unsigned char get_key(void)
{
 unsigned char i,j;
 while(PINA & 0x0F) {;}  // Wait when all keys are off
 __delay(30);                 // 30ms delay - button debouncer
 while((i=(PINA&0x0F))==0) {;} // Wait for button press
 __delay(30);                 // 30ms delay - button debouncer
 for(j=0;j<4;++j,i>>=1) // Find out bit number - button index
  if (i&1) return j;
 return 0; // Should not come here
}


Функция Vvod() должна только вводить количество требуемых витков, и возвращать их (или сохранять в глобале), при нажатии кнопки 0 или 3 - возвращаться. Запуск намотки и/или обработка Warning состояния - не ее дело
Код

// Function modifies counter (Danie) and returns button number, if not 1 or 2
unsigned char Vvod(void)
{
 unsigned char cnt_lo = Danie % 10;
 unsigned char cnt_hi = Danie / 10;
 unsigned char rv;

 for(;;)
  {
    show(cnt_hi, cnt_lo); // Put 2 digits/letters on indicator
    rv=get_key();
    switch(rv)
      {
        case 1: ++cnt_hi; if (cnt_hi>9) cnt_hi=0; break;
        case 2: ++cnt_lo; if (cnt_lo>9) cnt_lo=0; break;
        default: Danie = cnt_hi*10+cnt_lo; return rv;
      }
  }
}


Дальше уж сами  smile 

Это сообщение отредактировал(а) xvr - 20.3.2014, 14:53
PM MAIL   Вверх
Drakeman
Дата 22.3.2014, 01:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.3.2014

Репутация: нет
Всего: нет



Сложно понимается такое построение, но не страшно, смысл ясен, спасибо, появится время попробую дописать остальное. Вопрос по show, что оно делает, не нашел в нормальном виде объяснение?
PM MAIL   Вверх
xvr
Дата 22.3.2014, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(Drakeman @  22.3.2014,  01:12 Найти цитируемый пост)
Вопрос по show, что оно делает,

Код

void show(unsigned char sym1, unsigned char sym2)
{
  Rozrjad1 = sym1;
  Rozrjad2 = sym2;
}

PM MAIL   Вверх
Drakeman
Дата 22.3.2014, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.3.2014

Репутация: нет
Всего: нет



Тьфу блин, а я мозги мучаю, пытаясь допереть... smile 
Цитата

Метод Show делает видимым ранее невидимый компонент. Он задает значение true свойству Visible и проверяет, является ли видимым родительский компонент.

http://cubook.supernew.org/manual-c/methods/169-show.html
PM MAIL   Вверх
xvr
Дата 23.3.2014, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(Drakeman @  22.3.2014,  20:45 Найти цитируемый пост)
Метод Show делает видимым ранее невидимый компонент. 

Это цитата из руководства по Borland C++ Builder. Вы пытаетесь на свой ATMega16 Builder запустить?  smile 

PM MAIL   Вверх
Drakeman
Дата 23.3.2014, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 17.3.2014

Репутация: нет
Всего: нет



Это был ответ гугла на запрос "Show в Си"))
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.0510 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.