PDA

View Full Version : 16f688 NES controller not working properly



emerson
- 14th November 2011, 17:21
Here is what I am trying to do. I have two 16f688 chips communicating with the hardware serial ports. I have a Nintendo NES controller attached to the transmitter chip and an LCD attached to the receiver chip.

In theory, the transmitter chip sends a pulse to the controller down the latch line, reads the state of the data line and stores the value in the EEPROM. Then the transmitter sends a pulse down the clock line, which tells the controller to send the state of the second button down the data line. This process repeats 8 times so all button states can be stored. The controller will send the button states in this order: A, B, Start, Select, Up, Down, Left, Right. The transmitter then sends a trigger ("I") and the first button state to the receiver, and repeats 8 times for each button.

The receiver waits for the trigger ("I"), then stores the state of the first button in a variable. The variable is saved to the EEPROM and the process repeats 8 times. The receiver then will read the EEPROM and display the button state of each button on the screen.


A few things aren't working right though. First off, the A button is the only one that will respond, but the controller works fine when playing Nintendo. And second, the A button will change the state of all buttons on the LCD screen. The screen should be set up to display a 1 when the corresponding button is open, and a 0 when it's pressed, but instead of getting "0 1 1 1 1 1 1 1" when I press A, I get "0 0 0 0 0 0 0 0".

Everything else appears to work fine. If anyone could take a look at my code it would be greatly appreciated. I am using Microcode Studio with a melabs U2 programmer and MPASM assembler. Here are some websites that may help with understanding how the NES controller works.

http://www.zero-soft.com/HW/USB_NES_old/
http://web.mit.edu/tarvizo/web/nes-controller.html
http://www.nxp.com/documents/data_sheet/HEF4021B.pdf

and my codes:

transmitter


include "modedefs.bas"

ANSEL = 0
CMCON0 = 0

'~~~~~Serial Transmitter Definitions~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DEFINE HSER_RCSTA 90h ' Enable Serial PORT
DEFINE HSER_TXSTA 24h ' Enable transmit
DEFINE HSER_SPBRG 25 ' set USART to 9600 baud (when BRGH=1)
DEFINE HSER_CLROERR 1 ' Enable automatic overrun error
DEFINE LOADER_USED 1


'~~~~~Variables~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~
LATCH var portc.0 'pin 10
CLK var portc.1 'pin 9
DAT var portc.2 'pin 8

SerData var byte
CNT var byte

serdata = 0
cnt = 0
dat = 1

'pause 2000


'~~~~~Main Program~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Main:

low latch 'reset LATCH line
low clk 'reset CLK line


'~~~~~Read state of controller buttons and write them to EEPROM~~~~~~~~~~~~~~~~~~~~

pulsout latch, 12 'send a 12us high pulse down latch line to controller

'pauseus 1 '1us evens out initial CLK timing

for cnt = 0 to 7 '1us set CNT value
write cnt, dat '1us write state (1 or 0) of DAT pin to CNT value
' EEPROM location
pauseus 4 '4us
'6us total

pulsout clk, 6 '6us send 6us pulse down CLK line so controller
' will send next button state
next '1us repeat 8 times
'7us total


'~~~~~Send state of controller buttons to receiver~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

cnt = 0 'reset CNT value

for cnt = 0 to 7 'read EEPROM and send data serially 8 times
read cnt, serdata 'read EEPROM at CNT value location
hserout ["I", serdata] 'send wait trigger "I" and state of each button to receiver
next

goto main


and the receiver


ANSEL = 0
TRISC = 0
CMCON0 = 0

DEFINE LCD_DREG PORTC 'Define PIC port used for LCD Data lines
DEFINE LCD_DBIT 0 'LCD Data Starting Bit = Bit 0 or 4
DEFINE LCD_EREG PORTA 'Define PIC port used for E line of LCD
DEFINE LCD_EBIT 5 'Define Port pin used for E connection
DEFINE LCD_RSREG PORTA 'Define PIC port used for RS line of LCD
DEFINE LCD_RSBIT 4 'Define Port pin used for RS connection
DEFINE LCD_BITS 4 'Define the 4 bit communication mode to LCD
DEFINE LCD_LINES 2 'Define using a 2 line LCD
DEFINE LCD_COMMANDUS 2000 'Define delay time between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data sent.

Pause 500 ' Wait for LCD to startup


'~~~~~Serial Receiver Definitions~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
DEFINE HSER_RCSTA 90h ' Enable Serial PORT
DEFINE HSER_TXSTA 24h ' Enable transmit
DEFINE HSER_SPBRG 25 ' set USART to 9600 baud
DEFINE HSER_CLROERR 1 ' Enable automatic overrun error
DEFINE LOADER_USED 1


'~~~~~Variables~~~~~~~~~~~~~~~~~~

SerData var byte
SerData2 var byte
CNT var byte


'~~~~~Main Program~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'" "
lcdout $fe, 1, " NES CONTROLLER "

Main:

for cnt = 0 to 7 'set CNT value
hserin [Wait ("I"), serdata] 'wait for trigger "I" and store the button
'state in SerData
write cnt, serdata 'write button state to CNT value EEPROM location
next 'repeat 8 times

CNT = 0 'reset CNT value
lcdout $fe, $c0 'put LCD cursor to beginning of second line
for cnt = 0 to 7 'set CNT value
read cnt, serdata2 'read EEPROM CNT value location and store
'value in SerData2
lcdout dec1 serdata2, " " 'display SerData2 value and move right one space
next 'repeat 8 times

goto main