|
Проблема с ADC ATTINY461 |
|
|
|
Dec 24 2007, 18:13
|
Участник

Группа: Свой
Сообщений: 52
Регистрация: 30-11-05
Из: С-Пб
Пользователь №: 11 619

|
Столкнулся с тем, что часть программы, работавшая на M8, ATTINY26, m8535 отказывается работать на тани461, а именно п/п измерения фазы(полпериуда). При изучении выяснилось проблема кроется в работе АЦП. Проблема: Как оказалось, АЦП работает как хочет, хочет в середине фазы выдаст значение =0, или, при отсутствии сигнала может выдать большое значение(выше обычного шума) из-за чего происходит ошибка в показании прибора. но вышесказанное это вообще ничто, по сравнению с тем, что иногда (всегда по разному) за определенное количество ацп преабразований выдает их сумма равняется 0, что вообще не понятно. Во время работы ацп, прерывания запрещаются и сканирование каналов не происходит, на время тестов это отключено, таким образом измеряем только один канал с внешним опорником на 4.096в.
если кто нибудь встречался с данной проблеммой, то посоветуйте как ее решить. Условия работы и измерений: Еще, скорость АЦП никак не влияет, синал 100% во время измерений присутствеут, контролировалось по осцилографу, макс сигнал составлял в пике ~2.3 вольта.
|
|
|
|
|
Dec 25 2007, 12:46
|
Участник

Группа: Свой
Сообщений: 52
Регистрация: 30-11-05
Из: С-Пб
Пользователь №: 11 619

|
to GDI ерата молчит. там по идее проблемм не должно быть
to smk земли у всех общие.
to ArtemKAD все остальное питается от одного стабилизатора, напряжения на всех портах не выходит за 5в
|
|
|
|
|
Dec 25 2007, 16:58
|
Участник

Группа: Свой
Сообщений: 52
Регистрация: 30-11-05
Из: С-Пб
Пользователь №: 11 619

|
Результаты проверки: Программа заливалась в ATTINY26(откуда изначально и была взята) работает стабильно и без проблем, заливка происходила как с перекомпиляцией и настройкой под нее так и в тупую скомпилированная под ATTINY261 и ATTINY461 работала во всех 3х случаях стабильно. Таже программа без изменений заливалась в ATTINY461 начинала сходить с ума, что еще более загадочно, на другом компиляторе сделали только часть измерения с выводом в уарт(без изменения схемы) все работает вроде нормально. родилось предположение, что возможно компилятор, но я как то сомниваюсь, прога бы не смогла отработь даже одного цикла.
|
|
|
|
|
Dec 25 2007, 19:27
|
Участник

Группа: Validating
Сообщений: 64
Регистрация: 16-06-05
Пользователь №: 6 073

|
Цитата(__nik__ @ Dec 25 2007, 22:58)  Думаю, вам надо внимательно изучить этот документ: AVR504: Migrating from ATtiny26 to ATtiny261/461/861Перенос на другой контроллер обычно не ограничивается простой перекомпиляцией, что-то вы не учли.
|
|
|
|
|
Dec 25 2007, 21:36
|
Участник

Группа: Свой
Сообщений: 52
Регистрация: 30-11-05
Из: С-Пб
Пользователь №: 11 619

|
to AlexG Цитата часть программы, работавшая на M8, ATTINY26, m8535 часть программы, не обозначает что именно эту часть нужно исправлять, я извиняюсь, но иар не даст вам просто так перекомпилить программу TINY26 на TINY461, хотябы без малейшего изменения имени регистров, что как следствие несет за собой хотябы поверхностное чтение даташита. В указанном вами документе нет ничего путного кроме переименования регистров, указания на размер стека, и некоторого отличия регистров АЦП, которое в даташите и так описано намного лучше, там смотреть нечего. Разница в АЦП не используется, автотриггер мне не нужен, он придуман для медленно изменяющихся сигналов, тк переключение канала возможно только при не измеряющем АЦП (до его запуска) и после этого нужно делать 4 NOP иначе наизмеряет полный бред. повторяю, измеряется 1 канал, есть прерывание по которому данные передают на другую плату. товарищи, те которые всевремя пишут смотри даташит, такое ощущение что вы сами их не читаете, так что перестанте писать такую ахинею или цитируйте конкретное место, ссылка на сам документ на мой взгляд является отпиской. а теперь отвечаю на ваш вопрос. за 1 неделю уже перелазен в доль и поперек сайт атмела, поставлены науши поставщики, Компел и ЭФО, они наверно уже с содроганием слышат мой голос и представление моей фирмы, сюда я залез не из простого любопытства. появилось предположение что что то с контроллером прерываний не так, но это я проверю завтра...
|
|
|
|
|
Dec 27 2007, 17:37
|
Участник

Группа: Свой
Сообщений: 52
Регистрация: 30-11-05
Из: С-Пб
Пользователь №: 11 619

|
На данный момент обнаружил глюк иара, по какой причине выяснить не смог, пока что. Суть примерно такая, long Summ; unsigned int acvant; return (Summ/acvant*419.0/468.0); ошибка возникает при умножении, почему-то при умножении числа на константу на выходе получаем 0 глазам не верил когда смотрел на это, подставлял данные в софт дебугер, все правлильно считает. при дкбуге через dWare видел все тоже что описывал выше, единстевнное, один раз получилось сей глюк обойти простым переносом acvant в голбальные переменные, все исчезло и работало как положено в течении 2х часов, сегодня все теже глюки...
|
|
|
|
|
Dec 29 2007, 07:10
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(__nik__ @ Dec 27 2007, 20:37)  На данный момент обнаружил глюк иара, по какой причине выяснить не смог, пока что. Суть примерно такая, long Summ; unsigned int acvant; return (Summ/acvant*419.0/468.0); ошибка возникает при умножении, почему-то при умножении числа на константу на выходе получаем 0 глазам не верил когда смотрел на это, подставлял данные в софт дебугер, все правлильно считает. при дкбуге через dWare видел все тоже что описывал выше, единстевнное, один раз получилось сей глюк обойти простым переносом acvant в голбальные переменные, все исчезло и работало как положено в течении 2х часов, сегодня все теже глюки... чтобы что-то конкретное сказать нужна цитата из кода, а не примерный пересказ
|
|
|
|
|
Dec 29 2007, 21:43
|
Участник

Группа: Свой
Сообщений: 52
Регистрация: 30-11-05
Из: С-Пб
Пользователь №: 11 619

|
Место глюка нашел при помощи AVR Dragon, он оказался в умножении с точкой ( * 419.0) на что умножать не важно, результат всегда равен 0. Если убрать запятую, то считает верно но для меня недостоточно точно. Столкнулся еще с тем что не могу скорость АЦП переключить, это как то похоже это как то связано с иаром 4.21А. еще раз хочу обратить внимание что таже программа работает в тани26....
|
|
|
|
|
Dec 29 2007, 23:09
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(__nik__ @ Dec 30 2007, 01:43)  еще раз хочу обратить внимание что таже программа работает в тани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) прерывание в "нужном" месте б) модификация "нужной переменной" или появление "нужного значения" переменной. Всё это я к тому, что сама ошибка может находится совершенно не в том месте где вы её ищете, а проявляться в "давно вылизанной" части программы. И даже при внесении изменений в произвольное место менять своё поведение.
|
|
|
|
|
Dec 30 2007, 15:25
|
Участник

Группа: Свой
Сообщений: 52
Регистрация: 30-11-05
Из: С-Пб
Пользователь №: 11 619

|
Цитата(SasaVitebsk @ Dec 30 2007, 02:09)  Вы сами себе противоречите, уважаемый. Значит не та же программа. Если бы ошибка, которая у вас явно присутствует и которую вы вначале списали на камень, а потом на 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). пришлось исследования свернуть и заменить * на /, правда точность жутко упала почемуто.
|
|
|
|
|
Dec 30 2007, 16:06
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(__nik__ @ Dec 30 2007, 19:25)  извиняюсь, я пользуюсь PORTX_BitY=1; что интерпритируется как: SBI PORTX,Y и если вы будете использовать (X<<Y), то это облегчит жизнь компилятору и программу на пару байт так как будет использовать лишь одну мнемонику вместо 3х
поверьте, в голове я могу разобратся с многим, ибо 6 лет проработал без отладчиков и разбирался с проблеммани такими какие вам и не снились и по теории работы электроники быть просто не могут, не нужно судить о других по собственным знаниям. Если бы вы были внимательнее, то учитывая ваши 6 лет, вы бы заметили, что я специально применил PORTL, а не PORTA к примеру. Компилятор не сможет компильнуть SBI, так как для этого порта данная инструкция недопустима. Я, естественно, использую (X<<Y). А пример - есть пример. Я его максимально упростил для вас. Я имел ввиду саму проблему. А примеры использовал максимально доступные для понимания. Совершенно очевидно, что такая ошибка может возникать на любых портах в верхней части. Я пишу программы несколько больше вас, хотя и не претендую на то, что я "более сильный программист". Просто, учитывая что вы обратились за помощью, хотел помочь. И предложил один из вариантов возникновения ошибки. Посты ваши прочитал внимательно. Прочитайте их пожалуйста сами ещё раз. Они у вас оставляют желать лучшего по полноте описания и сыплют недосказанностью. С другой стороны объясните мне тупому, следующий момент. Представим что код скомпилированный компилятором ошибочен. (Вернее сказать вы получили не совсем то, что хотели получить). Так вот вопрос. Как ошибочный результирующий код может выдавать ошибку не каждый раз?Я пользуюсь IAR. Использую практически всегда максимальную оптимизацию по скорости. Пока не сталкивался с глюками, по вине компилятора. Очень многие вам сообщат то же самое. Хотя, врать не буду, по роду деятельности флоат практически не применяю.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|