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

 
 
 
Reply to this topicStart new topic
> LPC2103 и АЦП, Неверные показания АЦП
XWoo
сообщение Jul 22 2010, 20:49
Сообщение #1


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

Группа: Участник
Сообщений: 91
Регистрация: 19-11-09
Пользователь №: 53 737



Появилась у меня недавно платка, чем-то напоминающая Olimex LPC-H2103. В платке я задействовал таймер, spi, uart, подключил два 7-мисегментных индикатора. PLL выключил (Cclk=Pclk=Fosc=14.7456 МГц). Теперь взялся за АЦП. Примеры скачал. Запустил АЦП в Burst режиме (с прерыванием):

PINSEL0 |= 0x00F00000; // AD3,4
PINSEL1 |= 0x0003F000; // AD0,1,2

ADCR = 0x0020921F;
ADCR |= 0x00010000; // start burst mode

CLKDIV = 147-1 = 146, т.е. АЦП работает на ~100 КГц.
Задействованы аналоговые входы AD0..AD4.

В прерывании опрашиваю входы и результат загоняю в массив:

unsigned int r, ch;

r = ADGDR;
ch = (r >> 24) & 0x00000007;
ADCresult[ch] = (unsigned short)((r>>6) & 0x03FF);

Потом данные из массива отправляю по uart'у и вывожу целую и десятичную часть на 2 индикатора.

Всё работает, но есть одно "НО". У меня не соответствуют значения напряжения в АЦП (10-битный код из регистра ADGDR) и напряжения на аналоговом входе. Я подаю на вход AD4 (вывод 36) напряжение от 0 до 3,3 В. При этом показания напряжения АЦП отличаются от входного на несколько сот милливольт: вместо 3,0В АЦП выдаёт 2,9В; вместо 1,8В - 1,6В; вместо 0,5В - 0,4В - т.е. само отличие непостоянно: чем ближе к нулю, тем оно меньше.

10-битный код я преобразовываю в напряжение следующим образом: [код]*Vref, где Vref=3.3B - образцовое напряжение АЦП (вывод Vdda). Например, если код равен 0x02F6, то это соответствует напряжению 2501 милливольт, однако на вход AD4 подано напряжение 2.9 вольт! Разница в 400 мВ!

Может я неверно расчитываю показания АЦП? Как убрать такое несоответствие?

Ещё у меня младшие 8 бит постоянно меняются, т.е. в коде 0x02F6 число 0xF6 после следующего
измерения АЦП будет уже другим, например: 0x02E5, 0x02FE.
Это наверное нестабильность по питанию? Или какие-то помехи?
Go to the top of the page
 
+Quote Post
KRS
сообщение Jul 22 2010, 21:08
Сообщение #2


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



А вы пробовали только 1 канал и полингом опрашивать?
Go to the top of the page
 
+Quote Post
XWoo
сообщение Jul 23 2010, 08:02
Сообщение #3


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

Группа: Участник
Сообщений: 91
Регистрация: 19-11-09
Пользователь №: 53 737



да, пробовал. И AD0 и др каналы. И в single режиме опрашивал (в этом режиме я сперва и опробовал АЦП). Результат один и тот же!

Даже пробовал менять частоту АЦП (clkdiv): выставлял 57.6 КГц, 100 КГц, 1.05 МГц - всё работает без изменений. а вот на 2 МГц и выше (вплоть до 4.5 МГц) моя плата то ли тормозит, то ли вообще не запускается.
Go to the top of the page
 
+Quote Post
карабас
сообщение Jul 23 2010, 08:29
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 8-12-09
Пользователь №: 54 123



Vref=3.3B, а какое оно в реальности?
Go to the top of the page
 
+Quote Post
XWoo
сообщение Jul 23 2010, 13:28
Сообщение #5


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

Группа: Участник
Сообщений: 91
Регистрация: 19-11-09
Пользователь №: 53 737



Замерил Vref. Оно равно 3.48 В. И питание ядра также завышено, там 2.12 В.
Неужели данная проблема заключена в повышенном напряжении питания проца?
Займусь регулировкой двух стабилизаторов на 3.3 В и 1.8 В.
Go to the top of the page
 
+Quote Post
fmdost
сообщение Jul 23 2010, 22:32
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606



Цитата(XWoo @ Jul 23 2010, 17:28) *
Займусь регулировкой двух стабилизаторов на 3.3 В и 1.8 В.


Да, но сначала надо заменьть батарейку в тестере wink.gif
Go to the top of the page
 
+Quote Post
XWoo
сообщение Jul 29 2010, 10:21
Сообщение #7


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

Группа: Участник
Сообщений: 91
Регистрация: 19-11-09
Пользователь №: 53 737



да дело тут не в батарейках (3 различных мультиметра показывали одно и тоже), а в том что компилятор кейл строку "#define Vref (33/10)" воспринимает не как 3.3, а как 3, поэтому и произведение показаний ацп (10 бит) на Vref было занижено. а вот когда я поставил "#define Vref (3.3)", тогда всё встало на свои места.

оба напряжения я уменьшил до 1.90В и 3.35В (соответственно и Vref поставил равным 3.35).

если сделать эти напряжения равными 1.80/1.85 и 3.30, то моя платка не работала.


эту строку "#define Vref (33/10)" я увидел в примерах (исходники на си и pdf). видимо тому, кто писал тот код, не требовалась десятичная часть показаний АЦП, нужна была только целая часть.
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 29 2010, 10:39
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(XWoo @ Jul 29 2010, 16:21) *
эту строку "#define Vref (33/10)" я увидел в примерах (исходники на си и pdf). видимо тому, кто писал тот код, не требовалась десятичная часть показаний АЦП, нужна была только целая часть.

Это просто ваш компилятор оптимизировал вычисление константы. Причем целочисленное вычисление. Поскольку константы без явного указания типа все целочисленные (тип int).
А вообще вычислять напряжение АЦП с применением плавающей арифметики как-то неразумно. Тем более когда точность и диапазон изменения величин небольшой. По крайней мере уж на 32-х битных ARM проблем с целочисленным вычислением напряжения, измеряемого встроенным АЦП быть не должно.
Кстати, если уж совсем придираться biggrin.gif, то дефайн нужно было привести к виду
Код
#define VREF 3.3f

Во-первых, суффикс f явно приводит константу к типу float. Во-вторых, в макросах общепринято использовать только заглавные символы, чтобы отличать их (макросы) от переменных и функций.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jul 29 2010, 11:13
Сообщение #9


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Попробуйте вычислять так:

voltage = adc_value * VREF / RES где VFEF - опорное напряжение в милливольтах (например, 3300 для 3.3в) и RES - разрешение АЦП (для 10 бит - 1023).
Получится так:
Код
unsigned int voltage = adc_value * 3300 / 1023;

где voltage - в милливольтах.

Все вычисления целочисленные, а желаемого разрешения можно добиться, меняя VREF в большую сторону - 33000, 330000 и т.д.
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 29 2010, 11:29
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(sonycman @ Jul 29 2010, 17:13) *
Получится так:
Код
unsigned int voltage = adc_value * 3300 / 1023;

где voltage - в милливольтах.

Лучше будет так
Код
unsigned int voltage = ((unsigned long) adc_value * 3300UL) / 1023UL;

без скобок компилятор опять может оптимизировать вычисление константы и умножение будет снова на число 3.
Go to the top of the page
 
+Quote Post
XWoo
сообщение Jul 29 2010, 15:45
Сообщение #11


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

Группа: Участник
Сообщений: 91
Регистрация: 19-11-09
Пользователь №: 53 737



rezident и sonycman, спасибо вам за советы. Завтра попробую.

И спасибо всем за участие. smile.gif

Думаю эту тему можно закрыть.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 6th July 2025 - 15:13
Рейтинг@Mail.ru


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