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

Atmega8: Budowa konwertera PS/2 na RS-232 z użyciem Bascom, problem z kodem

pnetp 11 Paź 2006 19:49 2906 11
REKLAMA
  • #1 3107674
    pnetp
    Poziom 11  
    Posty: 12
    Mam pewien problem , buduje konwertor PS/2 <-> RS-232 na mega8 (program w bascomie)
    $regfile = "m8def.dat"
    $crystal = 8000000
    $baud = 4800
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    Config Keyboard = Pinb.2 , Data = Pinb.3 , Keydata = Keydata
    
    Dim Kod As Byte
    
    Cls
    Do
      Kod = Getatkbdraw()
    If Kod > 0 Then
      Lcd Chr(kod)
      Print Kod
    End If
    
    
    Loop
    End
    
    Keydata:
    
    Data 0 , 0 , 0 , 0 , 0 , 200 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , &H5E , 0
    
    Data 0 , 0 , 0 , 0 , 0 , 113 , 49 , 0 , 0 , 0 , 122 , 115 , 97 , 119 , 50 , 0
    
    Data 0 , 99 , 120 , 100 , 101 , 52 , 51 , 0 , 0 , 32 , 118 , 102 , 116 , 114 , 53 , 0
    
    Data 0 , 110 , 98 , 104 , 103 , 121 , 54 , 7 , 8 , 44 , 109 , 106 , 117 , 55 , 56 , 0
    
    Data 0 , 44 , 107 , 105 , 111 , 48 , 57 , 0 , 0 , 46 , 45 , 108 , 48 , 112 , 43 , 0
    
    Data 0 , 0 , 0 , 0 , 0 , 92 , 0 , 0 , 0 , 0 , 13 , 0 , 0 , 92 , 0 , 0
    
    Data 0 , 60 , 0 , 0 , 0 , 0 , 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0
    
    Data 48 , 44 , 50 , 53 , 54 , 56 , 0 , 0 , 0 , 43 , 51 , 45 , 42 , 57 , 0 , 0
    
    
    
    Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
    
    Data 0 , 0 , 0 , 0 , 0 , 81 , 33 , 0 , 0 , 0 , 90 , 83 , 65 , 87 , 34 , 0
    
    Data 0 , 67 , 88 , 68 , 69 , 0 , 35 , 0 , 0 , 32 , 86 , 70 , 84 , 82 , 37 , 0
    
    Data 0 , 78 , 66 , 72 , 71 , 89 , 38 , 0 , 0 , 76 , 77 , 74 , 85 , 47 , 40 , 0
    
    Data 0 , 59 , 75 , 73 , 79 , 61 , 41 , 0 , 0 , 58 , 95 , 76 , 48 , 80 , 63 , 0
    
    Data 0 , 0 , 0 , 0 , 0 , 96 , 0 , 0 , 0 , 0 , 13 , 94 , 0 , 42 , 0 , 0
    
    Data 0 , 62 , 0 , 0 , 0 , 8 , 0 , 0 , 49 , 0 , 52 , 55 , 0 , 0 , 0 , 0
    
    Data 48 , 44 , 50 , 53 , 54 , 56 , 0 , 0 , 0 , 43 , 51 , 45 , 42 , 57 , 0 , 0

    Urzywam funkcji getatkeyboardraw odbierającą wszystko to co wysyła
    klawiatura ,a na terminalu na Pc odbieram tylko kod klawisza + bajt 240 zwolnienie klawisza. Nawet po kodzie zwolnionego klawisza nie wysyła sie
    kod puszczonego klawisza .? Sprzętowo jes wszysko dobrze.
    Prosze o pomoc.

    ps.:A jak by ktoś mógł to niech wrzuci coś takiego w C (najlepiej kod + skompilowany program).
  • REKLAMA
  • #2 3107979
    greatlukas
    Poziom 14  
    Posty: 122
    Pomógł: 3
    Ocena: 7
    Mówisz masz :]
    
    #include <avr/io.h>
    #include <avr/delay.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include "scancodes.h"
    
    
    volatile uint8_t   flag,flag2;
    
    #define S_CLK    PORTD|=(1<<2)
    #define C_CLK    PORTD&=~(1<<2)
    #define CLK      bit_is_set(PIND,2)
    #define S_DATA   PORTD|=(1<<3)
    #define C_DATA   PORTD&=~(1<<3)
    #define DATA     bit_is_set(PIND,3)
    
    #define DATA_WY  DDRD|=(1<<3)
    #define DATA_WE  DDRD&=~(1<<3)
    #define CLK_WY   DDRD|=(1<<2)
    #define CLK_WE   DDRD&=~(1<<2)
    
    // key released
    #define S_KR     flag|=(1<<0)
    #define C_KR     flag&=~(1<<0)
    #define KR       bit_is_set(flag,0)
    // left shift
    #define S_LSH    flag|=(1<<1)
    #define C_LSH    flag&=~(1<<1)
    #define LSH      bit_is_set(flag,1)
    // right shift
    #define S_RSH    flag|=(1<<2)
    #define C_RSH    flag&=~(1<<2)
    #define RSH      bit_is_set(flag,2)
    // Caps Lock
    #define S_CL     flag|=(1<<3)
    #define C_CL     flag&=~(1<<3)
    #define CL       bit_is_set(flag,3)
    // Num Lock
    #define S_NL     flag|=(1<<4)
    #define C_NL     flag&=~(1<<4)
    #define NL       bit_is_set(flag,4)
    // Scroll Lock
    #define S_SL     flag|=(1<<5)
    #define C_SL     flag&=~(1<<5)
    #define SL       bit_is_set(flag,5)
    // Extended key
    #define S_EXT    flag|=(1<<6)
    #define C_EXT    flag&=~(1<<6)
    #define EXT      bit_is_set(flag,6)
    // Left Ctrl
    #define S_LCTRL  flag|=(1<<7)
    #define C_LCTRL  flag&=~(1<<7)
    #define LCTRL    bit_is_set(flag,7)
    // Right Ctrl
    #define S_RCTRL  flag2|=(1<<0)
    #define C_RCTRL  flag2&=~(1<<0)
    #define RCTRL    bit_is_set(flag2,0)
    // Left Alt
    #define S_LALT   flag2|=(1<<1)
    #define C_LALT   flag2&=~(1<<1)
    #define LALT     bit_is_set(flag2,1)
    // Right Alt
    #define S_RALT   flag2|=(1<<2)
    #define C_RALT   flag2&=~(1<<2)
    #define RALT     bit_is_set(flag2,2)
    // Left WIN
    #define S_LWIN   flag2|=(1<<3)
    #define C_LWIN   flag2&=~(1<<3)
    #define LWIN     bit_is_set(flag2,3)
    // Right WIN
    #define S_RWIN   flag2|=(1<<4)
    #define C_RWIN   flag2&=~(1<<4)
    #define RWIN     bit_is_set(flag2,4)
    // APPS
    #define S_APPS   flag2|=(1<<5)
    #define C_APPS   flag2&=~(1<<5)
    #define APPS     bit_is_set(flag2,5)
    // Code Ready
    #define S_KBDR   flag2|=(1<<6)
    #define C_KBDR   flag2&=~(1<<6)
    #define KBDR     bit_is_set(flag2,6)
    // Special Key
    #define S_SPC    flag2|=(1<<7)
    #define C_SPC    flag2&=~(1<<7)
    #define SPC      bit_is_set(flag2,7)
    
    
    
    
    
    
    //volatile unsigned char  bytes[3];
    //volatile uint8_t  bytes_to_send;
    unsigned char bitcount;
    unsigned char KBD_Code;
    
    
    void USART_Transmit( unsigned char Znak ) 
    { 
        while ( !( UCSRA & (1<<UDRE)) );// Wait for empty transmit buffer 
        UDR = Znak;// Put data into buffer, sends the data 
    }
    
    
    void KBD_Init(void)
    {
        // External interrupt
        //CLK
        CLK_WE;  // wejście
        C_CLK;
        //DATA
        DATA_WE;  // wejście
        S_DATA;
    
        KBD_Code=0;
        MCUCR = 2;                                // INT0 interrupt on falling edge
        bitcount = 11;
        GICR|=(1<<INT0);
    }
    
    
    int main()
    {
        // ==== single usart configuration ====
        // 19200 baud with 16000 kHz osc./error=0,2%
        // data 8/stop 1/parity NONE
        // receiver ON/transmitter ON/recv interrupt enabled
        UBRRH = 0x00;
        UBRRL = 0x33;
        UCSRA = 0x0;
        UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE);
        UCSRC = _BV(URSEL) | _BV(UCSZ0) | _BV(UCSZ1);
        // ==== end usart ====
        
    
        flag=flag2=0;
        C_KBDR;
        KBD_Init();    
    
    
    
        sei();    
        while (1)
        {
           if (KBDR)
           {
              if (KBD_Code==0xF0) S_KR; // Set Key Released
              else if (!KR) // if not key released
              {
                 if (KBD_Code==0xE0) S_SPC; // Set Special Key
                 else if (!SPC)
                 {
    //                USART_Transmit(KBD_Code);
                    switch (KBD_Code)
                    {
                       case 0x12: S_LSH; break; // Set Left Shift
                       case 0x59: S_RSH; break; // Set Right Shift
                       default:
                          for(int i=0;i<sizeof(scancodes);i+=3)
                          {
                             if (KBD_Code==scancodes[i])
                             {
                                if (!LSH && !RSH) USART_Transmit(scancodes[i+1]);
                                else USART_Transmit(scancodes[i+2]);
                             }
                          }break;
                    }
                 }
                 else
                 {
                    C_SPC; // Clear Special Key
                    switch(KBD_Code)
                    {
                       case 0x5A:  USART_Transmit(13);break;
                       default: break;
                    }
                 }
               }
              else
              {
                 C_KR; // Clear Key Released
                 switch (KBD_Code)
                 {
                    case 0x12: C_LSH; break; // Clear Left Shift
                    case 0x59: C_RSH; break; // Clear Right Shift
                 }
              }
              
              KBD_Code=0;
              C_KBDR;
              CLK_WE;
           }
        
        }
        return 0;
    }
    
    
    SIGNAL(SIG_INTERRUPT0)
    {
    //   if (DATA && bitcount==11) bitcount=12; // jak bit startu bedzie jedynką to zaczekaj na bit startu
       if(bitcount < 11 && bitcount > 2)      // Bit 3 to 10 is data. Parity bit,
       {                                      // start and stop bits are ignored.
          KBD_Code = (KBD_Code >> 1);
          if(DATA) KBD_Code = KBD_Code | 0x80;            // Store a '1'
       }
       if(--bitcount == 0)                    // All bits received
       {
    //       _delay_us(10);
          CLK_WY;          // blokuje klawiature przed wysylaniem dalszych kodów
          S_KBDR;          // Set KBD Ready
          bitcount = 11;
       }
    }
    

    i jeszcze scancode
    
    // [][1] - Unshifted characters; [][2] - Shifted characters
    const unsigned char scancodes[] = {
    0x0d,9,9,	// Tab
    0x0e,'`','~',
    0x15,'q','Q',
    0x16,'1','!',
    0x1a,'z','Z',
    0x1b,'s','S',
    0x1c,'a','A',
    0x1d,'w','W',
    0x1e,'2','@',
    0x21,'c','C',
    0x22,'x','X',
    0x23,'d','D',
    0x24,'e','E',
    0x25,'4','$',
    0x26,'3','#',
    0x29,' ',' ',
    0x2a,'v','V',
    0x2b,'f','F',
    0x2c,'t','T',
    0x2d,'r','R',
    0x2e,'5','%',
    0x31,'n','N',
    0x32,'b','B',
    0x33,'h','H',
    0x34,'g','G',
    0x35,'y','Y',
    0x36,'6','^',
    //0x39,',','<',
    0x3a,'m','M',
    0x3b,'j','J',
    0x3c,'u','U',
    0x3d,'7','&',
    0x3e,'8','*',
    0x41,',','<',
    0x42,'k','K',
    0x43,'i','I',
    0x44,'o','O',
    0x45,'0',')',
    0x46,'9','(',
    0x49,'.','>',
    0x4a,'/','?',
    0x4b,'l','L',
    0x4c,';',':',
    0x4d,'p','P',
    0x4e,'-','_',
    0x52,'\'','"',
    0x54,'[','{',
    0x55,'=','+',
    0x5a,13,13,	// enter
    0x5b,']','}',
    0x5d,'\\','|',
    //0x61,'<',
    0x66,8,8,	// backspace
    0x69,'1','1',	// KP 1
    0x6b,'4','4',	// KP 4
    0x6c,'7','7',	// KP 7
    0x70,'0','0',	// KP 0
    0x71,',',',',
    0x72,'2','2',
    0x73,'5','5',
    0x74,'6','6',
    0x75,'8','8',
    0x79,'+','+',
    0x7a,'3','3',
    0x7b,'-','-',
    0x7c,'*','*',
    0x7d,'9','9'//,
    //0,0
    };
    
    Załączniki:
    • KBD2RS.rar (14.74 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #3 3108058
    pnetp
    Poziom 11  
    Posty: 12
    Program jest skompilowany pod mega8? Sory za takie pytanie ale nie urzywam C do avr'ów . Uart jest sprzętowy?

    A ak w ogóle to dzięki[/url]
  • REKLAMA
  • #4 3108067
    greatlukas
    Poziom 14  
    Posty: 122
    Pomógł: 3
    Ocena: 7
    Faktycznie mój błąd mogłem napisać
    W załączniku program (*.hex) skompilowany na mege8535 z zewnętrznym kwarce 16MHz

    UART jest sprzętowy

    A jaki masz kwarc podpięty do Atmegi8 to zaraz przekompiluje i załącze
  • REKLAMA
  • #5 3109583
    pnetp
    Poziom 11  
    Posty: 12
    Wewnętrzny RC 8mhz . Program wysyła to co odbiera z klawiatury , bez dekodowania ?
    (Bo właśnie mi na takim zalerzy).
  • REKLAMA
  • #6 3110453
    greatlukas
    Poziom 14  
    Posty: 122
    Pomógł: 3
    Ocena: 7
    W załączniku kod do ATmega8 kwarc 8MHz
    Wysyła po RS wszystkie kody, bez translacji, łącznie z kodem puszczenia klawisza 0xF0 i klawisza "specjalnego" 0xE0
  • #7 3113122
    pnetp
    Poziom 11  
    Posty: 12
    Jaki jest ustawiony baud?

    Edit:
    Patrzyłem oczywiście w kod ale gdy na kompie ustawiam 19200 to wysyła mi:
    226 224 213 224 226 224 226 214 214 214
    przy załorzeniu że wciskam po kolei : A C I (strzałka w dół)
    Morze to problem transmisji? Na pc jest 8bitów danych brak bitu parzystości i 1 bit stopu i to samo wynika z
    
    // data 8/stop 1/parity NONE
    

    W czym jest problem?
  • #8 3113259
    greatlukas
    Poziom 14  
    Posty: 122
    Pomógł: 3
    Ocena: 7
    Troszke nie poważne pytanie z twojej strony, jeżeli zajżysz do kodu źródłowego, tam jest wyraźnie zaznaczone
    
    // ==== single usart configuration ====
    // 19200 baud with 8000 kHz osc./error=0,2%
    // data 8/stop 1/parity NONE
    // receiver ON/transmitter ON/recv interrupt enabled
    
  • #9 3113292
    pnetp
    Poziom 11  
    Posty: 12
    pnetp napisał:
    Jaki jest ustawiony baud?

    Edit:
    Patrzyłem oczywiście w kod ale gdy na kompie ustawiam 19200 to wysyła mi:
    226 224 213 224 226 224 226 214 214 214
    przy załorzeniu że wciskam po kolei : A C I (strzałka w dół)
    Morze to problem transmisji? Na pc jest 8bitów danych brak bitu parzystości i 1 bit stopu i to samo wynika z
    
    // data 8/stop 1/parity NONE
    

    W czym jest problem?
  • #10 3113352
    greatlukas
    Poziom 14  
    Posty: 122
    Pomógł: 3
    Ocena: 7
    Prawdę mówiąc to nie wiem co jest grane, wgraj plik z załącznika, dodałem, że jak wyślesz jakis znak z terminala to ATmegi, to ona powinna odesłać to samo, w ten sposób sprawdzisz czy masz prawidłowe połączenie pomiędzy PC a AVR.

    O kodach klawiszy poczytaj Tutaj
    ja dodam tyle, że:
    po wciśnięciu klawisza np 'a' klawiatura wysyłą kod 0x1C, jeżeli go przytrzymasz to klawiatura będzie cały czas wysyłać 0x1C, w momencie puszczenia klawisza klawiatura wysyła 0xF0, po czym kod klawisza, który został upuszczony, czyli w tym przypadku 0x1C

    Jeżeli wciśniesz strzałkę w dół, otrzymasz: 0xE0, 0x72
    Jak puścisz strzałkę to dostaniesz: 0xE0,0xF0,0x72
    Załączniki:
    • KBD2RS.rar (13.28 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #11 3113374
    pnetp
    Poziom 11  
    Posty: 12
    greatlukas napisał:

    Jak puścisz strzałkę to dostaniesz: 0xE0,0xF0,0x72


    Chyba 0xE0,0x72,0xF0,0xE0,0x72 ???

    A poza tym zauwarzyłem że jeżeli przytrzymam A to na samym początku wysyłają się jakieś błędne dane (np. 2248) a dopiero 28 a gdy puszcze to 240 i tu nie zawsze wysyła się ponownie znak kodu.

    Może o wina atmegi ???
  • #12 3113537
    greatlukas
    Poziom 14  
    Posty: 122
    Pomógł: 3
    Ocena: 7
    najpierw idzie 0xE0 (bo to znak specjalny) potem 0xF0 (bo puszczasz klawisz i potem kod klawisza jaki puszczasz.

    Chyba wiem w czym leży problem :] swego czasu miałem to samo i też zachodziłem w głowe od czego to może być. Podejżewam że AVR się resetuje (zawiesza) i dlatego dostajesz dziwne rzeczy, ja to rozwiązałem przez dodanie do zasilania przy samej atmedze kilku kondensatorów elektrolitycznych.

    W załączniku program, dodałem że na samym początku (zaraz pouruchomieniu) AVR wysyłą do PC 0xFF, w ten sposób sprawdzisz, czy AVR ci się resetuje, jeżeli w terminalu co jakiś czas bedziesz dostawał 0xFF, tak jak pisałem wyzej wystarczy dorzucić pare kondensatorów (pomimo tego że używam zasilacza stabilizowanego w którym są naprawde duuuuże kondensatory)
    Załączniki:
    • KBD2RS_Start_0xFF.rar (859 Bajtów) Musisz być zalogowany, aby pobrać ten załącznik.

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy budowy konwertera PS/2 na RS-232 z wykorzystaniem mikrokontrolera Atmega8 oraz programowania w Bascomie. Problemem jest poprawne odczytywanie i przesyłanie kodów klawiszy z klawiatury PS/2 do komputera przez interfejs UART. Wskazano, że program wysyła surowe kody klawiszy, w tym kody specjalne (0xE0) i kody puszczenia klawisza (0xF0), bez translacji. Użytkownik zgłasza problemy z niepoprawnymi danymi i niestabilnością transmisji, co może wynikać z resetów mikrokontrolera spowodowanych niewystarczającym filtrowaniem zasilania. Zaproponowano dodanie kondensatorów elektrolitycznych przy zasilaniu Atmegi8 w celu stabilizacji pracy. Omówiono także konfigurację UART (19200 baud, 8 bitów danych, brak parzystości, 1 bit stopu) oraz różnice w taktowaniu (wewnętrzny oscylator 8 MHz vs. zewnętrzny kwarc 16 MHz). Do testów zalecane jest wysyłanie znaków z terminala do mikrokontrolera i odbieranie ich z powrotem w celu weryfikacji poprawności połączenia. Podano przykłady kodów skanowania klawiszy i ich interpretacji.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA