Zamek szyfrowy na Attiny2313

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
CR7777
-
Posty: 20
Rejestracja: 15 lis 2009, 22:18
Lokalizacja: Mysłowice

Zamek szyfrowy na Attiny2313

Post autor: CR7777 » 27 gru 2009, 21:09

Witam Na początku pragnę nadmienić iż dopiero dzisiaj poznałem język BASCOM więc mam w nim duże a nawet bardzo duże braki tak więc gdybym napisał coś żle to nie miejcie mi tego za złe :wink:

Napisałem prościutki programik na procka który po wciśnięciu odpowiednich przycisków (wpisaniu kodu) np. zapali diodę na 2 sekundy po czym ją zgasi.

Załóżmy że przycisków jest 6 (pind.0 - pind.5, pind.6 to wyjście) a kod to 245 (pind.1, pind.3, pind.4).
Po wpisaniu kodu przez dwie sekundy na pind.6 jest stan "1" po czym powraca do pierwotnego stanu, przyciski także wracają do stanu "0".

Kod: Zaznacz cały

$regfile = "attiny2313.dat"                 
$crystal = 1000000            

config pind.0=input    
config pind.1=input    
config pind.2=input    
config pind.3=input    
config pind.4=input    
config pind.5=input    
config pind.6=output 

portd.0=0 
portd.1=0 
portd.2=0 
portd.3=0 
portd.4=0
portd.5=0 
portd.6=0               

  do

      if pinb.0=0 and pind.1=1 and pind.2=0 and pind.3=1 and pind.4=1          and pind.5=0 then
      pind.6=1
      wait 2
      pind.1=0
      pind.3=0
      pind.4=0
      pind.6=0
      endif

  loop

end
Wszystko ładnie (przynajmniej mam taką nadzieje) ale na przykład przychodzi ktoś kto nie zna kodu i naciska wszystkie przyciski byle jak, następnie przychodzę ja i nie wiem na których przyciskach jest jaki stan :roll:
Więc może macie na to jakiś pomysł :wink:

I tak w ogóle to SZCZĘŚLIWEGO NOWEGO ROKU!!!
Ostatnio zmieniony 28 gru 2009, 14:00 przez CR7777, łącznie zmieniany 4 razy.

snow
Użytkownik
Posty: 794
Rejestracja: 16 sty 2007, 3:44
Lokalizacja: lubelskie
Kontakt:

Post autor: snow » 27 gru 2009, 21:13

Zrób że jeśli od naciśnięcia pierwszego przycisku w ciągu np. 5s nie zostanie wpisany poprawny kod to wszystko wraca do stanu sprzed naciśnięcia tego przycisku

CR7777
-
Posty: 20
Rejestracja: 15 lis 2009, 22:18
Lokalizacja: Mysłowice

Post autor: CR7777 » 27 gru 2009, 21:16

Świetny pomysł ale mógłbyś mi pomóc to napisać bo jak już napisałem znam tylko podstawy :wink:

[ Dodano: 2009-12-27, 22:16 ]
I mam jeszcze jedno pytanie: Czy tam gdzie podaje warunek powinienem też podać że na pozostałych pinach musi być stan "0" ??

Awatar użytkownika
matrix
Użytkownik
Posty: 1805
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 27 gru 2009, 23:11

Kod: Zaznacz cały

do 
      if pinb.1=1 and pind.3=1 and pind.4=1 then 
       pind.6=1 
      endif 

loop
po pierwsze to nie pisz tego tak. nie sprawdzaj stanów wysokich. przestaw się z układów cyfrowych seri 40XX i 74XX na uP. tu zwykle sprawdza się wszystko od strony masy. poza tym jak sobie wyobrażasz nacisnąć wszystkie kolejne przyciski w ciągu mikrosekund? przecież procek sprawdzi Ci stan tych przycisków setki razy na sekundę. a co jak ktoś naciśnie wszystkie przyciski na raz? zabezpieczyłeś się przed tym? bo nie widzę tego. jak naciśnie wszystkie na raz to otworzy Ci zamek na bank bo spełni wszystkie warunki. trzeba to napisać inaczej. coś pi razy oko tak:

Kod: Zaznacz cały

if pind.0=0 then
   wait 2
   if pind.1=0 then
      wait 2
      if pind.3=0 then
         if pind.0=0 and pind.1=0 and pind.2=0 then
            exit if
            else
            reset zamek    'czyli otwórz zamek          
         end if
      end if
   end if
end if
trochę to nieeleganckie, ale to tak na szybko. poza tym też nie za bardzo będzie działać, ale próbuje naprowadzić na właściwą drogę.
Ostatnio zmieniony 30 gru 2009, 10:31 przez matrix, łącznie zmieniany 1 raz.

Awatar użytkownika
grysek67
Użytkownik
Posty: 315
Rejestracja: 27 cze 2007, 6:34
Lokalizacja: Limanowa
Kontakt:

Post autor: grysek67 » 29 gru 2009, 23:28

Pozatym nie piszemy

Kod: Zaznacz cały

pind.1=0 
tylko

Kod: Zaznacz cały

portd.1 = 0 
Jeśli chcemu coś podać na wyjście to wpisujemy do rejestru PORTx a jeśli sprawdzić stan wejść to sprawdzamy rejestr PINx.

I kolejna sprawa, jeśli pin ustawimy jako wejście to wpisując do dane do rejestru port tego pinu, to tylko ustawiamy albo kasujemy wewnętrzny pull-up a nie zmieniamy wartość na wyjściu :smile: To nie '51 tutaj wejście to wejście, a wyjście to wyjście

Awatar użytkownika
Pikczu
Użytkownik
Posty: 755
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

Post autor: Pikczu » 30 gru 2009, 2:59

Zobacz na szybkie wieczorno-nocne wypociny

Kod: Zaznacz cały

$regfile = "ATtiny2313.DAT"
$crystal = 10000000
$baud = 9600

$hwstack = 32
$swstack = 16
$framesize = 32


Config Portd = Output                                       'portd jako wyjście
Portd = 0                                                   'stan początkowy 0

Config portb = INPUT                                        'port b jako wejście
portb = 255                                                 'rezystory podciągające
enable interrupts                                           'globalne włączenie przerwań
Config Timer1 = Timer , Prescale = 256                      'configuracja timera `1
Enable Timer1                                               'włącz przerwanie od timera 1
On Timer1 P1                                                ' w momencie wystąpienia przerwania skocz do pod programu P1




Dim A As Byte                                               'zmienna A do niej na początku s aprzypisane stany z portu B
Dim kod(4) As Byte                                          'zmienna kod jako tablica o rozmiarze 4 byteów
Dim licz As Byte                                            'zmienna do liczenia
Dim flag1 as bit                                            'flaga
Dim czas as byte                                            'zmienna czas
Dim haslo(4)as byte                                         'zmienna hasło jako tablica o rozmiarze 4 byteów
Dim ok as byte                                              'zmienna ok bo nie miałem innego pomysłu jak porównac w szybki sposób dwie tablice
stop timer1                                                 'zatrzymanie timera1

print "test połaczenia"                                     ' to dla testu czy mój port szeregowy jest dobrze usatwiony i podpięty

Haslo(1) = 2                                                'właściwy kod
haslo(2) = 1                                                'właściwy kod
haslo(3) = 2                                                'właściwy kod
haslo(4) = 1                                                'właściwy kod

'===============================================================================

Do                                                          'początek pętli do loop


Debounce pinb.0 , 0 , pr , Sub                              'to jest to sprawdznaia stanu poszczególnych przycisków
Debounce Pinb.1 , 0 , Pr , Sub
Debounce Pinb.2 , 0 , Pr , Sub
Debounce Pinb.3 , 0 , Pr , Sub
Debounce Pinb.4 , 0 , Pr , Sub
Debounce Pinb.5 , 0 , Pr , Sub
Debounce Pinb.6 , 0 , Pr , Sub
Debounce Pinb.7 , 0 , Pr , Sub



if licz > 4 then                                            ' liczy ile razy przycisk(i) był(y) naciśnięt(e)
licz = 1                                                    'jeśli więcej niz 4 to ustaw na 1
end if                                                      'koniec warunku


if czas = 10 then                                           ' jesli przerwanie od timera 1 zostanie wykonane (to na samym dole P1) to ta zmienna czas zostaje zwiększona o 1
                     ' po 10 takich przerwaniach zostanie wyłączony led który był podpięty do portd.3
reset portd.3

stop TIMER1                                                 'zatrzymany timer 1

czas = 0                                                    ' wyzerowana zmienna czas
licz = 0                                                    ' wyzerowana zmienna licz
Kod(1) = 0                                                  ' cokolwiek zostało wprowadzone to po upływie czasu zostanie wykasowane
kod(2) = 0
kod(3) = 0
kod(4) = 0
print Kod(1) ; Kod(2) ; kod(3) ; kod(4)                     ' to było do testów nie potrzebne można wywalić
print haslo(1) ; haslo(2) ; haslo(3) ; haslo(4)             ' to było do testów nie potrzebne można wywalić
end if                                                      'koniec warunku




while flag1 = 1                                             ' jak długo flaga1 jest ustawiona na 1 czyli jakiś przycisk wciśnięty to:
print "licz::" ; licz                                       'to do testów można wywalić
 Kod(licz) = 255 - A                                        'przypisz wartość zmiennej A (stan pinów na porcie B) do tablicy kod

 If Kod(licz) = 1 Then
 print "kod:" ; kod(licz)   'print można wywalić było tylko do testów
 End If
 If Kod(licz) = 2 Then
print "kod:" ; kod(licz)                                    'print można wywalić było tylko do testów
  End If

If Kod(licz) = 4 Then

Kod(licz) = 3
print "kod:" ; kod(licz)                                    'print można wywalić było tylko do testów
End If

If Kod(licz) = 8 Then

Kod(licz) = 4
print "kod:" ; kod(licz)                                    'print można wywalić było tylko do testów
End If

If Kod(licz) = 16 Then
Kod(licz) = 5
print "kod:" ; kod(licz)                                    'print można wywalić było tylko do testów
End If

If Kod(licz) = 32 Then
Kod(licz) = 6
print "kod:" ; kod(licz)                                    'print można wywalić było tylko do testów
End If

If Kod(licz) = 128 Then
Kod(licz) = 8
print "kod:" ; kod(licz)                                    'print można wywalić było tylko do testów
End If
reset flag1                                                 'kasuje flagę
wend




''Tu nie małem pomysłu jak porównać dwie tablice więc zrobiłem naj prościej jak tylko się dało

if kod(1) = haslo(1) then                                   ' jeśli cyfra w tablicy kod pod indexem 1 jets taka sama jak hasło pod indexem 1 w tedy
ok.0 = 1                                                    'ustaw bit w zmiennej Ok
else                                                        'jeśli nie jest taki sam to nie ustawiaj
ok.0 = 0                                                    '
end if
if kod(2) = haslo(2) then
ok.1 = 1
else
 ok.1=0
end if
if kod(3) = haslo(3) then
ok.2 = 1
else
ok.2 = 0
end if
if kod(4) = haslo(4) then
ok.3 = 1
else
ok.3 = 0

end if

if ok = 15 then                                             ' jesli wszystkie cyfry w tablicy były takie same to:
set PORTD.4                                                 ' włącz leda podpiętego do portd.4
licz = 0                                                    ' zeruje zmienną licz
else
reset portd.4
end if


Loop
End

' w momęcie naciśnięcia przycisku zostanie odliczony czas okoló 25 ms i program przejdzie do PR:
pr:
incr LICZ                                                   'zwiększ zmienna licz o 1
A = Pinb                                                    'przypisz stan z pinów do zmiennej A
set portd.3                                                 'włącz diodę podpiętą akurat do tego portu
start TIMER1                                                ' włącz timer1 żeby mógł liczyć czas
timer1 = 1                                                  'wpisz wartość początkową do timera
set flag1                                                   'ustaw flagę pomocniczą flag1
Return                                                      'powrót do góry





P1:                                                         'pod program odliczania czasu ja go nazwałem P1
incr czas                                                   ' w momencie wystąpienia przerwania zwiększ zmienną czas
Return                                                      'powrót

Pomysł został skradziony z MCS forum
http://www.mcselec.com/index.php?option ... &Itemid=57

A dokładnie to te warunki

Kod: Zaznacz cały

While Key = P3
 Wend
 K(i) = 255 - Key
 If K(i) = 1 Then
 Goto Lcd_out
 End If
 If K(i) = 2 Then
 Goto Lcd_out
  End If
 If K(i) = 4 Then
 K(i) = 3
 Goto Lcd_out
 End If
 If K(i) = 8 Then
 K(i) = 4
 Goto Lcd_out
 End If
 If K(i) = 16 Then
 K(i) = 5
 Goto Lcd_out
 End If
 If K(i) = 32 Then
 K(i) = 6
 Goto Lcd_out
 End If
 If K(i) = 128 Then
 K(i) = 8
 Goto Lcd_out
 End If
Idę spać.

CR7777
-
Posty: 20
Rejestracja: 15 lis 2009, 22:18
Lokalizacja: Mysłowice

Post autor: CR7777 » 30 gru 2009, 13:13

Pikczu jesteś po prostu zaj3bisty :mrgreen:

Awatar użytkownika
Pikczu
Użytkownik
Posty: 755
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

Post autor: Pikczu » 30 gru 2009, 13:50

Eeee tam to jest mocno nie dopracowane ale działa.
każde naciśnięcie przycisku zeruje licznik czasu jeśli naciśniesz przycisk tylko raz
czas upłynie i zawartość zmiennych zostanie wykasowana.
jeśli wprowadzisz 4 odpowiednie cyfry w odpowiedniej kolejności to portd.4 zostanie ustawiony na 1.

Jeśli będziesz wciskał przyciski w kółko to będziesz nadpisywał wcześniej wpisane liczby.

Awatar użytkownika
kayron
Użytkownik
Posty: 2079
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 01 sty 2010, 11:13

No to spróbuj teraz napisać w ramach nauki prawdziwy zamek szyfrowy. Powiedzmy wyposażony w LCD alfanumeryczny, który spełnia następujące kryteria:
- Obsługuje 12 przyciskową klawiaturę (cyfry 0 -9, gwiazdka i krzyżyk)
- kod min 6 cyfrowy
- obsługa MIN 2 użytkowników, z własnym niepowtarzalnym kodem dostępu. Dla uproszczenia może być przechowywany w dowolnej pamięci procesora FLASH lub EEPROM. Oba rozwiązania mają plusy i minusy.
- podczas wbijania kodu na wyświetlaczu po naciśnięciu liczby wyświetla sie ona na wyświetlaczu po czym po 1 sekundzie znika i zamienia się w symbol gwiazdki (tak jak w czytnikach kart płatniczych).
- trzy krotne złe wprowadzenie kodu powoduje zablokowanie i alarm, a urządzenie da się tylko odblokować za pomocą klucza sprzętowego np. zwierając ukrytą zworką na czas 0,5 sek.
- po podaniu właściwego kodu otwiera sie zamek (np. przekaźnik, tak na 3 do 5 sek), a na wyświetlaczu pojawia się tekst powitalny np. Witaj ROMEK. Tekst powinien być przechowywany w pamięci EEPROM procesora, aby można łatwo go modyfikować, jego max długość to 16 znaków.
Spróbuj, naprawdę dużo sie przy temu nauczysz, a przy okazji zbudujesz sobie przydatny bajer. 2313 spokojnie to powinien uciągnąć.

ODPOWIEDZ