logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Bascom - Jednoczesny odczyt stanu 9 portów w Atmega8/16, jak to zrobić?

grzechu9009 10 Paź 2012 11:58 6837 38
REKLAMA
  • #1 11396661
    grzechu9009
    Poziom 11  
    Czy w Bascomie i Atmedze8 lub 16 jest możliwy jednoczesny odczyt stanu z kilku (9) portów?

    W moim urządzeniu chodzi o to że jeżeli przykładowo na głównym czujniku pojawi się stan wysoki i na którymś z 9 czujników również urządzenie ma się zatrzymać (poprzez reset portu pod który podłączę przekaźnik). Mógłbym zrobić pętlę i napisać np "IF pind.1=1 and pinb.1=1 then reset portc.0" i tak 9 razy, ale to zajmie zbyt długo, bo będzie się odbywać po kolei :( a ja potrzeuje żeby takie sprawdzanie odbyło się kilka razy na sekundę.

    PS. Wie ktoś gdzie w bascomie lub jego symulatorze odnaleźć informacje o czasie trwania pętli?

    Dodano po 1 [minuty]:

    Zapomniałem dodać że każdy z 9 czujników musi sygnalizować osobno żeby określić na którym jest awaria
  • REKLAMA
  • #2 11396740
    Mol
    Poziom 30  
    Jak z 9-ciu czujników zsumujesz sygnał i podasz na zewnętrzne przerwanie INT0 , to nie będziesz musiał bez przerwy sprawdzać stanu tych czujników. Jak przyjdzie zewnętrzne przerwanie z któregokolwiek , to zrobisz stop , a później możesz sprawdzić z którego to przyszło.
  • #3 11396758
    slawko_k
    Poziom 35  
    Najpierw piszesz że 9 if'ów za długo trwa a potem że chcesz tylko tylko kilak razy na sekundę sprawdzać więc ciężko zrozumieć na czym ci na prawdę najbardziej zależy.

    Jeżeli faktycznie 9 if;ów nie może być to zrób jak radzi kolega wyżej albo zmień mege8 na mege88 lub podobną tej rodziny i bez zmiany schematu możesz na przerwaniach każda nogę sprawdzić.
  • #4 11396772
    grzechu9009
    Poziom 11  
    chcialbym to sprawdzic 10 razy na sekunde. Nie wiem ile bedzie trwac jeden If, moze jakas podpowiedz jak zmerzyc ten czas? Moze w bascomie gdzies pisze?
  • #5 11396820
    slawko_k
    Poziom 35  
    W symulatorze podaje czas.
    Procesor jest szybszy niż myślisz. Nie zdążysz okiem mrugnąć jak ci 1000 IF'ów zrobi
  • #6 11396848
    grzechu9009
    Poziom 11  
    moze glupia prosba, ale czy moglbys mi wskazac gdzie w symulatorze tego szukac? Nie znalazlem nic takiego :-(

    Co do czasu trwania if-ow sugerowalem sie tym ze w symulatorze dlugo to trwalo :-P

    Rozumiem ze ma na to wplyw taktowanie Atmegi? Im wyzsza wartosc kwarcu tym szybciej?
  • Pomocny post
    #7 11396856
    Mundi1970
    Poziom 24  
    grzechu9009 napisał:
    chcialbym to sprawdzic 10 razy na sekunde. Nie wiem ile bedzie trwac jeden If, moze jakas podpowiedz jak zmerzyc ten czas? Moze w bascomie gdzies pisze?


    Twoje wolne IF pind.1=1 and pinb.1=1 then reset portc.0
    przy 16 MHz wykonuje się przez 26 cykili, 0,001625 mS niecałe 2 μs (1 μs = 1/1 000 000 s). :)

    Bascom - Jednoczesny odczyt stanu 9 portów w Atmega8/16, jak to zrobić?
  • REKLAMA
  • #8 11396868
    grzechu9009
    Poziom 11  
    tyle ze u mnie w tym miejscu jest 0 :-( moze dlatego ze nie dziala w petli tylko przelatuje po ifach i koniec programu. Potem to sprawdze, dzieki :-)
  • Pomocny post
    #9 11397234
    Konto nie istnieje
    Poziom 1  
  • #10 11403286
    grzechu9009
    Poziom 11  
    :not: dopiero teraz się skapnąłem że nie jest koniecznym dawanie na końcu end if jeżeli ma to być tylko jedna instrukcja po if :)

    Dlatego wcześniej mi się dłużyło :D
  • Pomocny post
    #11 11406301
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • Pomocny post
    #12 11406537
    Mundi1970
    Poziom 24  
    Cytat:
    IF pind.1=1 and pinb.1=1 then reset portc.0 zajmuje 26 cykli? Dziadostwo.
    Gdybyś się BARDZO śpieszył to możesz zrobić tak: ...

    Jeżeli napiszę się to trochę inaczej:

    Kod: text
    Zaloguj się, aby zobaczyć kod

    po kompilacji jest:

    8:        If Pind.1 = 1 Then
    +00000047:   9B81        SBIS      0x10,1         Skip if bit in I/O register set
    +00000048:   940C004E    JMP       0x0000004E     Jump
    9:           If Pinb.1 = 1 Then
    +0000004A:   9BB1        SBIS      0x16,1         Skip if bit in I/O register set
    +0000004B:   940C004E    JMP       0x0000004E     Jump
    10:             Reset Portc.0
    +0000004D:   98A8        CBI       0x15,0         Clear bit in I/O register
    13:       !nop  
    +0000004E:   0000        NOP

    Zamiast RJMP jest dłuższa instrukcja JMP, nie próbowałem z włączoną optymalizacją.
  • #14 11802960
    grzechu9009
    Poziom 11  
    Witam ponownie, odkopuje temat. Odczyt z 9 czujników na wspomnianych wyżej IF-ach się spisał "na styk". Teraz potrzebuje sprawdzić stan 18 czujników (w tym samym czasie, najlepiej jak najszybciej)

    czy mogę to zrobić tak jak polecił kolega Saabotaz:

    Saabotaz napisał:
    Jednoczesny odczyt zawsze był możliwy, np tak:

    Kod Basic4GL - [rozwiń]
     
    config portA = input
    porta = 255
     
    dim odczyt as byte
     
    '----- odczyt
    odczyt = porta
     


    Już prościej się nie da. Potem możesz użyć powolnych IFów żeby sprawdzić bity.


    tylko w formie:

    Pomiar:
    Do
    Bitwait PINC.1, set

    If Pind = 1 Then Reset Pinc.2

    If Pinb = 1 Then Reset Pinc.2

    Loop


    Chodzi mi o to żeby nie sprawdzać po kolei pojedyńczych linii każdego portu tylko całe porty, jeżeli zmieni się stan domyślnie ustawiony na 0 w którejś z końcówek pinb lub pind, końcówka Pinc.2 da sygnał na przekaźnik a ten wyłączy maszynę. Czy tak napisany program zadziała?

    Dodano po 11 [minuty]:

    Powinno być: ...then Reset Portc.2
  • #15 11803360
    slawko_k
    Poziom 35  
    jeśli dobrze zrozumiałem treść to warunek powinien być
    if pind<>0 then reset pinc.2

    bo linijka
    If Pind = 1 Then Reset Pinc.2
    zareague tylko na samotną nóżke pind.1
  • #16 11803408
    grzechu9009
    Poziom 11  
    i to sprawi że jeżeli na którymś z wejść należących do pinb, pinc, czy tam pind (oczywiście to jest do wglądu w specyfikacje atmegi, ale to na potem) stan zmieni się na wysoki instrukcja po "then" się wykona?

    Jeszcze jedno, chciałbym potem sprawdzic na którym z tych 18 czujników wystąpiła awaria (co za tym idzie zmiana stanu na pinie) Jak myslisz, mozna to sprawdzic na if-ach dla poszczególnych pinów?

    A może znasz jakiś jeszcze inny sposób (PROSTY) żeby jak najszybciej sprawdzić zmianę stanu na 18 wejściach do uC?
  • #17 11803636
    slawko_k
    Poziom 35  
    odnośnie zmiany stanu

    do
    if pind<> pind_old then
    ..........
    ............
    pind_old=pind
    end if
    loop
  • #18 11803920
    grzechu9009
    Poziom 11  
    Czyli:

    do
    if pinb<> pinb_old then
    if pinc<> pinc_old then
    if pind<> pind_old then
    pinb_old=pinb
    pinc_old=pinc
    pind_old=pind
    end if
    loop


    tylko gdzie dac reset port ? :P
  • #19 11804793
    Konto nie istnieje
    Poziom 1  
  • #20 11804955
    grzechu9009
    Poziom 11  
    DZIĘKI za dokładne opisanie :)

    A czy mógłbyś mi napisać dlaczego PIND =&B00100000 =32 ? Skąd te 32, czy to był tylko przykład, czy faktycznie po wpisaniu jakiejś formuły stan poszczególnych bitów przelicza się na jakąś tam wartość, w tym przypadku 32?
  • REKLAMA
  • Pomocny post
    #21 11805811
    Mol
    Poziom 30  
    32 binarnie to 00100000
  • #22 11808695
    grzechu9009
    Poziom 11  
    Kod: text
    Zaloguj się, aby zobaczyć kod
    Pomiar:


    Mniej więcej tak miało by to wyglądać wg tego co napisał kolega emarcus ?
    Bo coś mi się widzi że chyba nie :P Poproszę o nakierunkowanie :)

    Dodano po 18 [minuty]:

    Tylko jest jedno ale. To zajmuje 45 cykli, czyli tyle ile jakbym to robił po Ifach dla każdego portu.

    Dodano po 9 [minuty]:

    Sorki, na ifach byłyby 72 cykle (4 na każdy)
  • Pomocny post
    #23 11808879
    Konto nie istnieje
    Poziom 1  
  • #25 11810714
    grzechu9009
    Poziom 11  
    Ponawiam prośbę o poprawienie, bądź udzielenie wskazówek co do mojego fragmentu kodu :)
  • #26 11811185
    Mol
    Poziom 30  
    If Pind chyba powinieneś wpisać po kropce konkretną nóżkę np. If Pind.1 . Jeżeli chodzi o cały port to piszesz PORTD <>
  • Pomocny post
    #27 11811580
    Konto nie istnieje
    Poziom 1  
  • #28 11817615
    grzechu9009
    Poziom 11  
    Nie mam ściśle określonej liczby cykli, chce po prostu sprawdzić czujniki jak najszybciej. Zamiast Megi8 użyje AtMegi16 żeby uprościć sprawę wyświetlacza, po prostu podłącze go do dodatkowych portów A. Wyświetlacz LCD bedzie 2x16 ewentualnie 2x8.

    Dzięki za kolejny dobry przykład :) Rozumiem z niego że Temp to będzie "dim Temp As Byte", tylko jak potem rozszyfrować otrzymaną wartość i wyśłać ją poleceniem Lcd żeby mieć na wyswietlaczu numer portu, bądź portów (bo przecież może się okazać że bład wystąpi na wiecej niż jednym) ?
  • #29 11818702
    Konto nie istnieje
    Poziom 1  
  • #30 11818971
    grzechu9009
    Poziom 11  
    Ok, super :) Kolejne dzięki :)

    To wygląda następująco: czujnik zamontowany w maszynie jest to czujnik indukcyjny PNP podłączony to transoptora PC817. Tylko że troche zrypałem, bo nie napisałem o tym na poczatku. Ten transoptor ma wbudowany tranzystor NPN czyli w momencie kiedy dioda załączy tranzystor w transoptorze na atmegę pójdzie GND (tak mi się wydaje) więc muszę w ustawieniach pinów ustawić je na stan wysoki a w momencie kiedy czujnik coś wykryje transoptor się załączy i zrobi na pinie stan niski (mam nadzieję że nic nie pokręciłem)
    Bascom - Jednoczesny odczyt stanu 9 portów w Atmega8/16, jak to zrobić?

    podłączyłem wg schematu, tam gdzie +12 jest wyjście z czujnika indukcyjnego :)

    Dodano po 6 [minuty]:

    Możliwe zę wystarczy np zamiast

    If Pinc > 0 Then
    Flag = 1
    Reset Portc.2
    Temp = Pinc + 10
    End If

    zrobić

    If Pinc < 255 Then
    Flag = 1
    Reset Portc.2
    Temp = Pinc + 10
    End If


    Jeszcze jedno czy NAPRAWDĘ konieczne jest dodawanie R1 tak jak na tym przykładzie? Bo nie dam rady go wkomponować w płytkę przy 18 transoptorach :(

    Bascom - Jednoczesny odczyt stanu 9 portów w Atmega8/16, jak to zrobić?
REKLAMA