Hello, I am fairly new to programming with PICBASIC Pro and have run into a problem. I am currently using a Snes Controller, a Pic16F887, and a HD44780 compatible display (4 lines, 20 char)
I'm reading the output of the Snes Controller, and am trying to display what character is pressed on the LCD screen. I have a word variable which stores the button values from a shiftin command. This word is then displayed on the LCD. (I have fixed this portion of the problem, read past the italics)My problem is that the only button that changes anything displayed is the "B" button, and when B is pressed, it reads as all buttons being pressed (The LCD shows 0000000000000000 where 0 means pressed, 1 means unpressed.) When B is not pressed it reads 1111111111111111. When B is pressed it should read 0111111111111111 since the B button's status is the first bit transferred. I fixed the italicized portion to an extent, I cannot read any buttons after "Y" (the second bit sent) because my timing is not exact enough. Sometimes Y registers like it should, sometimes it does not, so I will have to work on the timing.
I found this information about how the controller passes information:
The SNES controller has three data pins plus +5V power and ground.*A high on
the Data Latch pin for 12 us signals the controller to start sending data
which is clocked by a sequence of 16 pulses (6 us high, 6 us low) on the
clock pin. Serial data (8 buttons + 4 directions + 4 unused signals) is
returned on the serial data pin.*The serial data is negative-edge triggered.
Clock Cycle Button Reported
=========== ===============
1 B
2 Y
3 Select
4 Start
5 Up on joypad
6 Down on joypad
7 Left on joypad
8 Right on joypad
9 A
10 X
11 L
12 R
13 none (always high)
14 none (always high)
15 none (always high)
16 none (always high)
My current code programmed onto the PIC is as follows:
Code:
Include "modedefs.bas"
OSCCON = %01110000 ' INTRC = 8MHz
DEFINE OSC 8
DEFINE LCD_DREG PORTB ' Set LCD Data port
DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus i.e, PortD.4-PORTD.7
DEFINE LCD_RSREG PORTD ' Set LCD Register Select port
DEFINE LCD_RSBIT 2 ' Set LCD Register Select bit i.e, PORTC.5
DEFINE LCD_EREG PORTD ' Set LCD Enable port
DEFINE LCD_EBIT 4 ' Set LCD Enable bit i.e, PORTE.4
DEFINE LCD_BITS 8 ' Set LCD bus size ot 4 bit Upper Nibble (4 or 8 bits)
DEFINE LCD_LINES 4 ' Set number of lines on LCD to 4 Lines
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
DEFINE LCD_DATAUS 50 ' dSet data delay time in us
DEFINE LCD_RWREG PORTD
DEFINE LCD_RWBIT 3
theoutput var Word
ANSEL = 0
PAUSE 1000 ' Wait a second
OUTPUT PORTC.1 ' configure input/output pins
OUTPUT PORTC.0
INPUT PORTC.2
LOW PORTC.1 ' Initialize LATCH
LOW PORTC.0 ' Initialize CLK
Loop: ' Main loop
PULSOUT PORTC.1, 10 ' Latch the data
SHIFTIN PORTC.2, PORTC.0, LSBPRE,[theoutput \16] ' Shift in socket 1 data
LCDOUT $FE, 1, BIN16 dasresult ' Display values
pause 50
GOTO Loop
END ' Repeat main loop
My guess on what is going on is that the internal oscillator might not be precise enough and is causing timing problems with the shiftin operation, but it could also be due to a complete lack of understanding of the shiftin operation, as this is the first time I've used it.
Does anyone have any ideas as to what might be going on? I'm not looking for someone to completely spell things out for me as I like t solve these kinds of problems, but a few nudges if anyone has some insight to this problem would be great. If anyone would like me to provide any more information please let me know.
Edit: Looking at some example code for a PS2 controller, I believe my shiftin code may be wrong, I'm going to mess around with it and see if that helps.
Edit2: spotted an error with the shiftin statement, 0 should be PORTC.0, will report back in a bit.
Edit3: It is now working to an extent. There is a timing issue as button Y, the next bit reported, will sometimes register as pressed to the mcrocontroller, and sometimes not, while all bits after it register no presses.
Bookmarks