7 / 7 / 0
Регистрация: 03.04.2015
Сообщений: 45
|
|||||||||||
1 | |||||||||||
Может кто сталкивался с таким? ATxmega256A3U04.03.2016, 23:10. Показов 2138. Ответов 20
Суть такая, есть некое устройство, где используется АЦП AD7795. АЦП настроено на биполярное преобразование и выдаёт значение результата преобразования как 32790 ( что является значением находящимся около нуля (т.е. максимальное отрицательное значение равно 0, измеренный НУЛЬ 32768, максимальное измеренное значение 65535). В результате, при пересчёте кода результата преобразования в напряжение на входе, контроллер зависает. Вот код по которому происходит преобразование:
Путём экспериментов, было найдено решение:
PS: сильно не пинайте, программирование железа изучаю сам, профильное образование совершенно другое и готов выслушать конструктивную критику. Спасибо.
0
|
04.03.2016, 23:10 | |
Ответы с готовыми решениями:
20
может кто сталкивался с таким ? Файл во вложении может содержать вирус? Кто-нибудь сталкивался с таким типом рассылки? Кто-то сталкивался с таким заданием? Кто-нибудь с таким сталкивался? Кто сталкивался с таким в drupal 7 ? |
Модератор
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
|
||||||
08.03.2016, 07:43 | 2 | |||||
попробуй вот так
все дело в том что нет аппаратной поддержки, все реализуется библиотеками от производителя а там возможны глюки, и для микроконтроллеров float все же ближе чем double
2
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
||||||
09.03.2016, 01:37 | 3 | |||||
Можно попробовать добавить явное приведение типа:
0
|
Модератор
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
|
||||||
09.03.2016, 06:37 | 4 | |||||
вот еще что подумал
а чему равно ? размерность? в каждом компиляторе это свое и если размерность 16 бит то будем иметь проблемы с приведением так как при 0xFFFF (65535) будем иметь -1 а не максимум 0х8000 будем иметь минимум(-32768) а не середину между 0x7FFF и 0x8000 разница не 1, а 65535 для начала сделай аргумент беззнаковым
0
|
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
|
|
09.03.2016, 17:24 | 5 |
сдается мне, вы просто получаете на "середину шкалы", а просто знаковое значение. 32790 - это может быть "-24". Попробуйте изменить объявление переменной на тип "signed int" (или signed short, здесь действительно зависит от компилятора и его настроек типов).
0
|
Модератор
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
|
|
09.03.2016, 17:53 | 6 |
signed допускается опускать int по умолчанию signed, в отличии от char который может быть unsigned/signed в зависимости от настроек
причем самое смешное? что на микроконтроллерах char чаще всего настроен unsigned а на больших компах signed
0
|
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
|
|
09.03.2016, 20:32 | 7 |
да я ж не против. У ТС данные объявлены как указатель на тип long, как известно 32-битный. Это значит, что его знак лежит в 31м бите, а не 15м, как все нормальные знаковые биты в этом случае.
Я открывал даташит на этот АЦП, но при беглом изучении не нашел описание выходных данных, но из тех АЦП, с которыми я сталкивался, знак был в 90% случаев. Поэтому, вопрос его использования весьма актуален.
0
|
Модератор
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
|
|
09.03.2016, 21:19 | 8 |
в том то и дело что неизвестно
стандарт гарантирует что char<=short<=int<=long о размерности ни слова, все на откуп компилятору,а про компилятор я у ТС не увидел можешь себе представить все эти типы 128 бит, по стандарту допускается вот тебе живой пример AVR и STM32 у одной int 16 у другой 32 бит вот посему я и предложил работать ему с беззнаковыми есть такой тип данных,не помню как называется, встречался со звуковыми АЦПухами все что от 0 до средины диапазона( допустим 0-0x8000) это отрицательные а все что выше положительные значения, а сам 0 это средина(0x8000), и перевод в дополнительный код (signed), приведет к еще большему геморою
0
|
7 / 7 / 0
Регистрация: 03.04.2015
Сообщений: 45
|
|
10.03.2016, 22:43 [ТС] | 9 |
Именно так и есть, По поводу явного приведения типов, такой вариант не сработал. ЗЫ: Среда Atmel Studio 7, С99.
0
|
Модератор
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
|
||||||
10.03.2016, 23:10 | 10 | |||||
так вот если используешь int (по умолчанию знаковый) и получаешь все что отрицательное у АЦПухи в переменной положительное и наоборот, тута старший бит знак означает 1 значит минус
вот так тебе нужно переводить
1
|
7 / 7 / 0
Регистрация: 03.04.2015
Сообщений: 45
|
|
11.03.2016, 00:44 [ТС] | 11 |
Я согласен, что int по умолчанию знаковый. где старший разряд, отвечает за знак. int (он же вроде как short int) занимает 2 байта памяти и меет значения от -32768 до 32367. Но я то использовал long int (ну или можно было использовать unsigned int от 0 до 65535), который занимает 4 байта и имеет диапазон от -2 147 483 648 до 2 147 483 647. Следовательно, от АЦП я при любом раскладе принимаю исключительно положительное число.
0
|
Модератор
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
|
|||||||||||
11.03.2016, 01:00 | 12 | ||||||||||
не факт
смотри вот мы имеем -1 в char и копируем его в int
и это правильно иначе при приведении из меньшего в больший числа бы волшебным образом менялись но в данной задаче это не приемлемо выход использовать беззнаковые, они то просто копируют бит в бит
1
|
7 / 7 / 0
Регистрация: 03.04.2015
Сообщений: 45
|
|
11.03.2016, 08:06 [ТС] | 13 |
Не знал про это, спасибо. Буду пробовать.
А ещё такой вопрос, можно ли как то получить доступ к глобальным переменным, не используя ключевого слова volatile при объявлении переменной?
0
|
Модератор
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
|
|||||||||||||||||||||
11.03.2016, 08:45 | 14 | ||||||||||||||||||||
берешь и вызываешь если переменная объявлена в другой единице трансляции (файл С) то нужно добавить слово extern чтобы компилятор её увидел
например так file1.c
слово volatile запрещает компилятору её оптимизировать например
так вот слово volatile запрещает ему такие вольности
0
|
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
|
|
11.03.2016, 09:54 | 15 |
вдобавок к сказанному еще хочу отметить, что вы передаете в функцию указатель на long, но не само число. Это значит, что если вы при вызове функции дадите указатель на переменную short, то функция вообще может сбеситься, т.к. вполне возможно после этой переменной память будет содержать еще данные, в данном случае являющиеся старшими разрядами переменной. То есть вы в этом случае должны передавать указательно только на тип long и более.
Что касается АЦП - то я в курсе глянул таки ДШ, принцип вы правильный указали. Но здесь немного не так (стр.25):
1
|
7 / 7 / 0
Регистрация: 03.04.2015
Сообщений: 45
|
||||||
11.03.2016, 15:23 [ТС] | 16 | |||||
переменная которая хранит данные от АЦП имеет тип тип long int, адрес которой я потом передаю в функцию по указателю.
0
|
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
|
|||||||||||
11.03.2016, 15:40 | 17 | ||||||||||
ну я понимаю, вроде бы не было замечено банальных ошибок. Просто 32битная арифметика даже цилочисленная довольно громоздкая в AVR. У нее ж даже команд деления нет, не то что float-сопроцессора. А вы ему постоянно double и long подсовываете. Я бы пересмотрел код в плане ухода от double и float, и работы в целочисленном поле, но, скажем, с умноженными на 1000 числами. Это заметно сэкономит процессорное время и убережет от ошибок.
ЗЫ: в каком-то проекте я слыхал, что тригонометрические вычисления (3d-координат, ничего заморского) в AVR занимали ~0,5c (!), хотя в выражениях там 3-4 строчки по 5-6 действий в каждой. Так что я бы сделал выражение
PS: только в моем варианте надо будет проследить насчет сдвига знака. Если он движется вместе со всеми байтами, то придется сдвиг втянуть внутрь выражения, дважды умножив adc и offs на множитель, сдвинуть их, а потом вычесть.
0
|
7 / 7 / 0
Регистрация: 03.04.2015
Сообщений: 45
|
|
11.03.2016, 17:11 [ТС] | 18 |
Т.е. для приёма данных от АЦП не обязательно при объявлении переменной использовать volatile, но если переменная участвует где-то в условии, то её надо обозвать volatile?
Добавлено через 1 час 25 минут Пока я приостановил это дело и вернусь к нему в ближайшее время. Большие типы данных были выбраны, с целью избежать нехватки места и избежать переполнения. Так сказать для первого приближения.
0
|
Модератор
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
|
|
11.03.2016, 19:06 | 19 |
а он движется, а на место его приходит опять он же( во завернул)
например число 10001000 (двоичное)надо сдвинуть на 2 вправо так вот для знакового результат сдвига будет 1110 0010 а для безнакового 0010 0010 в ассемблере различают сдвиг вправо арифметический( с копированием знакового бита) и логический( без копирования оного) при сдвиге влево оба сдвига ведут себя одинаково Добавлено через 54 минуты вот тут подробно про эту volatile http://we.easyelectronics.ru/S... atile.html
2
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
|
13.03.2016, 01:29 | 20 |
... Я где-то года два назад проводил исследование вопроса арифметики с плавающей точкой. К сожалению результатов не сохранилось, но вывод был следующим.
На контроллерах имеющих умножитель операции над float выполняются приблизительно с той же скоростью, как и над int32_t. Так что особых причин отказываться от float в пользу 4-х байтной целочисленной арифметики... На самом деле нет... А ошибок с целочисленной арифметикой наляпать можно преизрядно. И... Вообще говоря, 8МГц и 2Кб оперативки позволяют развернуть неслабую операционную систему... Такой комп на луну летал. А вы такты и байты считаете.
0
|
13.03.2016, 01:29 | |
13.03.2016, 01:29 | |
Помогаю со студенческими работами здесь
20
Друзья, я в шоке! Кто с таким сталкивался? Сокет 942. кто с таким сталкивался? Кто сталкивался с таким? Бьюсь уже три часа Кто сталкивался с фирмой DNS, и кто может сказать про эксплуатацию их ноутов сервис и прочее может кто сталкивался Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |