PC Keyboard question


Results 1 to 14 of 14

Threaded View

  1. #5
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    In the end I didn't use a 16F84A, but purely because the code space wasn't big enough for what i wanted to do. Also, I never ended up using any special PBP commands, opting to write a subroutine using interrupts that would get the timing perfect. I used an 18F1320 with it's 8Mhz internal clock, but I think 4Mhz would work too.

    Here's my code:

    Code:
    INCLUDE             "DT_INTS-18.bas"                        ' Include base interrupt system
    INCLUDE             "ReEnterPBP-18.bas"
    
    ' Interrupt Aliases                                         
    INT0IE              var INTCON.4                            ' INT0 external interrupt enable bit
    INTEDG0             var INTCON2.6                           ' INT0 external interrupt edge select bit: 1=Rising Edge 0=Falling Edge
    
    ' I/O
    kb_clock            var PORTB.0                             ' Keyboard clock pin
    kb_data             var PORTB.1                             ' Keyboard data pin
    
    ' Constants
    buffer_size         CON 32                                  ' Keyboard buffer size
    
    ' Variables
    packet              var word bank0                          ' Latest packet from the keyboard
    packet_index        var byte bank0                          ' Current bit in keyboard packet
    buffer              var byte[buffer_size] bank0             ' Keyboard data buffer
    buffer_i_index      var byte bank0                          ' Current buffer possition for inputs
    buffer_o_index      var byte bank0                          ' Current buffer possition for outputs
    data_received       var byte bank0                          ' Latest byte retrieved from the buffer
    n                   var word bank0                          ' Temporary variable for loops
    temp                var word bank0                          ' General temporary variable
    new_data            var bit bank0                           ' Flag to indicate there is new data from the keyboard
    parity_bit          var bit bank0                           ' Parity bit used for PIC->keyboard communication
    error               var bit bank0                           ' Flag to indicate an invalid packet
    
    ' Initialisation
    INPUT kb_clock                                              ' Keyboard Clock Pin = Input
    INPUT kb_data                                               ' Keyboard Data Pin = Input
    
    ASM                                                         
    INT_LIST macro   ;  IntSource   Label           Type   Reset Flag?
        INT_Handler     INT0_INT,   _int0_handler,  PBP,   yes
        endm
        INT_CREATE
    ENDASM
    
    INTEDG0=0                                                   ' INT0 Interrupt to Trigger on Falling Edge
    
    @ INT_ENABLE INT0_INT
    
    
    
    main:
    gosub check_for_new_data
    IF new_data=1 then
        ' Do whatever you want with the byte we just received. It is stored in data_received.       
    ENDIF
    goto main
    
    
    
    
    
    ' Keyboard interrupt handler: Retrieves packet from keyboard
    int0_handler:
    packet.11=kb_data                                          ' Store bit
    packet=packet>>1                                           ' Rotate the packet so it is ready for the next bit
    packet_index=packet_index+1                                ' Increment packet bit index
    iF packet_index=11 then                                    ' If packet is complete:
        gosub check_packet_for_errors                          ' Check the packet for errors
        if error=1 then                                        ' If there was an error:          
            packet=0                                           ' Discard the packet
            packet_index=0                                     ' Reset the packet bit index
            goto int_exit                                      ' Exit the interrupt
        ENDIF
        packet_index=0                                         ' Reset Packet Index
        packet=packet>>1                                       ' Discard the start bit
        buffer[buffer_i_index]=packet.byte0                    ' Store just the recieved byte
        buffer_i_index=buffer_i_index+1                        ' Increment buffer input index
        if buffer_i_index=buffer_size then buffer_i_index=0    ' If end of buffer has been reached, reset the index
        IF buffer_i_index=buffer_o_index THEN                  ' If the buffer is full:
            INT0IE=0                                           ' Disable Interrupt
            OUTPUT kb_clock                                    ' Set the keyboard's clock as output
            low kb_clock                                       ' Set the keyboard's clock line low (tell the keyboard to stall)
        endif                                               
    endif
    int_exit:
    @ INT_RETURN
    
    
    
    ' Subroutine to check to see if there is any new data waiting in the keyboard buffer
    check_for_new_data:
    IF buffer_o_index!=buffer_i_index then                      ' If the buffer is not empty:
        data_received=buffer[buffer_o_index]                    ' Get the next byte from the buffer
        new_data=1                                              ' Set the new data flag
        buffer_o_index=buffer_o_index+1                         ' Increment buffer output index 
        if buffer_o_index=buffer_size then buffer_o_index=0     ' If end of buffer has been reached, reset the index
        IF INT0IE=0 THEN                                        ' If the buffer was full, its now got a space, so:
            INPUT kb_clock                                      ' Release the keyboard's clock line
            INT0IE=1                                            ' Re-enable the interrupt
        ENDIF
    else
        new_data=0                                              ' If the buffer is empty, clear the new_data flag
    endif
    return
    
    
    
    ' Subroutine to check the incoming packet for errors
    check_packet_for_errors:
    error=0                                                     ' Reset error flag
    parity_bit=1                                                ' Set parity bit for start of calculation
    temp=packet                                                 ' Copy the packet to a temp variable so we can play with it
    if packet.0=1 then                                          ' Check that start bit = 0
        error=1
        return
    endif
    if packet.10=0 then                                         ' Check that stop bit = 1
        error=1
        return
    endif
    temp=temp>>1                                                ' Discard the start bit
    for n=0 to 7                                                ' Calculate what the bit parity should be
        if packet.0=1 then toggle parity_bit
        temp=temp>>1
    next n
    if packet.10!=parity_bit then                               ' Check the parity bit
        error=1
        return
    endif
    return
    Last edited by Kamikaze47; - 10th September 2007 at 07:27.

Similar Threads

  1. PC keyboard to ASCII
    By interak in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 1st October 2009, 17:51
  2. AT/PS2 Keybord - PIC Interface?
    By Kamikaze47 in forum Code Examples
    Replies: 73
    Last Post: - 9th August 2009, 16:10
  3. One USB keyboard to Two USB Ports
    By picnaut in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 11th June 2009, 00:04
  4. Question for the PC guru's
    By Bruce in forum Off Topic
    Replies: 24
    Last Post: - 28th January 2008, 21:05
  5. Pic to PC AT keyboard caracters
    By sezgin05 in forum General
    Replies: 5
    Last Post: - 27th March 2007, 10:45

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts