LINUX.ORG.RU

Зацикливается функция

 , ,


0

1

Микроконтроллер atmega48, можете думать что хотите по этому поводу, нравится мне AVR и все тут, внутренний тактовый генератор настроен на 1МГц.

Есть такой код.

#define F_CPU 1000000UL  // 1 MHz
#include <avr/io.h>
#include <util/delay.h>

void setup();

int main(void)            
{
    setup();
       
    while(1);

    return 0;
}

void setup()
{
    DDRB = 0x0;
    DDRC = 0x0;
    DDRD = 0x0;
    
    DDRC |= _BV(PC1);  // led pin as outpiut
    
    // left motor
    DDRB |= _BV(PB7);   // enable pin
    DDRD |= _BV(PD5);   // pin 1
    DDRD |= _BV(PD6);   // pin 2
    
    // right motor
    DDRB |= _BV(PB6);   // enable pin
    DDRB |= _BV(PB1);   // pin 1
    DDRB |= _BV(PB2);   // pin 2
    
    PORTC |= _BV(PC1);
    _delay_ms(100);
    PORTC &= ~_BV(PC1);
    _delay_ms(100);
}

Он должен настроить выходы контроллера, мигнуть светодиодом на выходе PC1 и уйти в бесконечный цикл, но не тут то было. Он начинает мигать светодиодом бесконечно, как будто setup() вызывается в в бесконечном цикле. Чяднт?.

★★★★

Последнее исправление: cetjs2 (всего исправлений: 1)

Ответ на: комментарий от Zubok

Подтянул ресет, сделал кнопочку сброса для приличия. Зацикливается по-прежнему.

WRG ★★★★
() автор топика
Ответ на: комментарий от WRG

Подтянул ресет, сделал кнопочку сброса для приличия. Зацикливается по-прежнему.

Так, да?

Vcc ---- [ 10 k ]------+---------o RESET
                       |
                       |
                       SW
                       |
                      ---

1. А осциллограф есть? Питание не контролируешь? Не просаживается ли питание в моменты зацикливания? Это могут быть очень короткие импульсы, если большая развертка, то можно не увидеть.

2. А с чего запитываешь? Как у тебя питание девайса устроено? Напрямую стабилизированным или у тебя на плате стабилизатор?

3. А как питание зафильтровано? Электролит на питание поставь побольше и ножки питания микроконтроллера емкостью 0.1 uF - 0.22 uF, где-то так (керамика) как можно ближе к Vcc и GND микроконтроллера, прямо напаяй на них. Если же электролит есть, то замени. Вдруг у него утечка большая. Просто у меня есть подозрения, что у тебя по питанию что-то.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Да, подключил именно так.

1) Нет, только мечтаю о нем.

2) Запитываю с свинцового аккума 6В 3.5Ач. На плате, стабилизатор 7805 (да, знаю, что не low drop, что уж есть) для питания логики, на моторы идет напрямую 6В.

3) Сразу после 7805 стоит кондер 25V 1000uF, старый, выпаял с древнего телека, на вид целый, не вздутый.

Попробовать заменить электролит?

WRG ★★★★
() автор топика
Ответ на: комментарий от WRG

Насколько помню, для 7805, по крайней мере для его советского варианта KР142EH5, минимальное входное напряжение 7.5 Вольт. Банально может не хватить напруги.

Infra_HDC ★★★★★
()
Ответ на: комментарий от WRG

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

WRG ★★★★
() автор топика
Ответ на: комментарий от WRG

2) Запитываю с свинцового аккума 6В 3.5Ач. На плате, стабилизатор 7805 (да, знаю, что не low drop, что уж есть) для питания логики, на моторы идет напрямую 6В.

6 В маловато, конечно. Есть риск получить не то напряжение. Это близко к просадке. Там минимум 1.5 В нужно. У тебя по реальным измерениям так и есть, но все равно есть риск. И ты не сказал, у тебя питание зафильтровано 0.1 uF? Без них есть риск (1) самовозбуда 7805, (2) влияние высокочастотных помех на контроллер. Высокочастотные помехи на питании давить надо не электролитами — электролиты имеют ограничение по полосе.

3) Сразу после 7805 стоит кондер 25V 1000uF, старый, выпаял с древнего телека, на вид целый, не вздутый.

Невздутость не гарантия, что у него нет утечки. А питание программатора откуда берется?

Zubok ★★★★★
()
Ответ на: комментарий от WRG

Померял, на выходе 4.92В. Ну и заряженный аккумулятор выдаёт 6.55В.

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

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 3)
Ответ на: комментарий от WRG

0.1 uF нету, попробую впаяю. Но вроде ни разу с таким не сталкивался, что-то новое.

Ну, необязательно 0.1 uF. До 1 uF есть какие? Два впаяй. Один непосредственно на выход 7805 на землю, а другой - на ножки питания микроконтроллера. Еще можно на питание L293D подпаять (Vcc — нога 16 вроде).

UPD. Ты думаешь, их просто так ставят? http://brittonkerin.com/annotateduino/arduino-uno-schematic.png (См. конденсаторы PC1, PC2, C1, C2, C4, C6, C7).

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 4)

Oзнакомься с регистром MCUSR. Анализируя его биты PORF, BORF, EXTRF, WDTF, ты сможешь определить источник сброса. Если у тебя всё-таки включён WDT, ты увидишь WDTF=1. Аналогично, если у тебя помехи по питанию, будет или BORF=1, или даже EXTRF=1

qbe
()
Ответ на: комментарий от WRG

0.1 uF нету, попробую впаяю. Но вроде ни разу с таким не сталкивался, что-то новое.

И имей в виду, что 6В - мало для 7805. Найди дома адаптер 9В или 12В, с него запитай. Тебе могут и конденсаторы не помочь.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Если конденсаторы с малым суммарным ESR, и если BOD настроен правильно, контроллер будет вполне нормально работать и от нестабилизированного источника. Mega48V вон вполне способна и от 1.8В работать. Главное - чтобы напряжение не плясало.

qbe
()
Последнее исправление: qbe (всего исправлений: 1)
Ответ на: комментарий от qbe

Главное - чтобы напряжение не плясало.

Так там у него маленький перепад между 6В входными и 5В выходными.

https://www.fairchildsemi.com/datasheets/LM/LM7805.pdf

На стр. 17, Fig 3 видим, что при разнице 1 В катастрофически падает выходной ток (пиковый!), который может обеспечить стабилизатор. Он может быть настолько маленьким, что простое включение чего-то внешнего может дать просадку по всему питанию в ноль практически.

и если BOD настроен правильно

Отключен вроде совсем. С этого вроде и начали разбирательства. Выше он свои fuse повесил.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Zubok

На стр. 17, Fig 3 видим, что при разнице 1 В катастрофически падает выходной ток (пиковый!), который может обеспечить стабилизатор. Он может быть настолько маленьким, что простое включение чего-то внешнего может дать просадку по всему питанию в ноль практически.

Этот график надо читать иначе. Он описывает пиковые токи, при которых выполняется условие просадки выходного напряжения не более 0.1В.

А в другом даташите http://www.hep.upenn.edu/SNO/daq/parts/lm7815.pdf есть более интересная картинка на стр.3 - Dropout Charactericstics

По ней видно, как именно ведёт себя 7805 вне участка стабилизации. Почти как пара p-n переходов и резистор. Подобное поведение легко объясняется схемотехникой выходного каскада (см схему на первой странице).

qbe
()
Ответ на: комментарий от WRG

А еще сегодня утром у меня накрылся импульсный БП и выдал не знаю сколько вольт (но точно больше 20В) на платку с контроллером. Я быстро это заметил и всё отрубил, но фиг знает, может успел чего нибудь повредить.

На вход стабилизатора 7805 просадил 20В или на ноги контроллера непосредственно? Если на стабилизатор, то ничего ему от 20В не будет. Контроллер же, скорее всего, вылетел бы сразу напрочь. У него 6В максимально допустимое значение. У меня сомнения, что он бы вообще заработал после этого. «быстро это заметил» - это за сколько сообразил?

Zubok ★★★★★
()
Ответ на: комментарий от qbe

В даташите Fairchild просто графика соответсвующего нет, поэтому только этот смотрел. Но и с ним понятно, что 6В не годится.

В общем, при 6В уже нет 5В на выходе, 4.5В сразу без нагрузки. Однако это вряд ли бы повлияло на сброс контроллера. Только если BOD включен и сконфигурирован на 4.3В. Но он вроде отключен, если нет никакой ошибки.

WDT вряд ли, так как у него есть код (Зацикливается функция (комментарий)), который не зацикливается. Фьюзы он не менял. Значит, WDT выключен. Иначе бы циклило все равно. Поэтому остается либо внешний Reset, либо просадка питания ниже порога со срывом внутреннего тактового генератора, либо BOD.

Внешний Reset раньше висел в воздухе, теперь он его подтянул. Все равно циклит.

Zubok ★★★★★
()
Ответ на: комментарий от WRG

Померял, на выходе 4.92В. Ну и заряженный аккумулятор выдаёт 6.55В.

Если у тебя нет другого источника, кроме аккумулятора, то при таком напряжении 6.55В можно включить аккумулятор через два диода последовательно (это 6.55-0.7-0.7), исключив пока 7805. Главное только, чтобы по току потребляемому они проходили. Если ты там моторы пока влючать не будешь, то потребление микроконтроллера, драйверов, светодиод не шибко большое. Если есть диоды помощнее, то возьми их. Не знаю, какие у тебя в наличии. Перед подсоединением проконтролируй получившееся напряжение мультиметром и пробуй.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Zubok

Если у тебя нет другого источника, кроме аккумулятора,

Или навесь батарейку 1.5В последовательно. Еще можно с компа взять питание. Как 5В, так и 12В. С БП или USB. Вариантов много.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Zubok

Рабочий код от проблемного там отличается тем, что ТС не трогал остальные пины контроллера.

Очень похоже, что у ТСа просто не подаётся нормально питание на микроконтроллер, питается контроллер по пинам, пока они в состоянии входов. Как только выполнена запись в DDR, пины переходят в лог. 0, и контроллер сбрасывается.

WRG попробуй посмотреть напряжение питания непосредственно на пине VCC микроконтроллера. Также попробуй вынутый из платы микроконтроллер прозвонить мультиметром в режиме проверки диодов. Прозванивать между лог. пинами и VCC.

qbe
()
Последнее исправление: qbe (всего исправлений: 1)
Ответ на: комментарий от qbe

Рабочий код от проблемного там отличается тем, что ТС не трогал остальные пины контроллера.

имеется ввиду, что проинициализирован только пин светодиода

qbe
()
Ответ на: комментарий от qbe

Вот мне тоже самое показалось. Может быть, что и ток в светодиод является решающим, когда он после его загорания сбрасывается. Но выглядит очень странновато. Вот еще говорит, что atmega328 без зависаний отрабатывает. Но это может быть работа на самом пороге. Чуть порог для 328 перейдет и тоже будет зацикливаться (может быть, конечно). У него фильтрации толком никакой и RESET висел. Поэтому до устранения всего этого и поднятия напруги на 7805 сказать ничего нельзя. Вот когда все исправит и будет виснуть, то... в общем, подождем.

И логично, да, глянуть программно причину сброса в MCUSR. Только у него ничего, видимо, больше не подключено и надо чем-то там опять пытаться мигать, чтобы показать, что произошло, а у него циклит чего-то.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Я предполагаю, что здесь вообще пин Vcc оторван, и имеет место паразитное питание.

qbe
()
Ответ на: комментарий от WRG

прошивка

Так, слушай! Я тут сел и еще раз проанализировал твой код. Вернее, то, что сгенерировал компилятор. И внезапно мне показалось странным, что компилятор вставляет rjmp .+0. Вроде бы ничего странного: это по сути 'nop', то есть переход на следующую инструкцию. Зачем он в коде - это вопрос. Допустим, что причуда компилятора, холостая инструкция. У меня появилось подозрение, что именно на этой инструкции происходит проблема.

000000c0 <setup>:
  c0:  	14 b8       	out	0x04, r1	; 4
  c2:	17 b8       	out	0x07, r1	; 7
  c4:	1a b8       	out	0x0a, r1	; 10
  c6:	39 9a       	sbi	0x07, 1	; 7
  c8:	3a 9a       	sbi	0x07, 2	; 7
  ca: 	82 e0       	ldi	r24, 0x02	; 2
  cc:	90 e0       	ldi	r25, 0x00	; 0
  ce:	16 d0       	rcall	.+44     	; 0xfc <beep>
  d0:	83 e0       	ldi	r24, 0x03	; 3
  d2:	90 e0       	ldi	r25, 0x00	; 0
  d4:	00 c0       	rjmp	.+0      	; 0xd6 
                        ^^^^^^^^^^^^
                  beep уже отработал, а flash_led уже не будет.
<flash_led>

000000d6 <flash_led>:
  d6:	00 97       	sbiw	r24, 0x00	; 0
  d8:	81 f0       	breq	.+32     	; 0xfa <flash_led+0x24

Полез я в гугл, решив на всякий случай проверить эту гипотезу, не сталкивался ли кто, и нахожу это:

http://www.avrfreaks.net/forum/strange-problem-generated-code-rjmp-0

Если внимательно почитаешь, то у человека эта «странная» инструкция вызывает проблемы. Он отметил (вот тут), что если изменить код, чтобы эта инструкция не генерировалась, то у него все начинает работать нормально.

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

http://www.avrfreaks.net/comment/296941#comment-296941

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

UPD: Попробуй разные опции оптимизации и проконтролируй в коде, всегда ли эта инструкция появляется.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 3)
Ответ на: комментарий от Zubok

У меня ощущение, что кристалл вместо перехода на следующую команду, как это и должен делать rjmp .+0, переходит на нулевой адрес, то есть как раз вектор reset.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Выглядит интересно, ни за что бы не подумал. Попробую сегодня вечероком.

А еще на правах оффтопика - подскажите low drop линейные стабилизаторы на 5в, и чтоб в ТО-220 или ТО-92. Ток ну пусть 0.5 ампера или больше. Всё таки с питанием тоже проблему надо решать.

WRG ★★★★
() автор топика
Ответ на: комментарий от WRG

Выглядит интересно, ни за что бы не подумал. Попробую сегодня вечероком.

Если хоть какая-то оптимизация используется, то это rjmp может не уйти. Надо еще конкретные флаги выключить попробовать. Например, какие-то из этих опций gcc можно для начала:

avr-gcc -O$(OPTIMIZATION) -fno-inline-functions-called-once -fno-inline-small-functions -fno-indirect-inlining -fno-partial-inlining -fno-inline-functions ...

Ну и др.

А еще на правах оффтопика - подскажите low drop линейные стабилизаторы на 5в, и чтоб в ТО-220 или ТО-92. Ток ну пусть 0.5 ампера или больше. Всё таки с питанием тоже проблему надо решать.

Слушай, их море! Открой любого производителя: onsemi, linear, fairchild, st. Там фильтры по параметрам: и напряжение, и ток, и корпус. Выбери тот, который есть в ближайшем магазине.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 4)
Ответ на: комментарий от Zubok

Очень интересно... Сегодня, если руки дойдут, попробую эту ситуацию смоделировать на atmega328. К сожалению, 48 сейчас под руками нет для экспериментов

qbe
()
Ответ на: комментарий от qbe

Мне кажется, что моделирование покажет, что все ок. Человек по ссылке на английском сказал, что он на atmega1280 и atmega2560 прогнал: на одном работает, на другом - нет. Код, который виснет, одинаков в обоих случаях. Убирает этот rjmp и код на проблемном кристалле работает. Он посчитал, что кристалл глючный. Судя по тому, что я поискал, ситуация очень редкая и нигде больше не встретилась, но уж очень похоже. Вдруг какая партия глюкавая была?

Просто я ничем больше не могу объяснить ситуацию пока. И то, что у него на atmega328 работает все, а там код такой же. Этот rjmp, похоже, артефакт от инлайна функций. Я вот думаю, что если инлайн отключить, то rjmp может исчезнуть.

Если кристалл глючный, то это, конечно, на выброс. Или какое-нибудь единичное устройство сделать, но без этого rjmp. Подождем, что скажет ТС.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Zubok

Я вот больше склоняюсь к поврежденному кристаллу, потому что 20В секунды на 3 все таки. Ток не знаю какой был. Я сравнил lst файлы для 328 и 48 diff'ом, они одинаковые один в один. Сегодня за стабилизаторами в магазин поеду.

WRG ★★★★
() автор топика
Последнее исправление: WRG (всего исправлений: 1)
Ответ на: комментарий от WRG

Ну все равно проверь. Интересно же. ТЫ не пробовал с опциями компилятора, что выше? Но после компиляции лучше просмотреть глазами файл *.lst.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Ну раз подозрение появилось, надо и себя обезопасить в текущих проектах ;)

48-ю смогу пощупать только после праздников.

qbe
()
Ответ на: комментарий от WRG

Если уж в магазин поедешь, возьми ещё хотя-бы одну мегу48, чтобы наверняка исключить вариант с поджаренным кристаллом.

Да, и укажи дату производства микросхемы

qbe
()
Ответ на: комментарий от qbe

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

А дату выпуска как узнать?

WRG ★★★★
() автор топика
Ответ на: комментарий от WRG

Партия 1106А

Сейчас попробую разные уровни оптимизация. А если прямо в lst Файле убрать rjmp, и попробовать? Или он там нужен обязательно?

WRG ★★★★
() автор топика
Ответ на: комментарий от Zubok

Попробовал разные уровни оптимизации, код взял из моего первого поста. Код с O1, O2 и Os получается абсолютно одинаковый, и он циклится. С O0 бинарник получается огромный, и он просто включает светодиод. Не мигает, а просто включает, не знаю уж что там дальше происходит.

WRG ★★★★
() автор топика
Ответ на: комментарий от WRG

Код с O1, O2 и Os получается абсолютно одинаковый, и он циклится.

Попробуй с опциями, что выше по отключению inline. Любая оптимизация включает inline.

Zubok ★★★★★
()
6 февраля 2015 г.
Ответ на: комментарий от Zubok

Подниму забытую тему. Появилось время, откопал другую платку с такой же m48, купленной в один день с проблемной, партия такая же, 1106А. Благо не запаяна намертво а стоит в панельке, благополучно извлечена из другой платы, установлена в проблемную и прошита проблемным кодом. Проблемы с зацикливанием на ней нет, как и на m328. Видимо все же кристалл поврежден после оказии с импульсным БП.

WRG ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.