__nik__ 0 24 декабря, 2007 Опубликовано 24 декабря, 2007 · Жалоба Столкнулся с тем, что часть программы, работавшая на M8, ATTINY26, m8535 отказывается работать на тани461, а именно п/п измерения фазы(полпериуда). При изучении выяснилось проблема кроется в работе АЦП. Проблема: Как оказалось, АЦП работает как хочет, хочет в середине фазы выдаст значение =0, или, при отсутствии сигнала может выдать большое значение(выше обычного шума) из-за чего происходит ошибка в показании прибора. но вышесказанное это вообще ничто, по сравнению с тем, что иногда (всегда по разному) за определенное количество ацп преабразований выдает их сумма равняется 0, что вообще не понятно. Во время работы ацп, прерывания запрещаются и сканирование каналов не происходит, на время тестов это отключено, таким образом измеряем только один канал с внешним опорником на 4.096в. если кто нибудь встречался с данной проблеммой, то посоветуйте как ее решить. Условия работы и измерений: Еще, скорость АЦП никак не влияет, синал 100% во время измерений присутствеут, контролировалось по осцилографу, макс сигнал составлял в пике ~2.3 вольта. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GDI 0 25 декабря, 2007 Опубликовано 25 декабря, 2007 · Жалоба Эррата ничего на эту тему не говорит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smk 0 25 декабря, 2007 Опубликовано 25 декабря, 2007 · Жалоба Первое, что приходит на ум так это посмотреть как соединены земли ИОН, АЦП и источника сигнала. А что, например, будет если закороить вход (сигнал всегда = 0)? А на AREF конденсатор цеплять не пробовали? Попробуйте еще вход АЦП соединить с землей через резистор 10 мОм. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 69 25 декабря, 2007 Опубликовано 25 декабря, 2007 (изменено) · Жалоба А какие уровни сигналов на остальных ногах по отношению к напряжению питания? Изменено 25 декабря, 2007 пользователем ArtemKAD Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
__nik__ 0 25 декабря, 2007 Опубликовано 25 декабря, 2007 · Жалоба to GDI ерата молчит. там по идее проблемм не должно быть to smk земли у всех общие. to ArtemKAD все остальное питается от одного стабилизатора, напряжения на всех портах не выходит за 5в Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
__nik__ 0 25 декабря, 2007 Опубликовано 25 декабря, 2007 · Жалоба Результаты проверки: Программа заливалась в ATTINY26(откуда изначально и была взята) работает стабильно и без проблем, заливка происходила как с перекомпиляцией и настройкой под нее так и в тупую скомпилированная под ATTINY261 и ATTINY461 работала во всех 3х случаях стабильно. Таже программа без изменений заливалась в ATTINY461 начинала сходить с ума, что еще более загадочно, на другом компиляторе сделали только часть измерения с выводом в уарт(без изменения схемы) все работает вроде нормально. родилось предположение, что возможно компилятор, но я как то сомниваюсь, прога бы не смогла отработь даже одного цикла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexG_changed 0 25 декабря, 2007 Опубликовано 25 декабря, 2007 · Жалоба Думаю, вам надо внимательно изучить этот документ: AVR504: Migrating from ATtiny26 to ATtiny261/461/861 Перенос на другой контроллер обычно не ограничивается простой перекомпиляцией, что-то вы не учли. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
__nik__ 0 25 декабря, 2007 Опубликовано 25 декабря, 2007 · Жалоба to AlexG часть программы, работавшая на M8, ATTINY26, m8535 часть программы, не обозначает что именно эту часть нужно исправлять, я извиняюсь, но иар не даст вам просто так перекомпилить программу TINY26 на TINY461, хотябы без малейшего изменения имени регистров, что как следствие несет за собой хотябы поверхностное чтение даташита. В указанном вами документе нет ничего путного кроме переименования регистров, указания на размер стека, и некоторого отличия регистров АЦП, которое в даташите и так описано намного лучше, там смотреть нечего. Разница в АЦП не используется, автотриггер мне не нужен, он придуман для медленно изменяющихся сигналов, тк переключение канала возможно только при не измеряющем АЦП (до его запуска) и после этого нужно делать 4 NOP иначе наизмеряет полный бред. повторяю, измеряется 1 канал, есть прерывание по которому данные передают на другую плату. товарищи, те которые всевремя пишут смотри даташит, такое ощущение что вы сами их не читаете, так что перестанте писать такую ахинею или цитируйте конкретное место, ссылка на сам документ на мой взгляд является отпиской. а теперь отвечаю на ваш вопрос. за 1 неделю уже перелазен в доль и поперек сайт атмела, поставлены науши поставщики, Компел и ЭФО, они наверно уже с содроганием слышат мой голос и представление моей фирмы, сюда я залез не из простого любопытства. появилось предположение что что то с контроллером прерываний не так, но это я проверю завтра... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
__nik__ 0 27 декабря, 2007 Опубликовано 27 декабря, 2007 · Жалоба На данный момент обнаружил глюк иара, по какой причине выяснить не смог, пока что. Суть примерно такая, long Summ; unsigned int acvant; return (Summ/acvant*419.0/468.0); ошибка возникает при умножении, почему-то при умножении числа на константу на выходе получаем 0 глазам не верил когда смотрел на это, подставлял данные в софт дебугер, все правлильно считает. при дкбуге через dWare видел все тоже что описывал выше, единстевнное, один раз получилось сей глюк обойти простым переносом acvant в голбальные переменные, все исчезло и работало как положено в течении 2х часов, сегодня все теже глюки... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mdmitry 0 28 декабря, 2007 Опубликовано 28 декабря, 2007 · Жалоба Суть примерно такая, long Summ; unsigned int acvant; return (Summ/acvant*419.0/468.0); ошибка возникает при умножении, почему-то при умножении числа на константу на выходе получаем 0 глазам не верил когда смотрел на это, подставлял данные в софт дебугер, все правлильно return какого типа? Подумайте, пожалуйста, о преобразовании типов при расчете. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 29 декабря, 2007 Опубликовано 29 декабря, 2007 · Жалоба На данный момент обнаружил глюк иара, по какой причине выяснить не смог, пока что. Суть примерно такая, long Summ; unsigned int acvant; return (Summ/acvant*419.0/468.0); ошибка возникает при умножении, почему-то при умножении числа на константу на выходе получаем 0 глазам не верил когда смотрел на это, подставлял данные в софт дебугер, все правлильно считает. при дкбуге через dWare видел все тоже что описывал выше, единстевнное, один раз получилось сей глюк обойти простым переносом acvant в голбальные переменные, все исчезло и работало как положено в течении 2х часов, сегодня все теже глюки... чтобы что-то конкретное сказать нужна цитата из кода, а не примерный пересказ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
__nik__ 0 29 декабря, 2007 Опубликовано 29 декабря, 2007 · Жалоба Место глюка нашел при помощи AVR Dragon, он оказался в умножении с точкой ( * 419.0) на что умножать не важно, результат всегда равен 0. Если убрать запятую, то считает верно но для меня недостоточно точно. Столкнулся еще с тем что не могу скорость АЦП переключить, это как то похоже это как то связано с иаром 4.21А. еще раз хочу обратить внимание что таже программа работает в тани26.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 29 декабря, 2007 Опубликовано 29 декабря, 2007 · Жалоба еще раз хочу обратить внимание что таже программа работает в тани26.... Вы сами себе противоречите, уважаемый. Значит не та же программа. Если бы ошибка, которая у вас явно присутствует и которую вы вначале списали на камень, а потом на IAR, происходила при обращении к оборудованию, то я бы поверил. Возможно файл объявлений ошибочный или даже проблемы с оборудованием каким то. Но ошибка, возникающая при умножении с использованием плавающей запятой (то есть данный кусок раскладывается в 2 десятка простых комманд) - не поверю. Настораживает также упоминание вами прерывания и "случайности" ошибки. Всё это наводит на мысль, что вы столкнулись с достаточно сложной, но весьма распространенной ошибкой при написании прерывания. Для ясности приведу два примера. 1) Пример с регистрами I/O В голове находится следующая строчка PORTL |= 1; Компильнётся примерно в следующее lds r16,portl ori r16,1 sts portl,r16 В прерывании следующая строчка PORTL |= 2; А теперь посмотрите внимательно. Если прерывание придёт во время исполнения команды ori при этом бит D1 порта L в это время будет равен 0, то произойдёт следующее. В прерывании бит 1 будет установлен в 1, но сразу по выходу из прерывания он опять сбросится в 0. И вы будете в непонятках так как в голове вы с этим битом не работаете. 2) Пример с переменными В голове находится следующие строчки volatile uint16_t i,j; if(i<j)... Представим себе что i=0x1f, а j=0x23. Очевидно, что условие должно выполниться. Учитывая что переменные 16 бит, то сама операция пройдёт в 2 этапа В прерывании следующая строчка i++; Представим, что прерывание произойдёт м/у сравнениями младших и старших байтов. Тогда первое сравнение будет F c 3. Потом идёт прерывание где i становится 0x20 и идёт сравнение 2 с 1. Результат - условие выполняться не будет. У вас возникнет ошибка. Примечание: IAR пытается бороться с такими ситуациями путём предварительной пересылки регистровой пары, а потом уж самой операции. Но это я так для примера привёл. Так как если операнд 4 байта, то и это уже не спасает от потенциальной ошибки. Проявляться такая ошибка будет крайне нерегулярно, так как необходимо: a) прерывание в "нужном" месте б) модификация "нужной переменной" или появление "нужного значения" переменной. Всё это я к тому, что сама ошибка может находится совершенно не в том месте где вы её ищете, а проявляться в "давно вылизанной" части программы. И даже при внесении изменений в произвольное место менять своё поведение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
__nik__ 0 30 декабря, 2007 Опубликовано 30 декабря, 2007 · Жалоба Вы сами себе противоречите, уважаемый. Значит не та же программа. Если бы ошибка, которая у вас явно присутствует и которую вы вначале списали на камень, а потом на IAR, происходила при обращении к оборудованию, то я бы поверил. Возможно файл объявлений ошибочный или даже проблемы с оборудованием каким то. Но ошибка, возникающая при умножении с использованием плавающей запятой (то есть данный кусок раскладывается в 2 десятка простых комманд) - не поверю. Настораживает также упоминание вами прерывания и "случайности" ошибки. Всё это наводит на мысль, что вы столкнулись с достаточно сложной, но весьма распространенной ошибкой при написании прерывания. Уважаемый, я кажется раз 5 уже писал что прерывания запрещены, да и происходят они ~7 раз в секунду, только в нужныж мне местах, и только для передачи информации на второй процессор. Для ясности приведу два примера. 1) Пример с регистрами I/O В голове находится следующая строчка PORTL |= 1; Компильнётся примерно в следующее lds r16,portl ori r16,1 sts portl,r16 извиняюсь, я пользуюсь PORTX_BitY=1; что интерпритируется как: SBI PORTX,Y и если вы будете использовать (X<<Y), то это облегчит жизнь компилятору и программу на пару байт так как будет использовать лишь одну мнемонику вместо 3х В прерывании следующая строчка PORTL |= 2; А теперь посмотрите внимательно. Если прерывание придёт во время исполнения команды ori при этом бит D1 порта L в это время будет равен 0, то произойдёт следующее. В прерывании бит 1 будет установлен в 1, но сразу по выходу из прерывания он опять сбросится в 0. И вы будете в непонятках так как в голове вы с этим битом не работаете. поверьте, в голове я могу разобратся с многим, ибо 6 лет проработал без отладчиков и разбирался с проблеммани такими какие вам и не снились и по теории работы электроники быть просто не могут, не нужно судить о других по собственным знаниям. 2) Пример с переменными В голове находится следующие строчки volatile uint16_t i,j; if(i<j)... Представим себе что i=0x1f, а j=0x23. Очевидно, что условие должно выполниться. Учитывая что переменные 16 бит, то сама операция пройдёт в 2 этапа В прерывании следующая строчка i++; Представим, что прерывание произойдёт м/у сравнениями младших и старших байтов. Тогда первое сравнение будет F c 3. Потом идёт прерывание где i становится 0x20 и идёт сравнение 2 с 1. Результат - условие выполняться не будет. У вас возникнет ошибка. согласен, в таком случае произойдет ошибка, но на этот случай да и для нормальной работы прибора есть некая задержка при обнаружении единичной ошибки, иными словами, никакой реакции не произойдет в случае если эта ошибка будет одна. Примечание: IAR пытается бороться с такими ситуациями путём предварительной пересылки регистровой пары, а потом уж самой операции. Но это я так для примера привёл. Так как если операнд 4 байта, то и это уже не спасает от потенциальной ошибки. Проявляться такая ошибка будет крайне нерегулярно, так как необходимо: a) прерывание в "нужном" месте б) модификация "нужной переменной" или появление "нужного значения" переменной. ИАР может и пытается, но при максимальном уровне оптимизации он на все плюет, и если вы посмотрите на код который он сгенерил, то обнаружите что половина того что вы написали он попросту либо соединил в одну строчку, либо удалилю Вот такой он загадочный, и чтобы писать на С а не на АСМ время зависимые подпрограммы, приходится его порядком поубеждать чтобы он не своевольничал и не удалял то что его не просят, и тем более не уменьшал разрядность в математике, именно для этого и вводилось чтобы он использовал математику с точкой принудительно, не знаю это его ошибка или нет, но при float = Long/conct он не использует математику с точкой при максимальной оптимизации. Всё это я к тому, что сама ошибка может находится совершенно не в том месте где вы её ищете, а проявляться в "давно вылизанной" части программы. И даже при внесении изменений в произвольное место менять своё поведение. Вот с этим я пожалуй пока не соглашусь, и даже думаю выложу либо скрины либо видео с экрана того что происходит, но вот только как дракон нам по гарантии поменяют. Ошибка именно в * , я думаю не в самом умножении а гдето при пересылки данных, потому как начальные действия делает верно. Утверждения на данный момент были сделаны при помощи АВР Дракон, правда он отработал всего сутки потом начал сажать питание испытуемой платы с нагревом 8ногой микрухи рядом с Мега128 на ней написано AHT). пришлось исследования свернуть и заменить * на /, правда точность жутко упала почемуто. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 30 декабря, 2007 Опубликовано 30 декабря, 2007 · Жалоба извиняюсь, я пользуюсь PORTX_BitY=1; что интерпритируется как: SBI PORTX,Y и если вы будете использовать (X<<Y), то это облегчит жизнь компилятору и программу на пару байт так как будет использовать лишь одну мнемонику вместо 3х поверьте, в голове я могу разобратся с многим, ибо 6 лет проработал без отладчиков и разбирался с проблеммани такими какие вам и не снились и по теории работы электроники быть просто не могут, не нужно судить о других по собственным знаниям. Если бы вы были внимательнее, то учитывая ваши 6 лет, вы бы заметили, что я специально применил PORTL, а не PORTA к примеру. Компилятор не сможет компильнуть SBI, так как для этого порта данная инструкция недопустима. Я, естественно, использую (X<<Y). А пример - есть пример. Я его максимально упростил для вас. Я имел ввиду саму проблему. А примеры использовал максимально доступные для понимания. Совершенно очевидно, что такая ошибка может возникать на любых портах в верхней части. Я пишу программы несколько больше вас, хотя и не претендую на то, что я "более сильный программист". Просто, учитывая что вы обратились за помощью, хотел помочь. И предложил один из вариантов возникновения ошибки. Посты ваши прочитал внимательно. Прочитайте их пожалуйста сами ещё раз. Они у вас оставляют желать лучшего по полноте описания и сыплют недосказанностью. С другой стороны объясните мне тупому, следующий момент. Представим что код скомпилированный компилятором ошибочен. (Вернее сказать вы получили не совсем то, что хотели получить). Так вот вопрос. Как ошибочный результирующий код может выдавать ошибку не каждый раз? Я пользуюсь IAR. Использую практически всегда максимальную оптимизацию по скорости. Пока не сталкивался с глюками, по вине компилятора. Очень многие вам сообщат то же самое. Хотя, врать не буду, по роду деятельности флоат практически не применяю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться