eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika › sdcc i at89c51 - dostęp do pinu "na około"
Ilość wypowiedzi w tym wątku: 26

  • 1. Data: 2017-03-14 19:07:22
    Temat: sdcc i at89c51 - dostęp do pinu "na około"
    Od: Atlantis <m...@w...pl>

    Ciąg dalszy moich eksperymentów z archaicznymi mikrokontrolerami. ;)

    Już kiedyś pytałem, czy da się w jakiś sposób przesłać wygodną
    konstrukcję wskazującą bezpośrednio na pin (np. "P0_0") za pomocą
    wskaźnika w C. Otrzymałem odpowiedź, że się nie da i muszę to robić w
    sposób standardowy.

    Natknąłem się jednak na pewne problemy... Próbuję przeportować pewną
    bibliotekę do obsługi przycisków (debouncing + wykrywanie długiego
    wciśnięcia). Kod podpatrzony w jednej z książek pana Kardasia, z paroma
    moimi modyfikacjami.

    Generalnie sprowadza się do tego, że mam strukturę opisującą przycisk:

    typedef struct key {
    unsigned char *port;
    unsigned char pin:3;
    unsigned char state:4;
    unsigned int timer;
    void (*push_proc)(void);
    void (*long_proc)(void);
    } key_t;

    Struktura jest inicjowana za pomocą funkcji key_init(), która przypisuje
    argumenty do struktury przekazanej przez wskaźnik, czyli wygląda to w
    ten sposób:

    key_init(&button2, &P0, 0, funkcja, funkcja);

    Kolejne argumenty oznaczają: adres struktury, adres portu, numer pinu w
    porcie, wskaźnik na funkcję wykonywaną po krótkim wciśnięciu przycisku i
    wskaźnik na funkcję wykonywaną po przytrzymaniu przycisku.

    Potem stan przycisku jest cały czas sprawdzany wewnątrz funkcji
    key_update(), która przyjmuje za argument adres struktury.

    Tyle tytułem wprowadzenia.

    Sęk w tym, że kod nie chce działać. Drogą eliminacji doszedłem do tego, że:
    1) Same wejścia cyfrowe działają - odwołanie się do nich bezpośrednio
    daje pozytywny efekt.
    2) Działa także konstrukcja key_press = !(P0 & (1<<NUMER_PINU))
    3) Program wchodzi do funkcji key_update.

    NIE DZIAŁA natomiast następująca konstrukcja:

    key_press = !(*(key->port) & (1<<(key->pin)));

    Strukturę inicjuję podając dane właściwego portu i pinu, a pomimo tego
    wciskanie przycisku nie jest widoczne.

    I teraz pytanie: co jest nie tak. Czyżbym w sdcc i/lub at89c51 nie mógł
    przesyłać w ten sposób informacji o porcie? A może po prostu coś
    przeoczyłem i w powyższej linijce tkwił jakiś banalny błąd, który umyka
    mojej uwadze, gdy na nią patrzę?


  • 2. Data: 2017-03-14 19:48:57
    Temat: Re: sdcc i at89c51 - dostęp do pinu "na około"
    Od: "J.F." <j...@p...onet.pl>

    Użytkownik "Atlantis" napisał w wiadomości grup
    dyskusyjnych:oa9bgq$7fd$...@n...icm.edu.pl...
    >Natknąłem się jednak na pewne problemy... Próbuję przeportować pewną
    >bibliotekę do obsługi przycisków (debouncing + wykrywanie długiego
    >wciśnięcia). Kod podpatrzony w jednej z książek pana Kardasia, z
    >paroma
    >moimi modyfikacjami.

    Atlantisie - na moj gust, jak bedziesz takie ambitne struktury robil
    ... to ci pamieci zabraknie :-)

    Duza ta klawiatura ? Regularnie zrobiona ?
    Moze regularne metody lepsze.

    >Generalnie sprowadza się do tego, że mam strukturę opisującą
    >przycisk:
    typedef struct key {
    unsigned char *port;
    unsigned char pin:3;
    unsigned char state:4;

    * ciekawe czy ten kompilator sobie radzi z tym :3.
    Skoro deklaracje przyjmuje, to niby powinien.

    unsigned int timer;
    void (*push_proc)(void);
    void (*long_proc)(void);
    } key_t;

    >Struktura jest inicjowana za pomocą funkcji key_init(), która
    >przypisuje
    >argumenty do struktury przekazanej przez wskaźnik, czyli wygląda to w
    >ten sposób:
    >key_init(&button2, &P0, 0, funkcja, funkcja);

    >Kolejne argumenty oznaczają: adres struktury, adres portu, numer pinu
    >w
    >porcie, wskaźnik na funkcję wykonywaną po krótkim wciśnięciu
    >przycisku i
    >wskaźnik na funkcję wykonywaną po przytrzymaniu przycisku.
    >Potem stan przycisku jest cały czas sprawdzany wewnątrz funkcji
    >key_update(), która przyjmuje za argument adres struktury.

    Ciekawe, na ile to optymalne. Przy kilku przyciskach ... moze ..

    >NIE DZIAŁA natomiast następująca konstrukcja:
    >key_press = !(*(key->port) & (1<<(key->pin)));

    Zlikwiduj testowo te :3, :4. Albo sobie wydrukuj ... albo wrzuc jak
    kompilator to na assembler zamienil.

    >Strukturę inicjuję podając dane właściwego portu i pinu, a pomimo
    >tego
    >wciskanie przycisku nie jest widoczne.

    >I teraz pytanie: co jest nie tak. Czyżbym w sdcc i/lub at89c51 nie
    >mógł
    >przesyłać w ten sposób informacji o porcie?

    89c51 czy 89c52 ?
    Bo tu chyba jest pies pogrzebany
    http://www.8052.com/tutaddr.phtml

    Indirect addressing always refers to Internal RAM; it never refers to
    an SFR.

    MOV R0,#99h ;Load the address of the serial port
    MOV @R0,#01h ;Send 01 to the serial port -- WRONG!!

    This is not valid. Since indirect addressing always refers to Internal
    RAM these two instructions would write the value 01h to Internal RAM
    address 99h on an 8052. On an 8051 these two instructions would
    produce an undefined result since the 8051 only has 128 bytes of
    Internal RAM.

    A aby zaadresowac taka nieokreslona komorke pamieci, kompilator musi
    skorzystac z adresowania posredniego.

    Swoja droga on tak to napisal, jakby pod 8051 bylo tak samo ... prawde
    mowiac nie pamietam, wydaje mi sie, ze mozna bylo adresowac porty @Rn.

    >2) Działa także konstrukcja key_press = !(P0 & (1<<NUMER_PINU))

    a ta kompilator moze skompilowac wstawiajac adres na stale.

    J.


  • 3. Data: 2017-03-14 19:54:09
    Temat: Re: sdcc i at89c51 - dostęp do pinu "na około"
    Od: Janusz <j...@o...pl>

    W dniu 2017-03-14 o 19:07, Atlantis pisze:
    > Ciąg dalszy moich eksperymentów z archaicznymi mikrokontrolerami. ;)
    >
    > Już kiedyś pytałem, czy da się w jakiś sposób przesłać wygodną
    > konstrukcję wskazującą bezpośrednio na pin (np. "P0_0") za pomocą
    > wskaźnika w C. Otrzymałem odpowiedź, że się nie da i muszę to robić w
    > sposób standardowy.
    >
    > Natknąłem się jednak na pewne problemy... Próbuję przeportować pewną
    > bibliotekę do obsługi przycisków (debouncing + wykrywanie długiego
    > wciśnięcia). Kod podpatrzony w jednej z książek pana Kardasia, z paroma
    > moimi modyfikacjami.
    >
    > Generalnie sprowadza się do tego, że mam strukturę opisującą przycisk:
    >
    > typedef struct key {
    > unsigned char *port;
    > unsigned char pin:3;
    > unsigned char state:4;
    > unsigned int timer;
    > void (*push_proc)(void);
    > void (*long_proc)(void);
    > } key_t;
    >
    > Struktura jest inicjowana za pomocą funkcji key_init(), która przypisuje
    > argumenty do struktury przekazanej przez wskaźnik, czyli wygląda to w
    > ten sposób:
    >
    > key_init(&button2, &P0, 0, funkcja, funkcja);
    >
    > Kolejne argumenty oznaczają: adres struktury, adres portu, numer pinu w
    > porcie, wskaźnik na funkcję wykonywaną po krótkim wciśnięciu przycisku i
    > wskaźnik na funkcję wykonywaną po przytrzymaniu przycisku.
    >
    > Potem stan przycisku jest cały czas sprawdzany wewnątrz funkcji
    > key_update(), która przyjmuje za argument adres struktury.
    >
    > Tyle tytułem wprowadzenia.
    >
    > Sęk w tym, że kod nie chce działać. Drogą eliminacji doszedłem do tego, że:
    > 1) Same wejścia cyfrowe działają - odwołanie się do nich bezpośrednio
    > daje pozytywny efekt.
    > 2) Działa także konstrukcja key_press = !(P0 & (1<<NUMER_PINU))
    > 3) Program wchodzi do funkcji key_update.
    >
    > NIE DZIAŁA natomiast następująca konstrukcja:
    >
    > key_press = !(*(key->port) & (1<<(key->pin)));
    >
    > Strukturę inicjuję podając dane właściwego portu i pinu, a pomimo tego
    > wciskanie przycisku nie jest widoczne.
    >
    > I teraz pytanie: co jest nie tak. Czyżbym w sdcc i/lub at89c51 nie mógł
    > przesyłać w ten sposób informacji o porcie? A może po prostu coś
    > przeoczyłem i w powyższej linijce tkwił jakiś banalny błąd, który umyka
    > mojej uwadze, gdy na nią patrzę?
    >
    Zobacz w asemblerze jak to kompilator przetłumaczył, może się okazać że
    poszedł w maliny.

    --
    Pozdr
    Janusz


  • 4. Data: 2017-03-14 21:03:03
    Temat: Re: sdcc i at89c51 - dostęp do pinu "na około"
    Od: Atlantis <m...@w...pl>

    W dniu 2017-03-14 o 19:48, J.F. pisze:

    > Atlantisie - na moj gust, jak bedziesz takie ambitne struktury robil ...
    > to ci pamieci zabraknie :-)

    Pilnuję zawartości pliku .mem i na razie mieszczę się w wyznaczonej
    normie. Przycisków jest kilka i tylko niektóre z nich wymagają podwójnej
    funkcjonalności przyciśnięcie/przytrzymanie. Pozostałym zrobię prostszy
    debouncing. ;)


    > * ciekawe czy ten kompilator sobie radzi z tym :3.
    > Skoro deklaracje przyjmuje, to niby powinien.

    Wygląda na to, że sobie radzi. Po dodaniu pól bitowych do definicji typu
    struktury zużycie pamięci zmniejszyło się o kilka bajtów. I z całą
    pewnością pola bitowe nie są przyczyną, bo na początku ich nie było, a
    problem występował. ;)



    > 89c51 czy 89c52 ?
    > Bo tu chyba jest pies pogrzebany
    > http://www.8052.com/tutaddr.phtml

    89c51


    > Swoja droga on tak to napisal, jakby pod 8051 bylo tak samo ... prawde
    > mowiac nie pamietam, wydaje mi sie, ze mozna bylo adresowac porty @Rn.

    Innymi słowy: da się jakoś dostać do tego portu z poziomu C? ;)


  • 5. Data: 2017-03-14 21:09:05
    Temat: Re: sdcc i at89c51 - dostęp do pinu "na około"
    Od: Zbych <a...@o...pl>

    W dniu 14.03.2017 o 19:07, Atlantis pisze:

    > NIE DZIAŁA natomiast następująca konstrukcja:
    >
    > key_press = !(*(key->port) & (1<<(key->pin)));
    >
    > Strukturę inicjuję podając dane właściwego portu i pinu, a pomimo tego
    > wciskanie przycisku nie jest widoczne.

    Używasz 51 czy 52? Bo w 52 odwołanie pośrednie do adresu 80h (port P0),
    spowoduje odwołanie do pamięci idata pod adres 80h.


  • 6. Data: 2017-03-14 21:21:58
    Temat: Re: sdcc i at89c51 - dost?p do pinu "na oko?o"
    Od: a...@m...uni.wroc.pl

    Atlantis <m...@w...pl> wrote:
    > Ci?g dalszy moich eksperyment?w z archaicznymi mikrokontrolerami. ;)
    >
    > Ju? kiedy? pyta?em, czy da si? w jaki? spos?b przes?a? wygodn?
    > konstrukcj? wskazuj?c? bezpo?rednio na pin (np. "P0_0") za pomoc?
    > wska?nika w C. Otrzyma?em odpowied?, ?e si? nie da i musz? to robi? w
    > spos?b standardowy.
    >
    > Natkn??em si? jednak na pewne problemy... Pr?buj? przeportowa? pewn?
    > bibliotek? do obs?ugi przycisk?w (debouncing + wykrywanie d?ugiego
    > wci?ni?cia). Kod podpatrzony w jednej z ksi??ek pana Kardasia, z paroma
    > moimi modyfikacjami.
    >
    > Generalnie sprowadza si? do tego, ?e mam struktur? opisuj?c? przycisk:
    >
    > typedef struct key {
    > unsigned char *port;
    > unsigned char pin:3;
    > unsigned char state:4;
    > unsigned int timer;
    > void (*push_proc)(void);
    > void (*long_proc)(void);
    > } key_t;
    <snip>
    > NIE DZIA?A natomiast nast?puj?ca konstrukcja:
    >
    > key_press = !(*(key->port) & (1<<(key->pin)));

    Przy dostepie do portow powinno byc 'volatile', np:

    typedef struct key {
    volatile unsigned char *port;
    ....

    Twoj problem jest prawdopodobnie zwiazany z at89c51, ale
    bez 'volatile' mozesz miec problem na dowolnym procku.

    --
    Waldek Hebisch


  • 7. Data: 2017-03-14 21:34:40
    Temat: Re: sdcc i at89c51 - dostęp do pinu "na około"
    Od: Atlantis <m...@w...pl>

    W dniu 2017-03-14 o 19:54, Janusz pisze:

    > Zobacz w asemblerze jak to kompilator przetłumaczył, może się okazać że
    > poszedł w maliny.

    Niestety, nie znam asemblera, więc kod niewiele mi mówi... :(

    ; src/SuperDebounce.c:18: key_press = !(*(key->port) & (1<<(key->pin)));
    mov _key_update_key_1_13,dpl
    mov (_key_update_key_1_13 + 1),dph
    mov (_key_update_key_1_13 + 2),b
    lcall __gptrget
    mov r2,a
    inc dptr
    lcall __gptrget
    mov r3,a
    inc dptr
    lcall __gptrget
    mov r4,a
    mov dpl,r2
    mov dph,r3
    mov b,r4
    lcall __gptrget
    mov r2,a
    mov a,#0x03
    add a,_key_update_key_1_13
    mov r1,a
    clr a
    addc a,(_key_update_key_1_13 + 1)
    mov r3,a
    mov r4,(_key_update_key_1_13 + 2)
    mov dpl,r1
    mov dph,r3
    mov b,r4
    lcall __gptrget
    anl a,#0x07
    mov r1,a
    mov b,r1
    inc b
    mov a,#0x01
    sjmp 00176$
    00174$:
    add a,acc
    00176$:
    djnz b,00174$
    mov r1,a
    anl ar2,a
    mov a,r2
    cjne a,#0x01,00177$
    00177$:
    clr a
    rlc a


  • 8. Data: 2017-03-14 22:02:07
    Temat: Re: sdcc i at89c51 - dost?p do pinu "na oko?o"
    Od: Atlantis <m...@w...pl>

    W dniu 2017-03-14 o 21:21, a...@m...uni.wroc.pl pisze:

    > Twoj problem jest prawdopodobnie zwiazany z at89c51, ale
    > bez 'volatile' mozesz miec problem na dowolnym procku.

    Dodałem "volatile", ale nie ma żadnej zmiany. Więc jednak nie o to
    chodziło...

    Powinienem przyjąć, że w przypadku tych MCU nie da się odwołać do portu
    przez wskaźnik? Mogę to obejść w inny sposób - najprościej będzie chyba
    przekazywać normalną liczbę i w zależności od jej wartości, odwoływać
    się do konkretnego portu, określonego twardo w kodzie. Sądziłem tylko,
    że może będzie się to dało zrobić bardziej elegancko. ;)


  • 9. Data: 2017-03-14 22:29:02
    Temat: Re: sdcc i at89c51 - dostęp do pinu "na około"
    Od: Atlantis <m...@w...pl>

    Ok, zrobiłem banalny "workaround" rezygnując z przekazywania adresu
    portu przez wskaźnik. Zamiast tego przekazuje jego numer i na jego
    podstawie, za pomocą sekwencji if-ów wykonuję operację na właściwym
    porcie. ;) Dodatkowo za pomocą pól bitowych udało mi się zmieścić
    identyfikator portu razem z identyfikatorem pinu i stanem maszyny stanów
    w jednej ośmiobitowej zmiennej. :)

    To może zapytam jeszcze o jedną rzecz, z którą obecnie walczę i chwilowo
    wygrać nie mogę. Projekt wykorzystuje RTC na DS1307. Sam układ działa
    (przetestowałem go za pomocą Arduino). Nie mogę jednak za nic
    skomunikować go z at89c51.

    Korzystam z tej biblioteki:
    http://saeedsolutions.blogspot.com/2012/11/interfaci
    ng-of-8051-with-ds1307-rtc.html

    Czy winę może ponosić fakt, iż mój projekt dość intensywnie korzysta z
    przerwań? Powinienem je wyłączać na czas każdej transmisji I2C, czy
    raczej nie tutaj szukać przyczyny?


  • 10. Data: 2017-03-15 01:42:31
    Temat: Re: sdcc i at89c51 - dostęp do pinu "na około"
    Od: "J.F." <j...@p...onet.pl>

    Dnia Tue, 14 Mar 2017 22:29:02 +0100, Atlantis napisał(a):
    > To może zapytam jeszcze o jedną rzecz, z którą obecnie walczę i chwilowo
    > wygrać nie mogę. Projekt wykorzystuje RTC na DS1307. Sam układ działa
    > (przetestowałem go za pomocą Arduino). Nie mogę jednak za nic
    > skomunikować go z at89c51.
    >
    > Korzystam z tej biblioteki:
    > http://saeedsolutions.blogspot.com/2012/11/interfaci
    ng-of-8051-with-ds1307-rtc.html
    >
    > Czy winę może ponosić fakt, iż mój projekt dość intensywnie korzysta z
    > przerwań? Powinienem je wyłączać na czas każdej transmisji I2C, czy
    > raczej nie tutaj szukać przyczyny?

    Raczej nie tutaj.
    Ogolnie - predkosc w I2C moze byc dosc dowolna.
    Za szybko nie wolno ... ale 100kHz chyba nie przekraczasz,
    za wolno ... tylko niektore uklady maja jakies timeouty,
    ale az tak bardzo przerwania Ci chyba nie spowalniaja.

    Za to oczywiscie w przerwaniu mozna duzo sp* - wiec moze wylacz i
    zobacz czy lepiej dziala.

    J.

strony : [ 1 ] . 2 . 3


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: