реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Преобразование кода 24 битного ацп к виду напряжения
messenger
сообщение Dec 31 2015, 14:32
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



Преобразую код 24 битного ацп к виду напряжения. Т.к. переменная 32 битная сделал вот так.

cod_acp=0;

T3= (acp_MSB & 0b10000000)>>7; //выделим знак то есть Z0000000
if (T3==1)
{
cod_acp=0b00000000000000000000000011111111;
}

cod_acp = (cod_acp<<8) ^ acp_MSB ; // 00000000 00000000 Z00000000 хххххххх
cod_acp = (cod_acp<<8) ^ acp_Mid_Byte; // и так далее
cod_acp = (cod_acp<<8) ^ acp_LSB;

znachenie_acp=((cod_acp*5.0)/8388607.0)/64.0;//переводим в напряжение

подскажите,есть более быстрый способ? что бы не тратить машинное время.
Первое что пришло в голову
znachenie_acp=cod_acp*0.00000000931322685637794;
может есть варианты как еще выделить знак?
мне нужно минимальное вермя преобразования

Сообщение отредактировал messenger - Dec 31 2015, 14:38
Go to the top of the page
 
+Quote Post
mcheb
сообщение Dec 31 2015, 15:46
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 326
Регистрация: 30-05-06
Пользователь №: 17 602



Цитата(messenger @ Dec 31 2015, 18:32) *
Преобразую код 24 битного ацп к виду напряжения.

А можно поинтересоваться,зачем это преобразование? Ну и попутно ещё всякие вопросы.
Go to the top of the page
 
+Quote Post
Alex11
сообщение Dec 31 2015, 18:41
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 106
Регистрация: 23-10-04
Из: С-Петербург
Пользователь №: 965



Лучше сделайте union из 4 байтов и 32-битного слова, а дальше примерно так:
if(acp_MSB < 0) cod_acp.b3 = 0xff;
else cod_acp.b3 = 0;
cod_acp.b2 = acp_MSB;
cod_acp.b1 = acp_Mid;
cod_acp.b0 = acp.LSB;
znachenie_acp=cod_acp.w*...
здесь посчитайте руками на что нужно умножить один раз, хотя, может быть, оптимизатор и так отработает.
Go to the top of the page
 
+Quote Post
messenger
сообщение Dec 31 2015, 19:08
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



я в codevision пишу.
Поясните что есть "union" и как сделать что бы писать побайтно в переменную как здесь cod_acp.b2 = acp_MSB;
Go to the top of the page
 
+Quote Post
M_Andrey
сообщение Dec 31 2015, 19:20
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 158
Регистрация: 15-10-07
Из: Й-Ола
Пользователь №: 31 376



Цитата(Alex11 @ Dec 31 2015, 21:41) *
if(acp_MSB < 0) cod_acp.b3 = 0xff;
else cod_acp.b3 = 0;


Здесь acp_MSB - байт, он беззнаковый и компилятор об этом предупредит.


Надо примерно так:

Код
</p><p>union    long2uch
{
    struct
        {
    struct    {    unsigned char l,ml,mh,h;    }    byte;
    signed long sl;
    }
} acp;

acp.byte.l  = 0;
acp.byte.ml = acp_LSB;
acp.byte.mh = acp_Mid_Byte;
acp.byte.h  = acp_MSB;

double znachenie_acp = acp.sl*(5.0/(2147483648*64));</p><p>


Go to the top of the page
 
+Quote Post
_pv
сообщение Jan 1 2016, 14:43
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



надо убрать плавающую запятую совсем и сделать просто
adcVolt = (adcCode * 149) >> 4;
результат получится в десятках наноВольт с точностью до 0.007%.

Цитата
Надо примерно так:
double znachenie_acp = acp.sl*(5.0/(2147483648*64));

вот так как раз не надо (особенно учитывая что это codevision), потому что (2147483648*64) хоть и стоит рядом с 5.0, думаю вполне может оказаться что будет сначала посчитано как int (который у АВР кстати вообще 16 битный, хотя опять же, как там у codevision - не уверен) а только потом преобразовано в double.
Go to the top of the page
 
+Quote Post
messenger
сообщение Jan 1 2016, 17:21
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



Цитата(_pv @ Jan 1 2016, 18:43) *
надо убрать плавающую запятую совсем и сделать просто
adcVolt = (adcCode * 149) >> 4;
результат получится в десятках наноВольт с точностью до 0.007%.


поясните пожалуйста для начинающих, не могу въехать
Go to the top of the page
 
+Quote Post
M_Andrey
сообщение Jan 1 2016, 17:52
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 158
Регистрация: 15-10-07
Из: Й-Ола
Пользователь №: 31 376



Цитата(messenger @ Jan 1 2016, 20:21) *
поясните пожалуйста для начинающих, не могу въехать

Вопрос в том что вы хотите получить. Вам действительно нужна точность 24 бита?
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 1 2016, 18:09
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(messenger @ Jan 1 2016, 20:21) *
поясните пожалуйста для начинающих, не могу въехать

Не сочтите мои слова как неуважение к новичкам, но учить язык программирования по ответам на форуме - неправильный, трудоемкий путь.
В любой книжке по С написано, что такое union, вы хотите тут подобрать людей, чтобы Вам книжки вслух читали?


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
_pv
сообщение Jan 1 2016, 21:41
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(messenger @ Jan 1 2016, 23:21) *
поясните пожалуйста для начинающих, не могу въехать

ну величина 1 LSB ацп это 5.0В/(2^23)/64 = 9.31322574615479 нановольт (кстати, двойку не потеряли на знаковости? то есть весь входной диапазон АЦП +-5В=10В или 5В?)
а число 149/16 == это 9.3125 (отличается от 9.31322574615479 лишь на 0.007%), то есть умножив код на 149 целочисленно (32 разряда не переполнятся) и поделив на 16, (сдвинув на 4), получится целочисленный результат, но в нановольтах.

про десяток нановольт в прошлом сообщении - это я по запятой в калькуляторе промазал, в 10 раз
Go to the top of the page
 
+Quote Post
messenger
сообщение Jan 2 2016, 07:30
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



Очень интересный способ! И память можно здорово сэекономить.
Только я не пойму, раз мы говорим о целочисленном результате, то пллучается просто "9" а не 9.3125, и тогда погрешность 3.5%
И если вся шкала 8388608 (2^23), то для 16 битной переменной это переполенение, а если брать 32 битную, то какой в этом смысл?


Сообщение отредактировал messenger - Jan 2 2016, 07:43
Go to the top of the page
 
+Quote Post
_pv
сообщение Jan 2 2016, 08:43
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(messenger @ Jan 2 2016, 13:30) *
Только я не пойму, раз мы говорим о целочисленном результате, то пллучается просто "9" а не 9.3125, и тогда погрешность 3.5%

если число например 1000000 умножить на 149, а потом поделить на 16, сколько получится, в целых числах?
Go to the top of the page
 
+Quote Post
messenger
сообщение Jan 2 2016, 10:09
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



9312500
Go to the top of the page
 
+Quote Post
_pv
сообщение Jan 2 2016, 10:28
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(messenger @ Jan 2 2016, 16:09) *
9312500

то есть, таким образом, используя целочисленное умножение/деление, число умножили на 9.3125, а не на 9.

Go to the top of the page
 
+Quote Post
messenger
сообщение Jan 2 2016, 19:39
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 361
Регистрация: 23-03-07
Пользователь №: 26 457



Что то я смысл не пойму. Беззнаковый int от 0 до 65535. Т.е мы уже вышли за пределы и нужна переменная типа long, которая по размеру такая же как и float.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th June 2025 - 17:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01677 секунд с 7
ELECTRONIX ©2004-2016