Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

STM32 Nucleo F103 RB Przycisk na rejestrach.

Pawel1243 29 Sep 2017 20:44 2787 59
Computer Controls
  • #1
    Pawel1243
    Level 7  
    Witam wszystkich na forum ;)
    Zaczynam naukę programowania mikrokontrolerów i przerabiam poradnik użytkownika szczywronek . Mam problem otóż nie mogę zrobić zaplania diody led poprzez naciśniecie przycisku. Przypuszczam że problem jest z konfiguracją rejestrów CRH bo nie wiem jak mam ustawić "10: Input with pull-up / pull-down" jeżeli do wyboru mode mam 0 lub 1 a muszę 10.
    Diody podłączone do portów są sprawne bo migały w moim poprzednim programie a przycisk wykorzystuję wbudowany w płytkę Nucleo f103RB.
    Oto kod:
    Code: c
    Log in, to see the code

    Pozdrawiam i licze na pomoc;)
  • Computer Controls
  • #3
    Pawel1243
    Level 7  
    Za poradą kolegi zmieniłem na
    Code: c
    Log in, to see the code
    ale jednak dalej coś jest nie tak;(
  • #4
    Sareph
    Level 24  
    Pawel1243 wrote:
    Za poradą kolegi zmieniłem na
    Code: c
    Log in, to see the code
    ale jednak dalej coś jest nie tak;(


    Jak skonfrontowałem ten kod z datasheetem, to dopiero początek problemów. ;)

    Pawel1243 wrote:
    jak mam ustawić "10: Input with pull-up / pull-down" jeżeli do wyboru mode mam 0 lub 1 a muszę 10.


    Nie masz do wyboru trybu 0 lub 1, masz do dyspozycji bity 0 lub 1. Znaczy, jeśli masz ustawić 11 to ustawiasz GPIO_CRL_MODEx_0 i GPIO_CRL_MODEx_1, razem daje Ci 11. Jak masz 01, to tylko GPIO_CRL_MODEx_0. Tak samo dla CNF.

    Code: c
    Log in, to see the code

    Czyścisz bit, który nawet nie jest ustawiony. W efekcie z ustawieniem MODE_1, PC13 przestawisz w "General purpose output Open-drain" (MODE 10, CNF 01), a zdaje się chciałbyś mieć je jako wejście.

    Sprawdź to, pisane z palca, może nie działać, późno jest ;)

    Code: c
    Log in, to see the code


    Nie konfiguruj PC13, on domyślnie jest "floating input", tam powinien być zewnętrzny pullup przy przycisku.

    Poza tym w wypadku BSRR, on jest write-only, więc:

    Code: c
    Log in, to see the code


    (bez "|")
  • Computer Controls
  • #5
    Pawel1243
    Level 7  
    Dziękuję koledze za pomoc, sporo mi to rozjaśniło. Oczywiście w dokumentacji teraz widzę że domyślnie ustawiony jest jako wejście ;)

    Zastanawiam się nad tym

    "Nie masz do wyboru trybu 0 lub 1, masz do dyspozycji bity 0 lub 1. Znaczy, jeśli masz ustawić 11 to ustawiasz GPIO_CRL_MODEx_0 i GPIO_CRL_MODEx_1, razem daje Ci 11. Jak masz 01, to tylko GPIO_CRL_MODEx_0. Tak samo dla CNF. "

    jeżeli mam ustawić 11 to nie powinienem ustawić GPIO_CRL_MODEx_1 i GPIO_CRL_MODEx_1 a jeżeli 01 to GPIO_CRL_MODEx_0?
    Domyślnie bity są ustawione na 1?
    Pozdrawiam ;)
  • #7
    Sareph
    Level 24  
    Pawel1243 wrote:
    "Nie masz do wyboru trybu 0 lub 1, masz do dyspozycji bity 0 lub 1. Znaczy, jeśli masz ustawić 11 to ustawiasz GPIO_CRL_MODEx_0 i GPIO_CRL_MODEx_1, razem daje Ci 11. Jak masz 01, to tylko GPIO_CRL_MODEx_0. Tak samo dla CNF. "

    jeżeli mam ustawić 11 to nie powinienem ustawić GPIO_CRL_MODEx_1 i GPIO_CRL_MODEx_1 a jeżeli 01 to GPIO_CRL_MODEx_0?
    Domyślnie bity są ustawione na 1?

    Na pewno nie MODE_1 i MODE_1 :D Innymi słowy jak masz tryb xy, to odpowiadają temu bity COSTAM_x i COSTAM_y (z 2 takich makr/stałych masz 4 możliwe kombinacje do poskładania), jak masz xyz, to masz stałe COSTAM_x, COSTAM_y, COSTAM_z, i tak dalej.
    W wypadku CRH i L, masz domyślnie ustawione CNF 01 i MODE 00.
  • #8
    Pawel1243
    Level 7  
    Rozumiem ze mam dwa bity do ustawienia : (skopiowane z pliku stm32f103xb.h)
    Code: c
    Log in, to see the code

    Jeżeli chcę ustawić
    Code: c
    Log in, to see the code
    to powinienem zrobić to w ten sposób:
    Code: c
    Log in, to see the code

    Mam w tabelce CNF0 jak i CNF1 w jaki spsób się do nich odwoływac aby ustawić odpowiednio bit?
    Jak kompilator rozróżni :
    Code: c
    Log in, to see the code

    od
    Code: c
    Log in, to see the code
    jak w jednym i drugim bity to 01?

    STM32 Nucleo F103 RB Przycisk na rejestrach. STM32 Nucleo F103 RB Przycisk na rejestrach.

    Kolega R-MIK nie wiem po co ta złośliwość? Jestem początkującym chcę nauczyć się programowania układów scalonych (hobby elektronika) staram się zaczynać od podstaw. Nie wszystko przychodzi mi łatwo bo nie jestem wykształcony w tym kierunku a w całkiem innym. Uważam że forum publiczne jest stworzone do pomocy a nie szyderstwa. Nawiązując do podanego przez kolegę linku:
    STM32 Nucleo F103 RB Przycisk na rejestrach.
  • #9
    Sareph
    Level 24  
    Pawel1243 wrote:
    Mam w tabelce CNF0 jak i CNF1 w jaki spsób się do nich odwoływac aby ustawić odpowiednio bit?
    Tak jak napisałeś. Po prostu albo go ustawiasz albo nie. A jak jest ustawiony to możesz skasować.

    Pawel1243 wrote:
    Jak kompilator rozróżni :
    Code: c
    Log in, to see the code

    od
    Code: c
    Log in, to see the code
    jak w jednym i drugim bity to 01?
    Nie rozróżni, dla kompilatora to dokładnie to samo. Kompilator ma tylko umieścić jakieś dane pod jakimś adresem pamięci, i to wszystko co go interesuje, on "nie wie" co to jest i do czego.
    Za to MCU to rozróżni po tym jak masz ustawiony MODE, jak MODE jest na input - to masz floating input, jak jest na output, to masz output open drain. Gdyby nie było oczywiste, to jak interpretowane jest CNF zależy od MODE.
  • #10
    Pawel1243
    Level 7  
    Czyli jak chcę ustawić mode na 11 to robię w ten sposób:
    Code: c
    Log in, to see the code

    A jak 01 to:
    Code: c
    Log in, to see the code

    Przepraszam że tak pytam ale muszę być pewny jak to działa bo jest to podstawa;)
    STM32 Nucleo F103 RB Przycisk na rejestrach.
    Pozdrawiam i dziękuję za pomoc;)
  • #11
    Sareph
    Level 24  
    Pawel1243 wrote:
    Czyli jak chcę ustawić mode na 11 to robię w ten sposób:
    Code: c
    Log in, to see the code

    A jak 01 to:
    Code: c
    Log in, to see the code

    Nie.

    Ja Ci już to pisałem chyba dwa razy, ale, jak chcesz 11, to:
    Code: c
    Log in, to see the code


    A jak 01, to:
    Code: c
    Log in, to see the code


    lub samo:

    Code: c
    Log in, to see the code


    Zależnie od tego czy bit 1 był wcześniej ustawiony (i trzeba go wtedy zdjąć) czy nie.

    Ewentualnie, bardziej uniwersalnie:
    Code: c
    Log in, to see the code



    To _0 na końcu albo _1, to nie jest wartość danego bitu a jego pozycja.
  • #12
    User removed account
    User removed account  
  • #13
    Pawel1243
    Level 7  
    Domyślnie CRL mam 01
    jeżeli chcę ustawić 00:
    GPIOA->CRL &= ~GPIO_CRL_MODE5_1;
    jeżeli 10 a poprzednio było 01:
    GPIOA->CRL &= ~GPIO_CRL_MODE5_0;
    GPIOA->CRL &= ~GPIO_CRL_MODE5_1;
    jeżeli 11 a poprzedni stan to 10:
    GPIOA->CRL &= ~GPIO_CRL_MODE5_0;
    Działanie na rejestrze polega na tym że mam zmieniać na przeciwny stan bitu lub go nie ruszać jak nie muszę i dlatego jak mam 01 (domyślne) a chcę 11 to wystarczy że zaneguję 0 operatorem &= ~ ?
    Kolega pisał że żeby zapisać 11 to muszę wykonać:
    Code: c
    Log in, to see the code
    tylko nie wiem po co ustawiać operatorem przypisania
    Code: c
    Log in, to see the code
    jak jest tam domyślnie 1.
  • #14
    User removed account
    User removed account  
  • #15
    Sareph
    Level 24  
    Pawel1243 wrote:
    Domyślnie CRL mam 01
    jeżeli chcę ustawić 00:
    GPIOA->CRL &= ~GPIO_CRL_MODE5_1;

    Nie, jeśli chesz mieć 01 -> 00, to:

    Code: c
    Log in, to see the code


    Pawel1243 wrote:
    jeżeli 10 a poprzednio było 01:
    GPIOA->CRL &= ~GPIO_CRL_MODE5_0;
    GPIOA->CRL &= ~GPIO_CRL_MODE5_1;

    Nie, powinno być:

    Code: c
    Log in, to see the code


    Pawel1243 wrote:
    jeżeli 11 a poprzedni stan to 10:
    GPIOA->CRL &= ~GPIO_CRL_MODE5_0;


    I ponownie, nie, bo powinno być:

    Code: c
    Log in, to see the code


    Pawel1243 wrote:
    Kolega pisał że żeby zapisać 11 to muszę wykonać:
    Code: c
    Log in, to see the code
    tylko nie wiem po co ustawiać operatorem przypisania
    Code: c
    Log in, to see the code
    jak jest tam domyślnie 1.


    To nie jest operator przypisania, no nie zupełnie. Ten operator rozwija się tak:

    Code: c
    Log in, to see the code


    A więc kompilator stworzy kod który odczyta rejestr, zmodyfikuje i zapisze z powrotem. RMW - Read Modify Write.

    Generalnie jest tak jak napisał R-MIK, skasować wszystkie ustawione bity i ustawić po swojemu, dlatego jak wyżej pisałem, pierwej

    Code: c
    Log in, to see the code

    A potem sobie ustaw ORem co tam chcesz.
  • #16
    Pawel1243
    Level 7  
    U mnie akurat aby wyzerować to muszę
    Code: c
    Log in, to see the code

    Potem ustawiam w sposób aby ustawić 11:
    Code: c
    Log in, to see the code


    Ogólnie nie mogę pojąć skąd kompilator wie czy odwołujemy się do mode0 czy do mode1 kompilując przykład poniżej:
    Code: c
    Log in, to see the code

    Jakby dało się ustawić coś typu Mode1=0 a Mode0=1 i CNF0=0 a CNF1-1 to wiem do którego bitu się odwołuje a poprzez MODE5_1 nie wiem czy zapełniam MODE0 czy MODE1;
    Dziękuję kolegom że pomagacie mi to zrozumieć ;)
  • Helpful post
    #17
    Sareph
    Level 24  
    Pawel1243 wrote:
    U mnie akurat aby wyzerować to muszę
    Code: c
    Log in, to see the code

    Potem ustawiam w sposób aby ustawić 11:
    Code: c
    Log in, to see the code

    Prawidłowo. A jakbyś uaktualnił CMSIS to byś miał i _Msk. ;)

    Pawel1243 wrote:
    Ogólnie nie mogę pojąć skąd kompilator wie czy odwołujemy się do mode0 czy do mode1 kompilując przykład poniżej:
    Code: c
    Log in, to see the code

    W tym przykładzie odwołujesz się do mode1.

    Pawel1243 wrote:

    Jakby dało się ustawić coś typu Mode1=0 a Mode0=1 i CNF0=0 a CNF1-1 to wiem do którego bitu się odwołuje a poprzez MODE5_1 nie wiem czy zapełniam MODE0 czy MODE1;

    Wiesz. Ustawiasz MODE1, MODEx_y - y tutaj to właśnie znaczy, który to bit. (a x - który pin).

    Pawel1243 wrote:
    Dziękuję kolegom że pomagacie mi to zrozumieć ;)
    Tylko jeszcze czytaj co piszemy, bo w/w to ja już usiluje wytłumaczyć drugi albo trzeci raz. :D
  • #18
    Pawel1243
    Level 7  
    Code: c
    Log in, to see the code


    Po tym mam 01

    Code: c
    Log in, to see the code

    Po tym 10
    Teraz już wiem ze MODEx_0 to Mode0 a MODEx_1 to Mode1 i wystarczy że czyszczę lub ustawiam w nich bit.
    To jest moje pierwsze podejście do mikrokontrolerów dlatego wszystko dla mnie jest nowe i bardzo dziękuję za wszelką pomoc, na gotowych bibliotekach zrobiłem nawet transmisję uart ale bardziej mnie interesuję programowanie na rejestrach gdzie wiem co robi i dlaczego.
  • #19
    Sareph
    Level 24  
    Pawel1243 wrote:
    Code: c
    Log in, to see the code


    Po tym mam 01

    Albo coś źle odczytujesz. ;P

    Pawel1243 wrote:
    To jest moje pierwsze podejście do mikrokontrolerów dlatego wszystko dla mnie jest nowe i bardzo dziękuję za wszelką pomoc;)
    To w zasadzie bardziej są podstawy C niż samych uC. Ale proszę bardzo.
  • #20
    Pawel1243
    Level 7  
    Ogólnie programowanie jak i uc są dla mnie nowe a nie chcę się uczyć po łepkach tylko cały poradnik zrozumieć a nie tylko przeczytać .
    Mylę się z 01?
    &= ~ zmienia mi na przeciwny bit? jest to operator and i neagacji
    |= czyli a|=1 to to samo co a=a|1 . Ustawia mi bit na 1
    Jeżeli się mylę to w jaki sposób ustawić 1 i 0?
  • #21
    User removed account
    User removed account  
  • #22
    Pawel1243
    Level 7  
    Dokładnie kolega R-MIK dopero zaczynam ale staram się sukcesywnie uczyć ;)

    Działanie poniżej ustawia Mode0 na 1 . Działanie wygląda CRL=CRL+GPIO_CRL_MODE5_0
    Code: c
    Log in, to see the code

    Działanie poniżej ustawia MODE1 na 0. CRL=CRL*~GPIO_CRL_MODE5_0
    Code: c
    Log in, to see the code

    Czyli według moich obliczeń GPIO_CRL_MODE5_x =1 i wartość poprzednia bitu nie ma znaczenia.
  • #23
    User removed account
    User removed account  
  • #24
    User removed account
    User removed account  
  • #25
    BlueDraco
    MCUs specialist
    R-MIK wrote:
    Nie bój sie assemblera. Procesory RISC maja niewiele prostych rozkazów.


    Platformy Kolega pomylił. W przypadku ARMa ani "niewiele" ani "prostych"; samo określenie ARM mianem RISC też dość dyskusyjne. Asembler ARM początkującego może jedynie wystraszyć.
    Problemy Autora wątku wynikają z nieznajomości operacji logicznych i języka C i mało mają wspólnego z mikrokontrolerami.
  • #26
    User removed account
    User removed account  
  • #27
    BlueDraco
    MCUs specialist
    RISC nie poznaje się po długości listy instrukcji, a po tym, co te instrukcje potrafią. Np. nie potrafią równocześnie przesyłać danych do pamięci i zmieniać wskaźnika stosu (PUSH/POP). W ARM jest PUSH/POP/LDM/STM, w dodatku na wielu rejestrach w jednej instrukcji - bardzo nieRISCowa cecha. Za to RISCową cechą jest rejestr LR i architektura typu Load-Store.
    Ogólnie RISC to jest procesor, który nie bardzo nadaje się do programowania przez człowieka w asemblerze - i pod tym względem ARM jest bardzo RISC. ;)
  • #28
    User removed account
    User removed account  
  • #29
    User removed account
    User removed account  
  • #30
    User removed account
    User removed account