SM
Guest
Tue Nov 08, 2011 10:16 am
Witam,
Czy ktoś tu z obecnych bawił się ADC w procesorkach STM32
i mógłby coś potwierdzić/sprawdzić u siebie?
Mam układ na STM32F103RBT6 i wykorzystuję 4 kanały ADC1
(regular channels) na PA0..PA3.
Problem jest taki że mam spory szum z przetwarzania - tak
jakby na zadawane przeze mnie napięcie do wejścia ADC coś
się nakładało. Nie mogłem tego zwalczyć, więc zająłem się
testowaniem ADC na pojedynczym wejściu.
Podpiąłem wejście ADC (pin PA0) do źródła zasilania przez
rezystor 10kOhm i dalej mam szum. Podpiąłem się więc z
oscyloskopem i co widzę? W momencie startu przetwarzania
przez ADC mam szpilkę napięciową na 100mV z wyjścia!
Zgodnie z dokumentacją wewnętrznie do PA0 powinien być
dołączony klucz (oporność około 1k) i kondensator
kilka pF jako układ pamiętający (sample and hold).
Efekt jest taki jakbym każdorazowo po starcie ADC miał
ten wewnętrzny kondensator naładowany i musiał go nie
ładować moim zewnętrznym, mierzonym napięciem, ale rozła-
dowywać! Zmodyfikowałem układ aby "mocno" sterować wejściem
dla ADC - wtórnik na wzm.operacyjnym. Trochę pomogło ale
nie za wiele - ładunek jest na tyle duży że nawet operacyjny
ma problem - układ zaczyna "dzwonić" i mam oscylacje.
Mam więc pytanie - czy ktoś spotkał się z tym problemem
w STM32? Czy one tak mają, czy też trafiłem na jakiś
odrzut/podróbę?
SM
P.S.
Ktoś chyba miał podobny problem
http://www.elektroda.pl/rtvforum/topic2087721.html#9921288
Nie jest to jednak efekt pamięciowy, bo występuje on także
przy przetwarzaniu tylko jednego kanału (nie jest to więc
"pozostałość" napięcia na wspólnym kondensatorze od S&H
z pomiaru z innego kanału).
MichaĹ BaszyĹski
Guest
Tue Nov 08, 2011 5:04 pm
W dniu 2011-11-08 10:16, SM pisze:
Quote:
Zgodnie z dokumentacją wewnętrznie do PA0 powinien być
dołączony klucz (oporność około 1k) i kondensator
kilka pF jako układ pamiętający (sample and hold).
Efekt jest taki jakbym każdorazowo po starcie ADC miał
ten wewnętrzny kondensator naładowany i musiał go nie
ładować moim zewnętrznym, mierzonym napięciem, ale rozła-
dowywać! Zmodyfikowałem układ aby "mocno" sterować wejściem
dla ADC - wtórnik na wzm.operacyjnym. Trochę pomogło ale
nie za wiele - ładunek jest na tyle duży że nawet operacyjny
ma problem - układ zaczyna "dzwonić" i mam oscylacje.
na wejściu ADC powinieneś mieć zewnętrzny kondensator odpowiedniej
pojemności (IMHO foliowy 10nF ew. ceramiczny - ale koniecznie NP0). Aby
wzm. operacyjny przy takim obciążeniu Ci nie dzwonił odseparuj wyjście
wzmacniacza od kondensatora opornikiem niewielkiej wartości (tak z
50-100 omów), sprzężenie zwrotne weź z kondensatora. I powinno być OK.
--
Pozdr.
Michał
SM
Guest
Tue Nov 08, 2011 5:17 pm
Quote:
na wejściu ADC powinieneś mieć zewnętrzny kondensator odpowiedniej
pojemności (IMHO foliowy 10nF ew. ceramiczny - ale koniecznie NP0). Aby
wzm. operacyjny przy takim obciążeniu Ci nie dzwonił odseparuj wyjście
wzmacniacza od kondensatora opornikiem niewielkiej wartości (tak z
50-100 omów), sprzężenie zwrotne weź z kondensatora. I powinno być OK.
Jutro sprawdzę czy ten 10nF wystarczy aby "połknąć" wypływający
z wejścia ładunek na tyle, żeby podbicie na nim napięcia
nie było zbyt duże. I czy ten rezystor sprawdzi się aby
wzm.oper. nie dzwonił.
Wcześniej robiłem inny test. Sądziłem że to te zakłócenia to szum
i dałem filtr RC między wzm.oper. a wejściem ADC. Stała czasowa
bardzo mocno za duża (specjalnie do testów). Przy niewielkich
napięciach tylko pogorszyło to sprawę - zadziałało "odwrotnie"
- jak układ różniczkujący.
SM
Zbych
Guest
Tue Nov 08, 2011 5:24 pm
On 08.11.2011 17:04, Michał Baszyński wrote:
Quote:
W dniu 2011-11-08 10:16, SM pisze:
Zgodnie z dokumentacją wewnętrznie do PA0 powinien być
dołączony klucz (oporność około 1k) i kondensator
kilka pF jako układ pamiętający (sample and hold).
Efekt jest taki jakbym każdorazowo po starcie ADC miał
ten wewnętrzny kondensator naładowany i musiał go nie
ładować moim zewnętrznym, mierzonym napięciem, ale rozła-
dowywać! Zmodyfikowałem układ aby "mocno" sterować wejściem
dla ADC - wtórnik na wzm.operacyjnym. Trochę pomogło ale
nie za wiele - ładunek jest na tyle duży że nawet operacyjny
ma problem - układ zaczyna "dzwonić" i mam oscylacje.
na wejściu ADC powinieneś mieć zewnętrzny kondensator odpowiedniej
pojemności (IMHO foliowy 10nF ew. ceramiczny - ale koniecznie NP0)
Czemu koniecznie NP0? Wartość pojemności nie jest krytyczna.
Quote:
wzm. operacyjny przy takim obciążeniu Ci nie dzwonił odseparuj wyjście
wzmacniacza od kondensatora opornikiem niewielkiej wartości (tak z
50-100 omów), sprzężenie zwrotne weź z kondensatora. I powinno być OK.
Podłączanie sprzężenia w taki sposób to proszenie się o oscylacje.
MichaĹ BaszyĹski
Guest
Tue Nov 08, 2011 6:21 pm
W dniu 2011-11-08 17:24, Zbych pisze:
Quote:
na wejściu ADC powinieneś mieć zewnętrzny kondensator odpowiedniej
pojemności (IMHO foliowy 10nF ew. ceramiczny - ale koniecznie NP0)
Czemu koniecznie NP0? Wartość pojemności nie jest krytyczna.
absorbcja dielektryczna. Wartość nie jest krytyczna
--
Pozdr.
Michał
Zbych
Guest
Tue Nov 08, 2011 10:05 pm
On 08.11.2011 18:21, Michał Baszyński wrote:
Quote:
W dniu 2011-11-08 17:24, Zbych pisze:
na wejściu ADC powinieneś mieć zewnętrzny kondensator odpowiedniej
pojemności (IMHO foliowy 10nF ew. ceramiczny - ale koniecznie NP0)
Czemu koniecznie NP0? Wartość pojemności nie jest krytyczna.
absorbcja dielektryczna. Wartość nie jest krytyczna
To by miało znaczenie w układnie próbkująco-pamiętającym. Tutaj masz
kondensator na wyjściu wtórnika.
MichaĹ BaszyĹski
Guest
Wed Nov 09, 2011 3:17 pm
W dniu 2011-11-08 22:05, Zbych pisze:
Quote:
To by miało znaczenie w układnie próbkująco-pamiętającym. Tutaj masz
kondensator na wyjściu wtórnika.
przy 10-12 bitach wbudowanych w uC to cokolwiek by nie dał i tak będzie
dobrze.
Ale przy dokładniejszych to inżynierowie Texasa na seminarium "Precision
Analog Applications" parę lat temu zalecali jednak NP0
O, chyba znalazłem (strona 22):
http://www.ti.com/lit/ml/slyp166/slyp166.pdf
Sugerują mikowe albo NP0/C0G z powodu nieliniowości ceramiki o dużej
stałej K.
Natomiast pisząc o braniu sprzężenia zwrotnego z kondensatora, a nie
sprzed opornika, zasugerowałem się rys. 44 z będącego jakiś czas temu u
mnie na tapecie PCM1804. Zapomniałem jednak o "drobiazgu" w postaci
jednak dość sporego kondensatora w sprzężeniu zwrotnym bezpośrednio
pomiędzy wyjściem i wejściem odwracającym
Tak więc z tym masz w dużej części rację - stałoprądowe (decydujące o
dokładności) jest brane z kondensatora, natomiast dołożone jest
dodatkowe zmiennoprądowe dla zachowania stabilności.
Tu zalecają jednak foliowe (str. 29) na wejściu ADC.
--
Pozdr.
Michał
Zbych
Guest
Wed Nov 09, 2011 4:14 pm
W dniu 2011-11-09 15:17, Michał Baszyński pisze:
Quote:
W dniu 2011-11-08 22:05, Zbych pisze:
To by miało znaczenie w układnie próbkująco-pamiętającym. Tutaj masz
kondensator na wyjściu wtórnika.
przy 10-12 bitach wbudowanych w uC to cokolwiek by nie dał i tak będzie
dobrze.
Ale przy dokładniejszych to inżynierowie Texasa na seminarium "Precision
Analog Applications" parę lat temu zalecali jednak NP0
O, chyba znalazłem (strona 22):
http://www.ti.com/lit/ml/slyp166/slyp166.pdf
Dzięki za podanie linka.
Quote:
Sugerują mikowe albo NP0/C0G z powodu nieliniowości ceramiki o dużej
stałej K.
Czyli problem wynika z nieliniowości pojemności w funkcji napięcia i ma
znaczenie tylko przy pomiarze napięć zmiennych. Według wykresów z pdfa
nie ma się co martwić o typ dielektryka przy częstotliwościach do 1kHz.
Quote:
Natomiast pisząc o braniu sprzężenia zwrotnego z kondensatora, a nie
sprzed opornika, zasugerowałem się rys. 44 z będącego jakiś czas temu u
mnie na tapecie PCM1804. Zapomniałem jednak o "drobiazgu" w postaci
jednak dość sporego kondensatora w sprzężeniu zwrotnym bezpośrednio
pomiędzy wyjściem i wejściem odwracającym
Tak więc z tym masz w dużej części rację - stałoprądowe (decydujące o
dokładności) jest brane z kondensatora, natomiast dołożone jest
dodatkowe zmiennoprądowe dla zachowania stabilności.
Tu zalecają jednak foliowe (str. 29) na wejściu ADC.
Zbych
Guest
Wed Nov 09, 2011 4:16 pm
W dniu 2011-11-08 10:16, SM pisze:
Quote:
Witam,
Czy ktoś tu z obecnych bawił się ADC w procesorkach STM32
i mógłby coś potwierdzić/sprawdzić u siebie?
Mam układ na STM32F103RBT6 i wykorzystuję 4 kanały ADC1
(regular channels) na PA0..PA3.
Problem jest taki że mam spory szum z przetwarzania - tak
jakby na zadawane przeze mnie napięcie do wejścia ADC coś
się nakładało. Nie mogłem tego zwalczyć, więc zająłem się
testowaniem ADC na pojedynczym wejściu.
Podpiąłem wejście ADC (pin PA0) do źródła zasilania przez
rezystor 10kOhm i dalej mam szum. Podpiąłem się więc z
oscyloskopem i co widzę? W momencie startu przetwarzania
przez ADC mam szpilkę napięciową na 100mV z wyjścia!
Sprawdź erraty, zwłaszcza rozdział:
"Voltage glitch on ADC input 0"
SM
Guest
Wed Nov 09, 2011 5:30 pm
W tej chwili na szybko dodałem na drucikach
zewnętrzny ADC 10bit po SPI (MCP3008).
Żadnego szumu, szpilek, czy też innych
problemów - pomiar z dokładnością 1 LSB.
Nie mniej jednak procka jeszcze przetestuję
bo zawsze to trochę szkoda nie korzystać
z jego ADC.
I jeszcze jedna uwaga. Układ zrobiłem tak,
że odczyt analoga robię z częstotliwością 5kHz
, wybieram największą wartość jaka wystąpi w
jednej sekundzie i zapisywał ją na kartę SD.
W ten sposób testowałem problemy z ADC. Paskudne
było to, że te szpilki wyłaziły czasem co kilka
sekund. Tak jakby start przetwarzania ADC lekko
przesuwał się w czasie - raz wypadało to na
maksimum szpilki, raz nie. Ciekawe było to że
raz trafiał procek w wartości pośrednie
(widoczne jako szum), innym razem albo nie rejestrował
piku, albo raz na kilka sekund zarejestrował
max. skok 100mV (bez wartości pośrednich).
Wszystko zależało od wartości napięcia na danym
kanale czy też innych kanałach - ciężko
było ustalić jakąś zależność.
SM
Konop
Guest
Wed Nov 09, 2011 10:35 pm
Quote:
Czy ktoś tu z obecnych bawił się ADC w procesorkach STM32
i mógłby coś potwierdzić/sprawdzić u siebie?
Mam układ na STM32F103RBT6 i wykorzystuję 4 kanały ADC1
(regular channels) na PA0..PA3.
Problem jest taki że mam spory szum z przetwarzania - tak
jakby na zadawane przeze mnie napięcie do wejścia ADC coś
się nakładało. Nie mogłem tego zwalczyć, więc zająłem się
testowaniem ADC na pojedynczym wejściu.
Podpiąłem wejście ADC (pin PA0) do źródła zasilania przez
rezystor 10kOhm i dalej mam szum. Podpiąłem się więc z
oscyloskopem i co widzę? W momencie startu przetwarzania
przez ADC mam szpilkę napięciową na 100mV z wyjścia!
Zgodnie z dokumentacją wewnętrznie do PA0 powinien być
dołączony klucz (oporność około 1k) i kondensator
kilka pF jako układ pamiętający (sample and hold).
Efekt jest taki jakbym każdorazowo po starcie ADC miał
ten wewnętrzny kondensator naładowany i musiał go nie
ładować moim zewnętrznym, mierzonym napięciem, ale rozła-
dowywać! Zmodyfikowałem układ aby "mocno" sterować wejściem
dla ADC - wtórnik na wzm.operacyjnym. Trochę pomogło ale
nie za wiele - ładunek jest na tyle duży że nawet operacyjny
ma problem - układ zaczyna "dzwonić" i mam oscylacje.
Mam więc pytanie - czy ktoś spotkał się z tym problemem
w STM32? Czy one tak mają, czy też trafiłem na jakiś
odrzut/podróbę?
Ja ADc używam tylko do orientacyjnego pomiaru napięcia i prądu, więc
nawet, jeśli te problemy u mnie by wystąpiły - nie zauważyłbym ich. Mogę
jutro spróbować coś pomierzyć i pooglądać... Ale najpierw - powiedz,
jaki to ADC, czy masz osobne VREF, czy wspólne z AVCC itp. Patrzyłeś na
zasilanie AVCC?? Może stmtąd coś przechodzi?? Jak masz ustawiony
przetwornik?? Ile cykli na próbkowanie?? Czy próbowałeś to zmieniać i
jak to wpływało na pomiary??
--
Pozdrawiam
Konop
SM
Guest
Thu Nov 10, 2011 6:36 am
Quote:
Ja ADc używam tylko do orientacyjnego pomiaru napięcia i prądu, więc
nawet, jeśli te problemy u mnie by wystąpiły - nie zauważyłbym ich. Mogę
jutro spróbować coś pomierzyć i pooglądać... Ale najpierw - powiedz,
jaki to ADC, czy masz osobne VREF, czy wspólne z AVCC itp. Patrzyłeś na
zasilanie AVCC?? Może stmtąd coś przechodzi?? Jak masz ustawiony
przetwornik?? Ile cykli na próbkowanie?? Czy próbowałeś to zmieniać i
jak to wpływało na pomiary??
Procesorek STM32F103RBT6, tak więc VREF wewnętrznie połączone do VDDA.
VDDA zasilane z VDD poprzez dławik 100uH, odsprzęgnięte 1uF+10nF
(ceramiczne SMD). Masa analogowa VSSA połączona w jednym punkcie
z VSS i wyprowadzona do stopnia wejściowego części analogowej.
Zmiana czasu próbkowania w SMPR2 dawała niewielkie zmiany (to było
dla mnie największym zaskoczeniem). Podobnie zmiana preskalera ADC
w CFGR.
Róźnice były przy przetwarzaniu na jednym kanale (PA0) i na 4 (PA0..3).
Poziom zakłóceń zmieniał się w zależności od napięć panujących na
wejściach. Np. Gdy miałem tylko PA0 to tam były największe zakłócenia,
ale gdy PA0..3 to PA0 i PA1 prawie nie zakłócały PA2 zakłócało, PA3
zakłócało najmocniej.
P.S.
Kawałek kodu.
@ --- clocks config ADC clk = 12MHz
ldr r0, [r12, #RCC_CFGR_OFS]
ldr r1, =(4 << RCC_CFGR_PPRE1) | (2 << RCC_CFGR_SW) | (2 <<
RCC_CFGR_ADCPRE)
orr r0, r1
str r0, [r12, #RCC_CFGR_OFS]
@ --- APB2 - 72MHz (ADC enable)
ldr r0, [r12, #RCC_APB2ENR_OFS]
ldr r1, =(1 << RCC_APB2ENR_IOPAEN) | (1 << RCC_APB2ENR_IOPBEN) | (1 <<
RCC_APB2ENR_IOPCEN) | (1 << RCC_APB2ENR_IOPDEN) | (1 << RCC_APB2ENR_AFIOEN)
orr r0, r1
ldr r1, =(1 << RCC_APB2ENR_TIM1EN) | (1 << RCC_APB2ENR_ADC1EN)
orr r0, r1
str r0, [r12, #RCC_APB2ENR_OFS]
@ --- init ADC
.equiv ADC_CR1_OFS, 0x04
.equiv ADC_SMPR2_OFS, 0x10
ldr r12, =ADC1_BASE
@ CR1
ldr r0, =0
str r0, [r12, #ADC_CR1_OFS]
@ CR2
ldr r0, =(7 << 17)
str r0, [r12, #ADC_CR2_OFS]
@ SQR1 (nbr of channels = 1)
ldr r0, =(0 << 20)
str r0, [r12, #ADC_SQR1_OFS]
@ SMPR2 (sample time) - tutaj robiłem zmiany
ldr r0, =(7 << 0) | (7 << 3) | (7 << 6) | (7 << 9)
str r0, [r12, #ADC_SMPR2_OFS]
@ SQR3 (sel channel IN0)
ldr r0, =(0 << 0)
str r0, [r12, #ADC_SQR3_OFS]
@ ADC power on
bez uruchomienia ADC (ADON=1) nie działa
u mnie kalibracja chociaż w PDFie piszą że kalibracja powinna być
robiona przy ADON=0. Ale STM nawet w swoich przykładach daje
ADON=1 przed kalibracją.
ldr r0, =(7 << 17) | (1 << 0)
str r0, [r12, #ADC_CR2_OFS]
@ reset kalibracji
ldr r0, [r12, #ADC_CR2_OFS]
orr r0, #0x8
ldr r0, =(7 << 17) | (1 << 3) | (1 << 0)
str r0, [r12, #ADC_CR2_OFS]
@ czekanie na zakończenie
jmp1: ldr r0, [r12, #ADC_CR2_OFS]
tst r0, #(1 << 3)
bne jmp1
@ start kalibracji
ldr r0, [r12, #ADC_CR2_OFS]
orr r0, #0x4
ldr r0, =(7 << 17) | (1 << 2) | (1 << 0)
str r0, [r12, #ADC_CR2_OFS]
@ czekanie na zakończenie
jmp2: ldr r0, [r12, #ADC_CR2_OFS]
tst r0, #(1 << 2)
bne jmp2
W przerwaniu co 5kHz wykonuję:
@ odczyt ADC
ldr r12, =ADC1_BASE
ldr r0, [r12, #ADC_DR_OFS]
@ zapis do bufora w RAM
...
@ start ADC
ldr r0, =(7 << 17) | (1 << 20) | (1 << 22) | (1 << 0)
str r0, [r12, #ADC_CR2_OFS]
Dla wyjaśnienia - jak widać wszystko w asemblerze. C używam tylko
do bardzo dużych projektów. Tutaj mam tylko ADC, obsługa SD Card,
obsługa USB jako CDC, więc dużo tego nie jest.
Ponieważ do RAM i rejestrów można dostać się tylko adresowaniem
pośrednim, żeby skrócić program używam pewnych na stałe przypisanych
rejestrów:
R12 - zawsze baza dla danego peryferium (ADC1_BASE, TIM1_BASE, ...)
R11 - zawsze wskazuje początek RAM (bss_beg) dzięki temu dostęp do
zmiennych byte, half word, word realizuję poprzez makra:
.macro getb Reg Name
ldrb \Reg, [r11, #\Name - bss_beg]
.endm
.macro geth Reg Name
ldrh \Reg, [r11, #\Name - bss_beg]
.endm
.macro getw Reg Name
ldr \Reg, [r11, #\Name - bss_beg]
.endm
.macro putb Reg Name
strb \Reg, [r11, #\Name - bss_beg]
.endm
.macro puth Reg Name
strh \Reg, [r11, #\Name - bss_beg]
.endm
.macro putw Reg Name
str \Reg, [r11, #\Name - bss_beg]
.endm
np:
getw r1, rx_cnt
putb r0, adc_num
nie muszę za każdym razem ładować do rejestru pomocniczego
adresu zmiennej żeby ją zapisać/odczytać
podobnie z dostępem do peryferiów - ładuje do R12 bazę
i posługuję się adresowaniem z przesunięciem
Marek Borowski
Guest
Thu Nov 10, 2011 10:36 am
On 10-11-2011 06:36, SM wrote:
Quote:
Dla wyjaśnienia - jak widać wszystko w asemblerze. C używam tylko
do bardzo dużych projektów.
Tak z ciekawosci, co to znaczy bardzo duzy projekt ?
Pozdrawiam
Marek
SM
Guest
Thu Nov 10, 2011 12:12 pm
Quote:
Dla wyjaśnienia - jak widać wszystko w asemblerze. C używam tylko
do bardzo dużych projektów.
Tak z ciekawosci, co to znaczy bardzo duzy projekt ?
Np. obsługa w jednym urządzeniu: czytników zbliżeniowych,
telefonu GSM, kamera, USB (przesyłanie na serwer GPRSem zdjęć
w JPG). To już było na tyle duże że przerwania, obsługa sprzętowa
urządzeń, scheduler dla multitaskingu pisałem w asm, a całość
łączyłem w C.
SM