⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 input_module.asm

📁 这个开发机器人项目源码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;    $Id: input_module.asm,v 1.8 2003/10/03 00:45:36 dwalters Exp $;    Copyright (C) 2003  Dafydd Walters <dwalters@users.sourceforge.net>;;    This program is free software; you can redistribute it and/or modify;    it under the terms of the GNU General Public License as published by;    the Free Software Foundation; either version 2 of the License, or;    (at your option) any later version.;;    This program is distributed in the hope that it will be useful,;    but WITHOUT ANY WARRANTY; without even the implied warranty of;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;    GNU General Public License for more details.;;    You should have received a copy of the GNU General Public License;    along with this program (COPYING.SOFTWARE); if not, write to the ;    Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, ;    MA  02111-1307  USA; ---------------------------------------------------------------------- title "input_module.asm - OAP Input Module" processor pic16f84 list r=dec ; set radix to decimal include "p16f84.inc"; ----------------------------------------------------------------------; Inputs (internal pull-ups enabled on port B):;  RB0 - RF In ;  RB1 - Pushbutton Keypad Matrix Input #1;  RB2 - Pushbutton Keypad Matrix Input #2;  RB3 - Pushbutton Keypad Matrix Input #3;  RB4 - IR In #1;  RB5 - IR In #2;  RB6 - IR In #3;  RB7 - IR In #4;  RA2 - PS/2 Keyboard Clock Input;; Outputs:;  RA0 - Pushbutton Keypad Matrix Strobe Output Row 2;  RA1 - Pushbutton Keypad Matrix Strobe Output Row 1;  RA3 - PS/2 Keyboard Clock Output;; Input and Output (changes from one to the other at varying times):;  RA4 - PS/2 Keyboard Data Input and Output;; The two pushbutton keypad strobe output signals cannot be driven at the; same time, otherwise a situation could arise where the supply is shorted; if two buttons in the same column are pressed simultaneously. For this; reason, when one of the strobes is driven Low, the other is set to an input; (a high impedance state).;; The PS/2 Keyboard Clock and Data lines are open collector signals. Therefore; we take advantage of the fact that RA4 is an open collector output to drive; the Data signal. Since the PIC16F84 has no other open collector outputs,; we employ an external transistor (Q1) on RA3 to drive the Clock signal.; Since this is an NPN transistor, we effectively have to use negative logic; when driving RA3, i.e. set output High to pull Clock Low.; This program senses input from one of three sources:;;  a) Local 6-button keypad, arranged in a 2x3 matrix (2 strobes and 3 inputs);  b) IR remote control;  c) RF remote control;; The program senses the start of IR or RF input activity by way of hardware; interrupts. Keypad activity is sensed by polling the keypad switch matrix; in the main (foreground) thread of the program.;; If both RF and IR remote contol are enabled, a signal received from the IR; remote takes precedence over a signal received from the RF remote, even if; transmission of a data word from the RF remote has already started. This is; necessary to get around the fact that the signal from the RF receiver ; component is very noisy when there's no RF signal being recieved. Without; this measure, the random noise signal on the RF input line effectively ; masks out the IR remote signal much of the time. The slight downside to this; is that there is also some noise (albeit much less) from the IR receiver; component too, which may sometimes mask RF signals.;; The transmission of data to the PC via synchronous serial transfer is ; performed in the main (foreground) thread. While data is being transferred; between the Input Module and the PC, interrupts are disabled to preserve; the integrity of the synchronous timing requirements of the PS/2 keyboard; protocol (quiescent noise from the IR or RF receiver components can; trigger many spurious interrupts; the time spent servicing these interrupts; would disrupt the timing loops of the foreground thread if interrupts were; not disabled).;; There are many nuances to the PS/2 keyboard protocol, but this program; largely ignores them, and tries to get away with the minimum compliance; necessary to bluff the host PC into thinking it's talking to a real; keyboard. For example, most of the host-to-keyboard commands are simply; acknowledged, and then ignored. Protocol error handling is also implemented; in a simplistic way that may not work for every possible failure mode.; This code has been tested on a few different PC motherboards and has been; found to work, so it seems we've got away with it ;-);; As far as the remote control protocol is concerned, both the IR and RF ; inputs are interpreted in SONY IR format:;; ********************************************************************; *   The SONY IR packet consists of three repeated words with       *; *   encoding done as variable width bursts of 40khz IR.            *; *   Inter word gap is     26.0ms                                   *; *   Start/leader bit is    2.5ms                                   *; *   One bit is             1.3ms                                   *; *   Zero bit is            0.7ms                                   *; *   Inter bit/synch gap is 0.7ms  (IR is OFF, signal is HIGH)      *; *   12 bits per word (7 command code bits, and 5 device code bits) *; *   Lowest order bit is transmitted first                          *; *                   1     0     1     0    0    ...                *; *   ___          _      _    _      _    _    _         __.._      *; *      |________| |____| |__| |____| |__| |__| |__...._|     |__   *; *        Start     Bit 1   2     3     4    5        12       Start*; *                                                                  *; ********************************************************************;; We assume TV (as opposed to Cable, VCR, etc) remote codes are used for the; IR remote control:;; +Volume  = UP; -Volume  = DOWN; -Channel = LEFT; +Channel = RIGHT; Enter    = ENTER; Power    = ENTER; Mute     = ESCAPE;; Numeric buttons on the remote correspond to their own digits.;; Infrared remote control can be disabled (useful in situations where there; may be IR remotes operating nearby and interfering with the robot) by; pressing and holding down the [Down Arrow] and [Right Arrow] buttons at the; same time for at least 2.5 seconds.  Infrared control is re-enabled by; holding down the [Left Arrow] and [Down Arrow] buttons at the same time for; at least 2.5 seconds.;; Radio remote control can be disabled (useful in situations where there; may be RF sources operating nearby and interfering with the robot) by; pressing and holding down the [Right Arrow] button for at least 2.5 seconds.; RF control is re-enabled by holding down the [Left Arrow] button for at ; least 2.5 seconds.;; The normal Sony IR protocol is to transmit 12-bit words (least significant; bit first) where the upper 5 bits identify the device (e.g. TV, VCR, etc.); and the lower 7 bits identify the command (e.g. +Volume, -Channel, etc.).; However, we stop "listening" once we've received the first 8 bits (which; means that, since the data is actually sent LSbit first, for IR remotes,; we get the 7 command bits, and just the least significant bit of the device; code). We mask off the upper 3 bits of the received byte, so ultimately, we; only care about the 5 least significant bits of the command code. The ; resulting 5 bit number (0 to 31) is what we use to look up the command in the; IR Scan Code Tables.;; Although the RF remote uses the same timings as the Sony protocol, it only; sends 8 bits.  Since the code that parses the bitstream from the IR remote; ignores anything received after 8 bits anyway, we can use the same code to ; parse the bitstream from the RF remote. The only difference is that we use; the upper 3 bits of the 8-bit word as a Robot ID code (akin to a "channel"; selection), to identify the particular RF remote that's transmitting, to ; avoid contention when there's more than one robot using the same protocol ; in the same vicinity. The Input Module is "tuned" to a particular RF remote; by setting its Robot ID, stored in EEPROM.;; Setting the Robot ID on the Input Module is performed by holding down a ; combination of the buttons in the top row of the keypad for >= 2.5 seconds.; When used this way, the three buttons in the top row form a 3-bit binary; number, with the right hand button being the least significant bit. So for; example, to set the Robot ID to 5, you would press and hold down the left; and right keys together for at least 2.5 seconds (4 + 1 = 5). To program 3, ; you would hold down the right two keys (2 + 1 = 3).;; Both the Robot ID Code setting, and the IR remote Enabled/Disabled flag; setting, are stored in EEPROM and will therefore survive power cycles.; The initial default settings are Robot ID = 1, and IR Enabled.;; For more notes relating to this program, please see the README file.; ----------------------------------------------------------------------; Constants#define RF_IN PORTB,0#define STROBE1_DIRECTION TRISA^0x080,1#define STROBE2_DIRECTION TRISA^0x080,0#define ROBOT_CODE_EE_ADDR 0#define IR_ENABLE_CODE_EE_ADDR 1#define RF_ENABLE_CODE_EE_ADDR 2#define ENABLE_REMOTE_CODE 0x050#define DISABLE_REMOTE_CODE 0x0A0#define KEYPAD_COL1 PORTB,1#define KEYPAD_COL2 PORTB,2#define KEYPAD_COL3 PORTB,3#define STROBE1 PORTA,1#define STROBE2 PORTA,0#define KEYBOARD_DATA PORTA,4#define KEYBOARD_DATA_DIRECTION TRISA^0x080,4#define KEYBOARD_CLOCK_OUT PORTA,3#define KEYBOARD_CLOCK_IN PORTA,2#define LEFT_ARROW_SCAN_CODE1 0x0E0#define RIGHT_ARROW_SCAN_CODE1 0x0E0#define UP_ARROW_SCAN_CODE1 0x0E0#define DOWN_ARROW_SCAN_CODE1 0x0E0#define ENTER_SCAN_CODE1 0x000#define ESCAPE_SCAN_CODE1 0x000#define LEFT_ARROW_SCAN_CODE2 0x06B#define RIGHT_ARROW_SCAN_CODE2 0x074#define UP_ARROW_SCAN_CODE2 0x075#define DOWN_ARROW_SCAN_CODE2 0x072#define ENTER_SCAN_CODE2 0x05A#define ESCAPE_SCAN_CODE2 0x076#define ONE_MS_DELAY 31#define REMOTE_STOP_DELAY 50            ; ms of "silence" from remote control; ----------------------------------------------------------------------; Variable Declarations (GPR) starting at data address 0x020 cblock 0x020HiCountScanCode1ScanCode2LoopCountBATloopCountParityDelayLoopCountKeyUpWaitCountKeyRowDataByteToSendReceiveByteReceivedRobotCodeIREnabledSettingRFEnabledSettingIRInterruptRemoteReceiveState RemoteReceiveMaskRemoteReceiveBitCountRemoteReceiveByte       ; Stores least significant 8-bits of remote code.RemoteStopCounterPortBStateSavedWSavedStatusSavedFSRSavedPCLATH; The RemoteReceiveState variable stores the current state of IR remote control; communications:;; 0=waiting for IR or RF leader to start, ; 1=waiting for IR leader to end,; 2=waiting for end of sync bit,; 3=waiting for end of data bit,; 4=waiting for scancode to be sent to host.; 5=waiting for remote signal to stop transmitting. endc; ----------------------------------------------------------------------; Configuration bits: ;; - Code Protection off; - Crystal oscillator; - Power-Up Timer on; - Watchdog Timer off __CONFIG _CP_OFF & _XT_OSC & _PWRTE_ON & _WDT_OFF; ----------------------------------------------------------------------; Program entry point at device reset org 0 goto MainStart; ----------------------------------------------------------------------; Interrupt Handler entry point org 4 goto IntStart; ----------------------------------------------------------------------; Table of Robot ID Code bit patterns from key patternsKeyRobotIDTable addwf PCL,f retlw 0                        ; Not valid retlw 4 << 5                   ; [Escape] retlw 2 << 5                   ; [Up Arrow] retlw 6 << 5                   ; [Escape] + [Up Arrow] retlw 1 << 5                   ; [Enter] retlw 5 << 5                   ; [Escape] + [Enter] retlw 3 << 5                   ; [Up Arrow] + [Enter] retlw 7 << 5                   ; [Escape] + [Up Arrow] + [Enter]; ----------------------------------------------------------------------; Table of conversions from IR Codes to Scan Codes (byte # 1)IRScanCode1Table movlw 0x1F andwf RemoteReceiveByte,w      ; Mask upper 3 bits of received byte addwf PCL,f retlw 0x000                    ; 0 : 1 on TV remote retlw 0x000                    ; 1 : 2 on TV remote retlw 0x000                    ; 2 : 3 on TV remote retlw 0x000                    ; 3 : 4 on TV remote retlw 0x000                    ; 4 : 5 on TV remote retlw 0x000                    ; 5 : 6 on TV remote retlw 0x000                    ; 6 : 7 on TV remote retlw 0x000                    ; 7 : 8 on TV remote retlw 0x000                    ; 8 : 9 on TV remote retlw 0x000                    ; 9 : 0 on TV remote retlw 0x000                    ; 10: not used retlw ENTER_SCAN_CODE1         ; 11: Enter retlw 0x000                    ; 12: 1- on TV remote retlw 0x000                    ; 13: 2- on TV remote retlw 0x000                    ; 14: C on TV remote retlw 0x000                    ; 15: not used retlw RIGHT_ARROW_SCAN_CODE1   ; 16: +Channel on TV remote retlw LEFT_ARROW_SCAN_CODE1    ; 17: -Channel on TV remote retlw UP_ARROW_SCAN_CODE1      ; 18: +Volume on TV remote retlw DOWN_ARROW_SCAN_CODE1    ; 19: -Volume on TV remote retlw ESCAPE_SCAN_CODE1        ; 20: Mute on TV remote retlw ENTER_SCAN_CODE1         ; 21: Power on TV remote retlw 0x000                    ; 22: Normal on TV remote retlw 0x000                    ; 23: Audio mode on TV remote retlw 0x000                    ; 24: not used retlw 0x000                    ; 25: not used retlw 0x000                    ; 26: not used retlw 0x000                    ; 27: not used retlw 0x000                    ; 28: not used retlw 0x000                    ; 29: -/-- on TV remote retlw 0x000                    ; 30: not used retlw 0x000                    ; 31: not used IF ((HIGH($)) != (HIGH(IRScanCode1Table)))     ERROR("IRScanCode1Table crosses page boundary!") ENDIF; ----------------------------------------------------------------------; Table of conversions from IR Codes to Scan Codes (byte # 2)IRScanCode2Table movlw 0x1F andwf RemoteReceiveByte,w      ; Mask upper 3 bits of received byte addwf PCL,f retlw 0x016                    ; 0 : 1 on TV remote retlw 0x01E                    ; 1 : 2 on TV remote retlw 0x026                    ; 2 : 3 on TV remote retlw 0x025                    ; 3 : 4 on TV remote retlw 0x02E                    ; 4 : 5 on TV remote retlw 0x036                    ; 5 : 6 on TV remote retlw 0x03D                    ; 6 : 7 on TV remote retlw 0x03E                    ; 7 : 8 on TV remote retlw 0x046                    ; 8 : 9 on TV remote retlw 0x045                    ; 9 : 0 on TV remote retlw 0x000                    ; 10: not used retlw ENTER_SCAN_CODE2         ; 11: Enter retlw 0x000                    ; 12: 1- on TV remote retlw 0x000                    ; 13: 2- on TV remote retlw 0x000                    ; 14: C on TV remote retlw 0x000                    ; 15: not used retlw RIGHT_ARROW_SCAN_CODE2   ; 16: +Channel on TV remote retlw LEFT_ARROW_SCAN_CODE2    ; 17: -Channel on TV remote retlw UP_ARROW_SCAN_CODE2      ; 18: +Volume on TV remote retlw DOWN_ARROW_SCAN_CODE2    ; 19: -Volume on TV remote retlw ESCAPE_SCAN_CODE2        ; 20: Mute on TV remote retlw ENTER_SCAN_CODE2         ; 21: Power on TV remote retlw 0x000                    ; 22: Normal on TV remote retlw 0x000                    ; 23: Audio mode on TV remote retlw 0x000                    ; 24: not used retlw 0x000                    ; 25: not used retlw 0x000                    ; 26: not used retlw 0x000                    ; 27: not used retlw 0x000                    ; 28: not used retlw 0x000                    ; 29: -/-- on TV remote retlw 0x000                    ; 30: not used retlw 0x000                    ; 31: not used IF ((HIGH($)) != (HIGH(IRScanCode2Table)))     ERROR("IRScanCode2Table crosses page boundary!") ENDIF; ----------------------------------------------------------------------; Interrupt handler start point

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -