Обсуждаем контроллеры компании Atmel.
Ответить

Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 08:24:11

День добрый, ломал голову как сделать счетчик от 0 до 99 с обнуление при переполнении. Вроде бы сломал и сделал, через прерывания, таймер и все такое. Проверил в протеусе работает. Стал проверять на железе высвечиваются по 0 на обоих сегментах :( думал мк закосячил, залил старую программку для вывода чисел указанных в коде - все нормально вывело, а тут не считает. Делал по урокам в инете, все в кучу собрал но не повезло. В протеусе адекватно работает на частоте в 2МГЦ, в реале перепробовал все частоты внутреннего генератора от 1-2-4-8 на всех высвечивается по 00 :(
Может быть кто подскажет что не так в коде? Подключение на макетке правильно ибо если было бы не правильно прошлые программы не работали бы.
сделано в CVAVR код и схему прилагаю, а так же проект+протеус.
Код программы:

Схема:

Архив с проектом и схемой в протеусе:
проект.rar
(65.41 KiB) Скачиваний: 237

Re: Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 10:20:34

Код:
if(m==0){

Лишний кусок кода.

Код:
unsigned char sek;


Попробуйте заменить на.

Код:
voliatile unsigned char sek;


Ваша программа, если работает в Протеусе, должна работат и в проце.
Возмозно в проце выставлена работа от внешнего кварца.

Re: Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 11:47:33

codenamehawk писал(а):Возмозно в проце выставлена работа от внешнего кварца.

Сделал как вы сказали, в протеусе работает на железе опять нет. Фьюзы стоял на внутренний кварц 8МГц если я не ошибаюсь. Вот скриншот как выставлены фьюз-биты

Re: Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 12:06:07

Поставь студию попроще, к примеру 4.19, файл .cof в отладчик.

Re: Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 12:56:12

Порт B то у Вас явно перегружен.

Re: Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 13:28:33

Vov123 писал(а):Поставь студию попроще, к примеру 4.19, файл .cof в отладчик.

а где взять этот файл и как туда запихать?
Z_h_e писал(а):Порт B то у Вас явно перегружен.

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

Re: Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 13:33:02

moonlight1 писал(а):а как его собственно разгрузить? на нем же только 2 анода сегментов висят и все...
А Вы посчитайте какой ток будет, если зажечь все сегменты. Аноды говорите... поставте биполярный NPN транзистор. База на порт, коллектор на + питания, эмиттер на анод.

Re: Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 13:47:16

Z_h_e писал(а):
moonlight1 писал(а):а как его собственно разгрузить? на нем же только 2 анода сегментов висят и все...
А Вы посчитайте какой ток будет, если зажечь все сегменты. Аноды говорите... поставте биполярный NPN транзистор. База на порт, коллектор на + питания, эмиттер на анод.

без этого вполне на другой программе работает.
вот в этой программе, счет от 0 до 999 по нажатию кнопки, все нормально работает на железе

схема

в реали к сожалению нет у меня транзистора нпн, но без него с другим кодом работает, а с тем что в 1м сообщении нет. не думаю что купив транзисторы заработает, но попытаться стоит ;)

Re: Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 13:55:14

Да я и не говорил что у Вас нули показывает из-за перегрузки порта.

Попробуйте функцию ind вызывать редко, например раз 3 сек и используйте в параметре не переменную, а некое число. Может увидите, что у Вас происходит и локализуете проблему.

Re: Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 13:55:56

Z_h_e писал(а):Да я и не говорил что у Вас нули показывает из-за перегрузки порта.

Попробуйте функцию ind вызывать редко, например раз 3 сек и используйте в параметре не переменную, а некое число. Может увидите, что у Вас происходит и локализуете проблему.

а) ну значит я не так понял. попробую спасибо
попробовал, вызывать реже, чет все равно тоже самое =\
ладно черт с ней, потом додумаю может быть почему не работает.

Re: Программа работает в proteus'e но на железе отказывается

Ср июл 27, 2016 17:29:25

Фьюзы стоял на внутренний кварц 8МГц
Где вы нашли контроллер с внутренним кварцем? Явно ведь не ATmega8, у нее встроенного кварца нет, только RC-генератор.
static flash unsigned char digit[] = {
~(0b00111111), // 0
Не самый удобный способ записи. Хотя в вашем примере на 999, эта инициализация реализована еще хуже.
PORTB.0=1;
PORTD=digit[des];
delay_ms(5);
В cvavr не надо делать ручное чтение из flash? В avr-gcc для этого pgm_read_byte() и т.п.
Можно попробовать увеличить задержку здесь.
ASSR= 0b00001000;
Форматирование ужасно. Какая религия мешает писать по-человечески? Запретите ее на форуме. ASSR = (1<<AS2);
Сам асинхронный таймер тактируется? Попробуйте помигать диодами из его прерывания или затактировать от системного таймера. Кстати, на схеме низкочастотного кварца нет.

Re: Программа работает в proteus'e но на железе отказывается

Чт июл 28, 2016 06:09:18

COKPOWEHEU писал(а):только RC-генератор.

я это и умел ввиду :oops:
Не самый удобный способ записи. Хотя в вашем примере на 999, эта инициализация реализована еще хуже.

как смог так сделал. не все же сразу должно быть хорошо :)
Сам асинхронный таймер тактируется? Попробуйте помигать диодами из его прерывания или затактировать от системного таймера. Кстати, на схеме низкочастотного кварца нет.

хорошо. спасибо

Re: Программа работает в proteus'e но на железе отказывается

Чт июл 28, 2016 07:42:10

Код:
#define SEG_PORT PORTD
#define SEG_A 0
#define SEG_B 1
...
#define SEG_F 5
#define SEG_G 6
PROGMEM const char num[]={
  ~(1<<SEG_A | 1<<SEG_B | 1<<SEG_C | 1<<SEG_D | 1<<SEG_E | 1<<SEG_F), //0
  ~(1<<SEG_B | 1<<SEG_C), //1
...
  ~(1<<SEG_A | 1<<SEG_B | 1<<SEG_C | 1<<SEG_D | 1<<SEG_E | 1<<SEG_F | 1<<SEG_G), //8
  ~(1<<SEG_A | 1<<SEG_B | 1<<SEG_C | 1<<SEG_D | 1<<SEG_F | 1<<SEG_G) //9
};
Такой способ позволяет легко менять выводы местами, плюс этот кусок можно таскать из кода в код. Ну и выглядит нагляднее, чем "магические числа".
как смог так сделал. не все же сразу должно быть хорошо :)
Когда я делаю динамическую индикацию, обычно завожу "видеобуфер" и отрисовываю его по таймеру.
Код:
#define DIG_PORT PORTB
#define DIG_MASK (1<<0 | 1<<1)
const char digits[2]={
  (1<<0),
  (1<<1)
};

volatile char video_buf[2];

//динамическая индикация
ISR(TIM0_OVF_vect){
  static unsigned char digit=0;
  DIG_PORT &=~DIG_MASK; //перед переключением обязательно надо погасить предыдущий разряд
  SEG_PORT = video_buf[ digit ];
  DIG_PORT |= digits[ digit ];
  digit++;
  if(digit > 1)digit = 0; //знаю, что можно обойтись инверсией младшего бита, но этот вариант проще масштабировать
}

//вывод целого числа (0-99)
void OutInt(unsigned char data){
  char dec;
  while(data > 10){
    dec++;
    data -= 10;
  }
  video_buf[1] = pgm_read_byte( &num[ dec ] );
  video_buf[0] = pgm_read_byte( &num[ data ] );
}
Примерно так. Писал из головы под avr-gcc, но суть должна быть понятна.

Re: Программа работает в proteus'e но на железе отказывается

Чт июл 28, 2016 13:30:51

COKPOWEHEU писал(а):легко менять выводы местами

т.е. не важно как будут подключены выводы к мк? круто если так.
все понял в чем соль, не надо считать по битам легко прикинуть как будет.

Когда я делаю динамическую индикацию, обычно завожу "видеобуфер" и отрисовываю его по таймеру.
Примерно так. Писал из головы под avr-gcc, но суть должна быть понятна.

подкинули вы мне пищу для размышлений, освобожусь от дел насущных обязательно буду пробовать

Re: Программа работает в proteus'e но на железе отказывается

Чт июл 28, 2016 14:55:01

Преимущество в том, что в пределах одного порта можно вешать сегменты на произвольные пины. Часто у контроллеров выводы одного порта сгруппированы рядом (к сожалению, не всегда, классическая ATmega8 примером), а сегменты у индикатора расположены в произвольном порядке (наверное, какая-то логика в их расположении есть, но я ее не увидел). Тогда для упрощения разводки платы можно поменять местами какие-нибудь выводы.
Несложно сделать и полностью произвольный доступ к каждому выводу, но на мой взгляд это проигрыш по скорости.
подкинули вы мне пищу для размышлений, освобожусь от дел насущных обязательно буду пробовать
Это радует

Re: Программа работает в proteus'e но на железе отказывается

Ср авг 08, 2018 20:58:00

Здравствуйте, коты, кошечки и котята!
Хочу поделиться некоторым опытом. Написал я программу для Атмеги8 на ассемблере. Программа не очень чтобы сложная, но для меня, как в некоторой степени начинающего пользователя АВРов, довольно сложная и запутанная. Отладил её в Протеусе. Работает отлично! Записал код в микруху, запустил на макетной платке. Не работает! Начал ковырять. Перечитал много тем на разных форумах о причинах неработы программы в железе. Сначала думал, что помехи по питанию. Поставил соответствующие кондёры. Безрезультатно. Потом начал ковырять фьюзы. Дело в том, что раньше когда-то я имел дело с АТ89S52, а там фьюзов нет. Перепробовал разные варианты. Безрезультатно. Думаю, пойду другим путём. Урезал программу до минимума и начал проверять её работу в железе, постепенно добавляя блоки. Вначале всё работало отлично, но после добавления одного из блоков стало происходить странное. Программа то работала, то не работала. Иногда при включении питания или сбросе работала несколько раз подряд, а иногда - по несколько раз подряд не работала. И ещё: если программа не отработала до конца, а я подавал сигнал сброса, то после этого сброса она переставала работать. Знатоки, вероятно, уже поняли причину такого поведения. А мне пришлось повозиться, прежде чем я понял причину, хотя тоже мог бы догадаться.
Теперь о том, как я искал причину.
В некоторых блоках программы поставил команды, которые выводили в свободный порт какое-то число, которое соответствовало порядку выполнения программы. Т. е., если в порту появляется это число, это значит, что программа зашла в своей работе в этот блок. По этому признаку можно определить, что происходит в программе. Но как определить, что это число появляется в порту, ведь программа выполняется довольно быстро? Для этого я использовал 2-канальный цифровой осциллограф в ждущем режиме. Один вход подсоединил на линию порта 0, от неё же брал синхронизацию. А второй вход подключал к остальным выводам порта. Зарисовывал графики. Получилось нечто вроде картины логического анализатора. Совместив графики и проанализировав их, я узнал, куда, в какие блоки заходит программа. Получилось, что программа не заходила в один блок, в который она должна была обязательно зайти. Проанализировав код, я предположил причину, по которой программа не заходит в этот блок. Устранив причину, я добился того, что программа заработала так, как надо!
В чём же была причина?
Причина очень проста. Дойдя до определённого момента, программа анализировала флаг (бит в регистре), который в начале программы должен был быть сброшенным, т. е. равняться 0. Зная, что после команды сброса, МК обнуляет все РОНы, я не позаботился его принудительно обнулить. Оказывается, что МК не обнуляет РОНы при сбросе и включении питания! Это для меня было новостью. МК, с которыми я ранее имел дело, обнуляли все РОНы при сбросе и включении питания. Оказывается, к Атмеге8 это правило не относится. А может быть, схема сброса у меня была не лучшего качества, хотя я перепробовал разные варианты, которые не дали желаемого результата.
Конечно, взрослые жирные коты, наверно, посмеются, что, мол, кот таких простых вещей не знает. Но молодым котятам может пригодиться опыт, который я приобрёл ценой нескольких дней ковыряния в коде программы, поиска схожей причины на форумах и тыкания деталек в макетку. И я буду рад, если мой пост кому-то сэкономит часы, а то и дни поиска неисправности.

Re: Программа работает в proteus'e но на железе отказывается

Ср авг 08, 2018 21:42:22

Инициализировать нужно всё, чем собираешься пользоваться. Это каждый программист знает. Даже если в даташите пишут, что при ресете регистр ввода-вывода инициализируется каким-либо значением, то это утверждение всегда лучше поставить под сомнение и проинициализировать регистр самостоятельно. У меня была забавная ситуация с ATmega128, когда USART работал не с той скоростью, а всё потому, что я поленился проинициализировать бит, задающий удвоение частоты, из-за того, что он мол по ресету сам устанавливается в нужное значение.

Re: Программа работает в proteus'e но на железе отказывается

Чт авг 09, 2018 09:33:00

B@R5uk писал(а):Даже если в даташите пишут, что при ресете регистр ввода-вывода инициализируется каким-либо значением, то это утверждение всегда лучше поставить под сомнение
Что за чушь?

Добавлено after 12 minutes 14 seconds:
Владимир-32 писал(а):Оказывается, что МК не обнуляет РОНы при сбросе и включении питания! Это для меня было новостью. МК, с которыми я ранее имел дело, обнуляли все РОНы при сбросе и включении питания. Оказывается, к Атмеге8 это правило не относится. А может быть, схема сброса у меня была не лучшего качества, хотя я перепробовал разные варианты, которые не дали желаемого результата.
А где написано что должны были сбрасываться?
На счет поиска ошибки + Вам, тут часто бывает так, код напишут - не работает, ничего не попробовав бегут сразу за помощью.

Re: Программа работает в proteus'e но на железе отказывается

Чт авг 09, 2018 09:34:41

Z_h_e, мне по чём знать? Спросите разработчиков и производителей. Может очетпятка в документе, ноль и единицу перепутали, а может баг при производстве был, не к той линии питания развели. Мне главное чтобы работало без излишнего мозгосношения, поэтому сомневаюсь во всём и не верю никому на слово.

Re: Программа работает в proteus'e но на железе отказывается

Чт авг 09, 2018 09:41:21

Если бы контроллер не инициализировал РВВ так как написано, он бы не работал в принципе.

Если Вам попался неисправный МК, то никакие "правила сделать на всякий случай которые все программисты знают" не помогут.
Если есть такой явный баг, он по-любому будет описан в erratа или в свежем ДШ.
Ответить