Skocz do zawartości

Kurs STM32 - #6 - Pomiar napięcia, przetwornik ADC


Komentator

Pomocna odpowiedź

html_mig_img
Tym razem poznamy bliżej działanie przetwornika analogowo-cyfrowego. Za jego pomocą będziemy mogli zmierzyć napięcie na wejściu układu.Podstawowa wiedza o ADC konieczna jest nie tylko przy budowie robotów. Peryferia te używane są w większości systemów, które mają czujniki.

UWAGA, to tylko wstęp! Dalsza część artykułu dostępna jest na blogu.

Przeczytaj całość »

Poniżej znajdują się komentarze powiązane z tym wpisem.

Link do komentarza
Share on other sites

Mam pytanie związane z zad. 6.1, chciałbym się upewnić czy dobrze rozumiem: wzór na wyliczenie częstotliwości próbkowania ADC to

gdzie N to ilość cykli zegara ADC na pomiar, tak?

Link do komentarza
Share on other sites

Włącza diodę, jeśli pada za mało światła na fotorezystor.

#include "stm32f10x.h"
#include <stdio.h>

void send_char(char c)
{
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
USART_SendData(USART2, c);
}

int __io_putchar(int c)
{
if (c=='\n')
send_char('\r');
send_char(c);
return c;
}

int main(void)
{
GPIO_InitTypeDef gpio;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

GPIO_StructInit(&gpio);

gpio.GPIO_Pin = GPIO_Pin_0;
gpio.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &gpio);

gpio.GPIO_Pin = GPIO_Pin_2;
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &gpio);

gpio.GPIO_Pin = GPIO_Pin_3;
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &gpio);

gpio.GPIO_Pin = GPIO_Pin_13;
gpio.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &gpio);

GPIO_StructInit(&gpio);
gpio.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|
                        GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &gpio);

USART_InitTypeDef uart;

USART_StructInit(&uart);
uart.USART_BaudRate = 115200;
USART_Init(USART2, &uart);
USART_Cmd(USART2, ENABLE);

ADC_InitTypeDef adc;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);                    //dzielnik napiecia, zeby zegar (64 MHz) zmniejszyc ponizej 14 MHz)

ADC_StructInit(&adc);
adc.ADC_ContinuousConvMode = ENABLE;
adc.ADC_NbrOfChannel = 1;
adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_Init(ADC1, &adc);

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_71Cycles5);    //Ustawienie kanalu wejsciowego (kanal 0 multipleksera)
ADC_Cmd(ADC1, ENABLE);

ADC_ResetCalibration(ADC1);                        //autokalibracja przetwornika
while (ADC_GetResetCalibrationStatus(ADC1));

ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1));

ADC_TempSensorVrefintCmd(ENABLE);                    //wlaczenie napiecia referencyjnego
ADC_SoftwareStartConvCmd(ADC1, ENABLE);

while (1)
{
    uint16_t adc = ADC_GetConversionValue(ADC1);        //wyslanie wyniku po UART
    printf("Adc = %d (%.3fV)\r\n", adc, adc * 3.3f / 4096.0f);

    if (adc <= 3000)                                //wlacza diode, jesli za malo swiatla pada
    {
        GPIO_SetBits(GPIOC, GPIO_Pin_0);
    }

    else
    {
        GPIO_ResetBits(GPIOC, GPIO_Pin_0);
    }

}
}
Link do komentarza
Share on other sites

Mam dość głupie, ale ważne dla mnie pytanie.

Skąd wartość napięcia referencyjnego 1.2V? Mógłby mi ktoś to wytłumaczyć? Szukam w dokumentacji ale nigdzie tej informacji znaleźć nie mogę (zapewne szukam źle).

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Mam mały problem / wątpliwość. Po włączeniu konwersji VRef, wartość jaka jest odczytywana na moim DiscoveryF0 to 1690+-, gdy tymczasem tutaj jest opisane, że powinno być 1490+-. Wg noty katalogowej procesora znajdującego się na mojej płytce, napięcie VRef powinno być takie samo jak w tym kursie. Co może być nie tak?

Link do komentarza
Share on other sites

Zadanie domowe 6.5. Podłączyłem dwa fotorezystory, wszystko działa ok, tylko zdarzenie kiedy oba kanały mają dokładnie taką samą wartość napięcia następują niezwykle rzadko (co jest zrozumiałe, przy takich pomiarach).

Czy ktoś może podać sugestię, jak zrealizować porównanie "mniej-więcej"? Tzn, chciałbym zrobić warunek:

if (ADC_kanal1 == ADC_kanal2) printf "prosto";

, z tym, że ADC_kanal1 może różnić się od ADC_kanal2 o jakąś założoną przeze mnie wartość, powiedzmy x.

Link do komentarza
Share on other sites

smilee, witam na forum 🙂

Najlepiej odejmować jeden pomiar od drugiego i sprawdzać jaka jest wartość bezwzględna wyniku. Możesz uznać, że jeśli różnica jest mniejsza o 20, to znaczy, że wskazania można traktować jako równe 🙂

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Witajcie, chciałem uruchomić odczyt z ADC1 z kanału 0 na STM32F401RE. Niestety program nie działa. Kod:

ADC_InitTypeDef adc;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    ADC_StructInit(&adc);
    adc.ADC_ContinuousConvMode = ENABLE;
    //adc.ADC_NbrOfChannel = 1;

    adc.ADC_NbrOfConversion=1;
    adc.ADC_ScanConvMode=1;
    adc.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
    ADC_Init(ADC1, &adc);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_0,1,ADC_SampleTime_28Cycles);
    //ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 1, ADC_SampleTime_71Cycles5);
    ADC_Cmd(ADC1, ENABLE);


    //ADC_ResetCalibration(ADC1);
    //while (ADC_GetResetCalibrationStatus(ADC1));

    //ADC_StartCalibration(ADC1);
    //while (ADC_GetCalibrationStatus(ADC1));

    ADC_TempSensorVrefintCmd(ENABLE);
    ADC_SoftwareStartConv(ADC1);

Czy ktoś jest w stanie mi powiedzieć co jest źle, bądź  co zapomniałem uwzględnić?

Uprzejmie proszę o pomoc, Pozdrawiam 

Link do komentarza
Share on other sites

Jak widać ledwo moderator wyjedzie na wakacje, a od razu na forum źle się dzieje 🙂

@Protektor28 - ten kurs dotyczy stm32f103. Przykłady były na opisywanym układzie testowane, ale na innych mogą wymagać modyfikacji. Jeśli dopiero się uczysz, to najłatwiej wykorzystać opisywany sprzęt, albo poszukać kursu omawiającego Twoją wersję.

Ale niezależnie od wszystkiego, w komentarzach do kursów powinny być omawiane rzeczy związane z kursem... jeśli chcesz zapytać o stm32f401 lub inny model, załóż proszę nowy temat.

Edytowano przez Elvis
  • Lubię! 1
Link do komentarza
Share on other sites

Witam!

Pomiar u mnie wynosi bez podłączania Vref około 1,6V (sprawdziłem multimetrem). Sprawdziłem też programowo (keil zakładka peripherals) i wyświetla mi wartości np 0x000007BF, czyli wlasnie około 1,6V. Czy aby mierzyć wartości od 0V trzeba najpierw jakoś podłączyć ADC1 do masy? Płytka to nucleo f103rb oczywiście;)

Link do komentarza
Share on other sites

Hej.

Gdzie w Reference Manual mogę znaleźć informację na temat tego, które piny są podłączone do ADC, UART lub innych peryferiów? Jakoś nie mogę tego znaleźć, jedynie wiem, że mogę się wspomóc podglądem pinów w programie CubeMX, ale to rozwiązanie wydaje mi się mało zadowalające.

Dzięki!

Link do komentarza
Share on other sites

Bo dokument Reference Manual jest opisem bloków funkcjonalnych od strony programowej a nie ich implementacji w konkretnym chipie. Od tego masz Data Sheet kostki, której używasz. Tam są opisane wszystkie obudowy w jakich występuje, fizyczne parametry elektryczne oraz właśnie to czego szukasz, czyli ogromna tabelka wyszczególniająca wszystkie piny (każdej obudowy - przecież różnią się liczbą, numeracją i nazwami) oraz ich "obłożenie" fukcjami alternatywnymi. Czy możesz podać pełną nazwę procesora?

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

1 godzinę temu, marek1707 napisał:

Bo dokument Reference Manual jest opisem bloków funkcjonalnych od strony programowej a nie ich implementacji w konkretnym chipie. Od tego masz Data Sheet kostki, której używasz. Tam są opisane wszystkie obudowy w jakich występuje, fizyczne parametry elektryczne oraz właśnie to czego szukasz, czyli ogromna tabelka wyszczególniająca wszystkie piny (każdej obudowy - przecież różnią się liczbą, numeracją i nazwami) oraz ich "obłożenie" fukcjami alternatywnymi. Czy możesz podać pełną nazwę procesora?

Już widzę, dziękuję! Datasheet tabela5 do układu stm32f103rb. Już wszystko ma sens. 🙂

Edytowano przez MaciejZyskowski
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.