Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[bascom] IF - jak sprawdzić kilka warunków jednocześnie?

17 Sty 2009 02:46 9224 15

  • Poziom 20  
    Witam, pisałem taki prosty program w BASCOMIE do odczytu z klawiatury kodu. Każda cyfra była przesyłana po kolei do zmiennej a,b,c,d, i na koniec napotkałem na problem.
    Nie potrafię sprawdzić czy kod wpisany z klawiatury jest poprawny.

    Jeśli jest jeden warunek, to wiem jak to napisać:

    Code:
    if a=1 then goto kod_poprawny


    lub

    Code:
    if a=1 then 
    
    goto kod_poprawny
    else
    goto bledny_kod
    end if


    Ale jeśli mam sprawdzić kilka jednocześnie, to jak to zapisać?

    Code:
    'sprawdzenie kodu
    
    if a=1 then (co tu wpisać)
    if b=2 then
    if c=3 then
    if d=4 then
       goto kod_poprawny
    else
       goto bledny_kod
    end if


    Jak użyć komendy if then else end if żeby sprawdzić kilka warunków na raz?
    Może jakąś inną komendę użyć? no case?
  • Poziom 28  
    if a=1 and b=2 then
  • Poziom 23  
    Używając właśnie operatorów logicznych
    Code:
    and, or

    lub zagnieżdżając pętle
    Code:
    if a=2 then
    
       if b>10 then
          if pinb.0=0 then
          ...
          end if
       else
          ...
       end if
    end if

  • Poziom 20  
    Używałem and i or ale czy to możliwe ze wyskoczył błąd jak użyłem aż czterech?

    if a=1 and b=2 and c=1 and d=1 then
  • Poziom 23  
    karolczyzycki napisał:
    Używałem and i or ale czy to możliwe ze wyskoczył błąd jak użyłem aż czterech?

    if a=1 and b=2 and c=1 and d=1 then
    Możliwe jest wszystko :)
    To co napisałeś jest poprawne o ile dalej w kodzie i wcześniej wszystko jest poprawne. Pokaż cały kod to zobaczymy co jest źle, albo chociaż napisz jaki to błąd wyskoczył. My wróżkami nie jesteśmy.
    Taki kod jest poprawny:
    Code:
    Dim A As Byte , B As Byte , C As Byte , D As Byte
    

    If A = 1 And B = 2 And C = 1 And D = 1 Then
       
    End If

    Do : Loop : End

  • Poziom 20  
    Linijka:
    Code:
    If C = 1 And D = 1 And E = 1 And F = 1 Then Goto Ok

    "sama" się chyba naprawiła

    Tak wygląda kod, na własne potrzeby, a raczej z powodu błędów, musiałem dodać linijki wyświetlające jaką cyfrę wciskam, później oczywiście nie powinno tego być
    Program działa, do momentu gdy odczytaną z klawiatury zmienną B ma być przypisana do C,D,E,F

    Wgrałem program i każdą zmienną wyświetla jako "0" , czyli nie przypisuje tej odczytanej B ani do C,D,E,F.
    Czy powodem jest to że po przejściu do podprogramu zmienna jest kasowana?

    Code:
    $regfile = "m16def.dat"
    
    $crystal = 16000000
    $baud = 19200
    $hwstack = 32
    $swstack = 10
    $framesize = 40



    'Deklaracje zmiennych
    Dim B As Byte
    Dim C As Byte
    Dim X As Byte
    Dim Y As Byte
    Dim D As Byte
    Dim E As Byte
    Dim F As Byte
    Dim G As Byte

    'Ustawienia
    Config Kbd = Porta
    Config Lcdpin = Pin , Rs = Portc.2 , E = Portc.3 , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7
    Config Lcd = 16 * 2
    Config Portc.1 = Output
    Set Portc.1
    Cursor Off
    X = 0


    'pętla główna
    Do

    Odczyt_kawiatury:
       Locate 1 , 1
       Lcd "Brak klawisza"
       Locate 2 , 13
       B = Getkbd()
       If B = 0 Then Goto Dekoder
       If B = 1 Then Goto Dekoder
       If B = 2 Then Goto Dekoder
       If B = 3 Then Goto Dekoder
       If B = 4 Then Goto Dekoder
       If B = 5 Then Goto Dekoder
       If B = 6 Then Goto Dekoder
       If B = 7 Then Goto Dekoder
       If B = 8 Then Goto Dekoder
       If B = 9 Then Goto Dekoder
       If B = 10 Then Goto Dekoder
       If B = 11 Then Goto Dekoder
       If B = 12 Then Goto Dekoder
       If B = 13 Then Goto Dekoder
       If B = 14 Then Goto Dekoder
       If B = 15 Then Goto Dekoder
       If B = 16 Then Goto Odczyt_kawiatury
       Loop
       End



    Dekoder:
          Incr X
          Cls
          Locate 2 , 7
          Lcd "proba" ; X

          Locate 1 , 1
          Lcd "cyfr" ; B
          Waitms 400

       Select Case X

          Case 1 : B = C
            Cls
            Lcd C
            Waitms 1000

         Case 2 : B = D
            Cls
            Lcd D
            Waitms 1000

          Case 3 : B = E
            Cls
            Lcd E
            Waitms 1000

          Case 4 : B = F
            Cls
            Lcd F
            Waitms 1000

          Case 5 : Goto Sprawdzam_kod


       Case Else
       Goto Odczyt_kawiatury
       End Select
       Cls
       Goto Odczyt_kawiatury


    Sprawdzam_kod:
       Cls
       Locate 1 , 1
       Lcd "Sprawdzam KOD"
       Waitms 700
          If C = 1 And D = 1 And E = 1 And F = 1 Then Goto Ok
       Goto Zly


    Ok:
        Cls
        Locate 1 , 1
        Lcd "kod poprawny"
        Waitms 3000
        Cls
        X = 0
        Goto Odczyt_kawiatury


    Zly:
          Cls
          Locate 1 , 1
          Lcd "Bledny kod"
          Waitms 3000
          Cls
          X = 0
          Goto Odczyt_kawiatury
  • Poziom 32  
    Zamiast tego:
    Code:
    If B = 0 Then Goto Dekoder
    
       If B = 1 Then Goto Dekoder
       If B = 2 Then Goto Dekoder
       If B = 3 Then Goto Dekoder
       If B = 4 Then Goto Dekoder
       If B = 5 Then Goto Dekoder
       If B = 6 Then Goto Dekoder
       If B = 7 Then Goto Dekoder
       If B = 8 Then Goto Dekoder
       If B = 9 Then Goto Dekoder
       If B = 10 Then Goto Dekoder
       If B = 11 Then Goto Dekoder
       If B = 12 Then Goto Dekoder
       If B = 13 Then Goto Dekoder
       If B = 14 Then Goto Dekoder
       If B = 15 Then Goto Dekoder
       If B = 16 Then Goto Odczyt_kawiatury


    zastosuj Select Case i staraj się nie używać goto jeżeli już musisz to robić to skorzystaj z gosub.
  • Poziom 36  
    Witam !
    Pokazuję błąd ponieważ sprawdzasz stany portów !
    Z tego co wiem stan portów AVR to zero lub jedynka. !
    źle jest B=2 . napisz B=1 lub B=0
    Może być albo 0 albo 1.
    Pozdrawiam Stefan Amator

  • Poziom 20  
    Jak mogę nie używać, goto czy gosub jeśli po każdorazowym odczytaniu program musi coś zrobić? np odkodować cyfrę i zapisać za każdym razem do innej zmiennej?

    Code:
    B = Getkbd()
    
    Select Case B
    Case 0 : goto Dekoder
    Case 1 : goto Dekoder
    Case 2 : goto Dekoder
    Case 3 : goto Dekoder
    ...
       


    Chyba takie coś musi być
  • Poziom 32  
    A nie prosciej
    Code:

    case 0:

    instrukcja z twojego dekoder

    case 1:
    ...

    etc

  • Poziom 20  
    Przecież wtedy objętościowo kod programu będzie większy bo 16 razy użyje komend z pod programu.
  • Poziom 32  
    O matko... zobacz:
    Code:
    if B=16 then call Odczyt_kawiatury
    
    else
    call dekoder
    end if

  • Poziom 20  
    Czyli pętla do loop ma wyglądać tak, że jeśli cyfra 16 (klawiatura podaje 16 jeśli nie wcisnę klawisza), do wraca i odczytuje od nowa, a jeśli cokolwiek innego to idzie do dekodera?
    Code:
    Do
    

    Odczyt_kawiatury:
       Locate 1 , 1
       Lcd "Brak klawisza"
       Locate 2 , 13
       B = Getkbd()

       If B = 16 Then Call Odczyt_kawiatury
        Else
        Call Dekoder
         End If
       Loop
       End

    Mam teraz błąd:
    SUB or FUNCTION not DECLARED [odczyt_klawiatury]
    SUB or FUNCTION not DECLARED [dekode]

    przecież mam podaną etykietę odczyt_klawiatury i dekoder ...

    Już gra...
    Brakowało
    Code:
    Declare Sub Odczyt_kawiatury
    
    Declare Sub Dekoder



    Nadal nie działa przypisanie zmiennej B do c,d,e,f
    Już nawet dodałem żeby wyświetlał zmienne.
    Po odczycie idzie do dekoder podmienia b na c (w 1 wciśnięciu),, ale nadal c=0
    Code:
    Dekoder:
    
          Incr X
          Cls
          Locate 2 , 7
          Lcd "proba" ; X
          Locate 1 , 1
          Lcd "cyfra" ; B
          Waitms 200

       Select Case X

          Case 1 : B = C
            Cls
            Lcd C
            Waitms 500

         Case 2 : B = D
            Cls
            Lcd D
            Waitms 500

          Case 3 : B = E
            Cls
            Lcd E
            Waitms 500

          Case 4 : B = F
            Cls
            Lcd F
            Waitms 500

          Case 5 : Goto Sprawdzam_kod


    Jak już pisze to dokończę, znalazłem błąd...

    taka mała pomyłka, nie przypisuje bo:
    Code:
    B = E

    a ma być
    Code:
    E=B



    Czy jest możliwość zapisu kodu (4 cyfr) do eepromu w procesorze? czy muszę mieszę zewnętrzny np. 24c02B
  • Poziom 32  
    Tak jest poczytaj w helpie o writeeeprom.
  • Poziom 17  
    jest troche inna metoda sprawdzania wielu zmiennych,
    zamiast budować długi łańcuch if xx AND xx AND xx itd
    można to zrobić "odwrotnie"
    if wzór1 <> wciśniety_pierwszy then goto zły_pin
    if wzór2 <> wciśniety_drugi then goto zły_pin
    .
    .
    .
    else
    pin_ok=1
    endif

    przy takich krótkich (4 cyfry) to jest może mało przydatne
    lecz gdy sprawdzasz dziesiątki warunków to jest chyba bardziej przejrzyste i łatwiej modyfikować

    ps. sorki za brak znaczników "code" nie pamiętam jak ich użyć
  • Poziom 36  
    elektrofil napisał:
    jest troche inna metoda sprawdzania wielu zmiennych,
    zamiast budować długi łańcuch if xx AND xx AND xx itd
    można to zrobić "odwrotnie"
    if wzór1 <> wciśniety_pierwszy then goto zły_pin
    if wzór2 <> wciśniety_drugi then goto zły_pin
    .
    .
    .
    else
    pin_ok=1
    endif

    przy takich krótkich (4 cyfry) to jest może mało przydatne
    lecz gdy sprawdzasz dziesiątki warunków to jest chyba bardziej przejrzyste i łatwiej modyfikować

    ps. sorki za brak znaczników "code" nie pamiętam jak ich użyć


    Moze ten przyklad bezposrednio od MCS Elec. pomoze w zrozumieniu konceptu "keypad".

    http://www.mcselec.com/index.php?option=com_content&task=view&id=160&Itemid=57

    Nadmierna rozbudowa warunku :
    If... Then
    ...
    elseif.... then
    .....
    elseif.... then
    .....
    else
    End if
    nadmiernie wydluzy program i mozesz sie pogubic w warunkach.
    Podobnie ma sie tez z operatorami logicznymi, przy dwoch lub trzech OK.
    Gniazdowanie warunku - zwieksza PS
    Powyzszy przyklad stosuje "case".

    Odnosnie pytania dot. zapisu (wpisu) czterocyfrowej lub wiekszej liczby do EPROM....
    Bascom pozwala wpisac kazda liczbe do EPROM pod warunkiem ze jest tam dostateczna ilosc miejsca (- w twoim wypadku to jest oczywiste) oraz zmienna ta lub stala musi byc odpowiednio zwymiarowana i zadeklarowana zwykle na poczatku programu.

    np:
    ..............
    Dim Moja_zmienna As Word ' moze tu byc zarowno: Byte,Word, Integer, Long, itd, zaleznie od wielkosci zmienmnej.
    ..............
    Aby uniknac czestych bledow radzilbym unikac wpisu do pierwszej pozycji pamieci Eprom, wygodne jest z gory przydzielenie miejsca w Eprom dla twojej zmiennej.
    np:
    Dim A As Eram Word At 2 ' moze tu byc zarowno: Byte,Word, Integer, Long, itd, zaleznie od wielkosci zmienmnej.
    Ta 2-jka jest poczatek miejsca w pamieci, - moze to byc inne miejsce. W przypadku wiecej zmiennych do wpisania posluzysz sie kolejnymi wolnymi "nierezerwowanymi" miejscami.
    Jezeli wczesniej deklarujesz 'String * n' pamietal zostawic jedno dodatkowe miejsce.

    Wpisu do Eprom dokonujesz, - gdzies w programie gdy zachodzi potrzeba.
    np:
    Writeeeprom Moja_zmienna , A
    --------------------
    Normalnie mozesz uzyc prostszego polecenia:
    A = Moja_zmiena ' dla wpisu do Eprom
    i odpowiednio:
    Moja_zmienma = A ' dla odczytu z Eprom

    emarcus