View Full Version : Help! Need Programming Help!
DubbleD
Mar 27, 2009, 04:26 PM
Hey Guys! I'm really new to programming PICs, I used to program in BASIC many years ago, but I'm having some trouble getting all my ducks in a row with the new stuff, so I need to ask some questions. I've built several of the navigation light projects out there and they're all great, but now I want to learn to do it myself, to make the program do exactly what I want it to do.
I found a program that was designed to flash a pair of LEDs, that I wanted to use for strobe lights on an RC aircraft. It flashed two different LEDs, each in a double-blink pattern, but for some reason they didn't blink at the same rate, so they would start out blinking in an alternating pattern, first one, then the other, but then after a few seconds they would actually be blinking in sync with each other, both at the same time, then they would gradually drift back apart for a while, and so on and so on. Not cool looking, watching them made my eyes cross, I was afraid I'd get hypnotized and crash. So I found a different program that also flashed two LEDs, one after another, but they only blinked once each, and they stayed on about 1/2 second each, too slow and too long to simulate aircraft strobes. I have managed to figure out the program enough to change the variable that controls the length of time each LED stays on, so I can make them both flash very quickly, like a strobe, but only once each, back and forth. I need to somehow interrupt the program with a loop that blinks each LED twice before switching to the other LED. Here is the portion of the program that controls the flash of the LEDs, and I'll try to give all the info about it I can think of.
;----------------------------------------------
;-------FLASH STROBE LIGHTS (T1;;STRB1;;STRB2;;TMR4)
K5_____DECFSZ TMR4,F
_______GOTO MAIN
_______MOVLW T1_______;RESTORE TMR4
_______MOVWF TMR4
_______BTFSS GPIO,STRB1
_______GOTO K6________;LSTA=0
_______BCF GPIO,STRB1__;LSTA=1
_______BSF GPIO,STRB2
_______GOTO MAIN
K6_____BSF GPIO,STRB1__;LSTA=0
_______BCF GPIO,STRB2
_______GOTO MAIN
;----------------------------------------------
_______END
Sorry about all the underlines-the forum wouldn't let me cut and paste from the .asm file, it ignored my spaces and kept cramming all the words next to each other, so I had to use underlines to make it readable.
T1 is the variable that controls how long the LED stays "on", TMR4 is the timer that controls (I think) how long it takes the program to loop around again, STRB1 and STRB2 are the two LEDs. As you can see, the program looks to see if STRB1 is set, if not then it goes to K6 and sets STRB1 and clears STRB2, then the program loops around and the next time through it does just the opposite, which makes the two LEDs flash alternately. I've discovered that the LED is actually "on" when the bit is cleared, (BCF GPIO,STRB1) is that correct??
OK, here's where I need HELP! I've experimented some by modifying the .asm file and re-compiling it, the compiler didn't report any errors and so I programmed my PIC with the new .hex file, but I got OSC errors and it rendered my chip unusable, so I'm running out of PICs! Here's what I'd like to be able to do......I want each LED to blink twice while the other LED remains off. I can get the blink rate to where it needs to be by adjusting the value of T1, but every time either LED is turned off, the other is turned on, so all I'm getting is a rapid, alternating flashing back and forth of both LEDs. I'm thinking I need to insert another variable that I can count up (INCF) or down (DECF) that will cause the program to bypass the line that turns the other LED on, and forces it to loop around and flash the same LED again, then the next time through maybe use the DECFSZ command to send it to the second section that flashes the opposite LED, and do the same thing in that section. But I can't figure out exactly where to put it or how. Does that make any sense? Can anybody help me with this? I've tried to do it but I'm making some kind of mistake that either causes it to not work, or worse yet frys my chip.
I know it's hard to help someone that doesn't understand any more than I do, so I apologize. I'm sure these are stupid questions to most of you guys, but I'm trying really hard to learn this stuff. I just this morning figured out how define my PIC and set the config fuses in the program so I wouldn't have to remember to do it manually before programming it. :D
Thanks if you can help.
DubbleD (Dumb and Dumber)
Malc C
Mar 27, 2009, 05:36 PM
The following code worked for me using a 12F675 PIC. I'm sure you can modify it to suit your needs. It basically double flashes three LEDs in sequence.. ie
flash,flash....flash,flash....flash,flash
list p=12F675
#include "p12f675.inc"
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF
del_lo equ 0x20
del_hi equ 0x21
org 0x00
nop
goto init
org 0x04
return
init
banksel 0x80 ;select upper register bank
clrf ANSEL ;make all I/O ports digital
movlw 0x0B
movwf TRISIO ;make GP4 and GP5 outputs
banksel 0x00 ;select lower register bank
clrf GPIO ;initialise all outputs
clrf del_lo ;initialise delay counter low byte
clrf del_hi ;initialise delay counter high byte
flash
bsf GPIO,4 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine
bcf GPIO,4 ;set output GP4 low
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine
bsf GPIO,4 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine
bcf GPIO,4 ;set output GP4 low
movlw 0xFF
movwf del_hi
call delay ;call the delay subroutine
bsf GPIO,2 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine
bcf GPIO,2 ;set output GP4 low
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine
bsf GPIO,2 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine
bcf GPIO,2 ;set output GP4 low
movlw 0xFF
movwf del_hi
call delay ;call the delay subroutine
bsf GPIO,5 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine
bcf GPIO,5 ;set output GP4 low
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine
bsf GPIO,5 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine
bcf GPIO,5 ;set output GP4 low
movlw 0xFF
movwf del_hi
call delay ;call the delay subroutine
goto flash ;go back and do it again
delay
decfsz del_lo,f ;decrement the low order delay register
goto delay ;go back if it hasn't reached zero
decfsz del_hi,f ;decrement the high order delay register
goto delay ;go back if it hasn't reached zero
return ;return to where the subroutine was called
end
If you change the value of the line movlw 0x45 the delay rate between the flashes change
Hope this helps
DubbleD
Mar 27, 2009, 06:26 PM
Thanks Malc C, with a little more help I think I can make that work. I see that you have three different sections that output to pins 4,2, and 5, in that order, so I think I can handle changing the code to output to the pins I have empty for my strobes. Am I correct in thinking that if I want to change the amount of delay between the pairs of flashes, not between each flash, I would change the values of the "del_lo equ 0x20" and/or "del_hi equ 0x21" lines at the beginning of the program? The reason I'm asking is that if I don't, it seems like there would be a pause in my program between the flash cycles of my two strobes if I only use two of the three sections you have. Is that right?
One more question, what does the code after the del_lo and before the init section do? Is it important to the flash timing?
OK, I lied. Two more questions. Do I need to insert the "del_lo/del_hi" and "init" sections at the beginning of my program, or just at the beginning of the FLASH portion of my program?
Thanks for your help. I know these are really elemetary questions, but I think I'm learning something.
DD
Malc C
Mar 28, 2009, 09:25 AM
To be perfectly honest, its a long time since I got involved with that code. It was my first "tutorial" on assembly, and it sank in so much that I never used assembly again and switched to PicBASIC as, like you have a better understanding of the BASIC commands and logic. From memory the delay routine simply counts down a register until it reaches 0, so not sure on how to actually change the delay between each sets of flashes. I'm hoping some of the more experienced assembly coders here can chip in and offer you some advice.
The alternative would be to download and use the excellent Microbasic application and re-write your code in basic...
robe_uk
Mar 28, 2009, 12:16 PM
del_lo equ 0x20
del_hi equ 0x21 these two lines are defining general purpose RAM resistors used by the program for counters or the like.
org 0x00 Tells assembler program where to put the following code 0x00 is the start of code point for the 675
nop
goto init This tells program to goto init, which is the start of the program
org 0x04 0x04 is the interupt vector for the 675, if there was an interupt, which acts like a call command the next line just makes it return
return
OK, I lied. Two more questions. Do I need to insert the "del_lo/del_hi" and "init" sections at the beginning of my program, or just at the beginning of the FLASH portion of my program?
del_lo/del_hi = as above defining general RAM resistors, I tend to do the following,
cblock 0x20
del_lo
del_hi
etc....
endc
This lets me define general purpose registors quickly, check data sheets to see how many are available to you.
The init section is setting up ports etc and only has to be done once.
The way I tend to lay out a program is;
define processor and fuses
define my RAM registors
define things for assembler, ie if using PORTA is a servo output port I would write
#define servoport PORTA; or servoport equ PORTA, this means any time I refer to PORTA in my program I use servoport so if i change my mind and decide to use PORTB i only have to change one line of code.
Then I have my main program
Main:
call init ;initalize ports etc, only tends to be done once so at start of Main. which I put in a subroutine out of the way at bottom of code,
Mainloop: ;I tend to split everything into smaller sub routines and loop around calling them.
call checksomething
call do some maths
call output something
goto Mainloop
I have very limited programming knowledge (so hopefully those who do dont laugh to loudly at me :o )but know enough the assembly takes a lot of lines to do very little, am to lazy to learn 'c' or something
Alison F
Mar 28, 2009, 12:46 PM
Hi DD,
Have you seen the PICLIST site on the net? I found that really useful when I was starting out. http://www.piclist.com/techref/microchip/index.htm
I work with PICs for a living, and mostly once you have your basic construct and outline established then everything else goes on top. Here...
This is a cut down version btw, with most of my core code chopped out.
;------------------------------------------------------------------------------
;0.0.Project Summary
;------------------------------------------------------------------------------
;Immiediate release version: 0.06
;*
; _MCLRE_OFF
; _CP_ON
; _DATA_CP_ON
;------------------------------------------------------------------------------
;0.1.Compiler setup
;------------------------------------------------------------------------------
LIST P=16F627A, R=DEC ;16F627, decimal system
#include "P16F627A.INC" ;link pre-defines, standard EQU's etc.
;LIST P=16F648A, R=DEC ;16F627, decimal system
;#include "P16F648A.INC" ;link pre-defines, standard EQU's etc.
__idlocs 0x0061 ;give the chip an ID word number
;set the config/fuse string
__config _INTOSC_OSC_NOCLKOUT & _PWRTE_ON & _LVP_OFF & _WDT_OFF & _BOREN_ON & _MCLRE_OFF & _CP_ON & _DATA_CP_ON
ERRORLEVEL -302 ;remove message about using proper bank
;------------------------------------------------------------------------------
;0.2.Constants and equates
;------------------------------------------------------------------------------
;port assignments of the uart
RS232_RX_PORTB_ EQU 1
RS232_TX_PORTB_ EQU 2
;psx port assignments
PSX_DAT_PORTB_I_ EQU 7
PSX_CMD_PORTB_O_ EQU 4
PSX_CLK_PORTB_O_ EQU 6
PSX_ACK_PORTB_I_ EQU 5
PSX_ATN_PORTB_O_ EQU 3
PSX_MASK_TRISB_ EQU b'10100010'
;amiga mouse assignments
AMIGA_YB_PORTA_ EQU 7 ;RA7 - Pin 16 ;DTYPE - Pin 1
AMIGA_XA_PORTA_ EQU 0 ;RA0 - Pin 17 ;DTYPE - Pin 2
AMIGA_YA_PORTA_ EQU 4 ;RA4 - Pin 3 ;DTYPE - Pin 3
AMIGA_XB_PORTA_ EQU 3 ;RA3 - Pin 2 ;DTYPE - Pin 4
;AMIGA_MB_PORTA_ EQU 2 ;RA2 - Pin 1 ;DTYPE - Pin 5
;AMIGA_LB_PORTA_ EQU 6 ;RA6 - Pin 15 ;DTYPE - Pin 6
;AMIGA_RB_PORTA_ EQU 1 ;RA1 - Pin 18 ;DTYPE - Pin 9
;atari mouse assignments
ATARI_XB_PORTA_ EQU 7 ;RA7 - Pin 16 ;DTYPE - Pin 1
ATARI_XA_PORTA_ EQU 0 ;RA0 - Pin 17 ;DTYPE - Pin 2
ATARI_YA_PORTA_ EQU 4 ;RA4 - Pin 3 ;DTYPE - Pin 3
ATARI_YB_PORTA_ EQU 3 ;RA3 - Pin 2 ;DTYPE - Pin 4
ATARI_XB_PORTA_BIT_ EQU b'10000000' ;RA7 - Pin 16 ;DTYPE - Pin 1
ATARI_XA_PORTA_BIT_ EQU b'00000001' ;RA0 - Pin 17 ;DTYPE - Pin 2
ATARI_YA_PORTA_BIT_ EQU b'00010000' ;RA4 - Pin 3 ;DTYPE - Pin 3
ATARI_YB_PORTA_BIT_ EQU b'00001000' ;RA3 - Pin 2 ;DTYPE - Pin 4
;ATARI_LB_PORTA_ EQU 6 ;RA6 - Pin 15 ;DTYPE - Pin 6
;ATARI_RB_PORTA_ EQU 1 ;RA1 - Pin 18 ;DTYPE - Pin 9
;atari joystick assignments
ATARI_UP_PORTA_ EQU 7 ;RA7 - Pin 16 ;DTYPE - Pin 1
ATARI_DOWN_PORTA_ EQU 0 ;RA0 - Pin 17 ;DTYPE - Pin 2
ATARI_LEFT_PORTA_ EQU 4 ;RA4 - Pin 3 ;DTYPE - Pin 3
ATARI_RIGHT_PORTA_ EQU 3 ;RA3 - Pin 2 ;DTYPE - Pin 4
ATARI_BUT1_PORTA_ EQU 6 ;RA6 - Pin 15 ;DTYPE - Pin 6
ATARI_BUT2_PORTA_ EQU 1 ;RA1 - Pin 18 ;DTYPE - Pin 9
ATARI_BUT3_PORTA_ EQU 2 ;RA2 - Pin 1 ;DTYPE - Pin 5 (7800)
;psx button encoding
PSX_BYTE4_LEFT_ EQU 7
PSX_BYTE4_DOWN_ EQU 6
PSX_BYTE4_RIGHT_ EQU 5
PSX_BYTE4_UP_ EQU 4
PSX_BYTE4_START_ EQU 3
PSX_BYTE4_RIGHT_THUMB_ EQU 2
PSX_BYTE4_LEFT_THUMB_ EQU 1
PSX_BYTE4_SELECT_ EQU 0
PSX_BYTE5_L2_ EQU 7
PSX_BYTE5_R2_ EQU 6
PSX_BYTE5_L1_ EQU 5
PSX_BYTE5_R1_ EQU 4
PSX_BYTE5_TRIANGLE_ EQU 3
PSX_BYTE5_O_ EQU 2
PSX_BYTE5_X_ EQU 1
PSX_BYTE5_SQUARE_ EQU 0
;psx control flags
PSX_SELECT_CMD_FLAG_BUSY_ EQU 0
PSX_START_VAR_FLAG_BUSY_ EQU 1
PSX_ANALOGUE_MODE_ EQU 4
PSX_REPEAT_LEFTRIGHT_ EQU 5
PSX_REPEAT_TOGGLE_ EQU 6
PSX_REPEAT_TOGGLE_XOR_ EQU b'01000000'
PSX_COMMAND_AWAITING_ EQU 7
;EQU's relating to the rs232 messages stored in EEPROM
RS232_EE_MESSAGE_RESET_ EQU 1
RS232_EE_MESSAGE_MARKER_ EQU 7 ;this identifies the start of a message
;setup_config_flags_
SETUP_CONFIG_FLAG_ATARI_ EQU 0 ; -------x ;0x00 = 1 = ATARI ST Mouse , 0 = AMIGA
; ------x- ;0x01 =
; -----x-- ;0x02 =
; ----x--- ;0x03 =
; ---x---- ;0x04 =
; --x----- ;0x05 =
SETUP_CONFIG_FLAG_RIGHT_THUMB_ EQU 6 ; -x------ ;0x06 = 1 = LEFT THUMBSTICK , 0 = RIGHTTHUMBSTICK
SETUP_CONFIG_FLAG_PIN5_ EQU 7 ; x------- ;0x07 = Pin 5 / 7800 Enabled on DIGITAL
SETUP_CONFIG_FLAG_PIN5_XOR_ EQU b'10000000'
SETUP_CONFIG_FLAG_ATARI_XOR_ EQU b'00000001'
SETUP_CONFIG_FLAG_RT_THUMB_XOR_ EQU b'01000000'
;deciphering the PSX packets with mouse
MOUSE_FLAGS_RIGHT_ EQU 0x01 ; -------x ;1 = RIGHT, 0 = LEFT
MOUSE_FLAGS_UP_ EQU 0x02 ; ------x- ;1 = UP, 0 = DOWN
MOUSE_FLAGS_DIR_ EQU 0x03 ; -----x-- ;1 = RIGHT/DOWN, 0 = LEFT/UP
MOUSE_FLAGS_ANAL_THUMB_ EQU 0x04 ; -x------ ;1 = there was thumbstick movement
MOUSE_FLAGS_Y_MOVEMENT_ EQU 0x05 ; --x----- ;1 = there is y movement
MOUSE_FLAGS_X_MOVEMENT_ EQU 0x06 ; -x------ ;1 = there is x movement
MOUSE_FLAGS_ANALOGUE_ EQU 0x07 ; x------- ;1 = ANALOGUE
MOUSE_QA_STARTUP_ EQU b'01100110' ;initial quadrature position
MOUSE_QB_STARTUP_ EQU b'11001100' ;initial quadrature position
;quadrature delay values
MOUSE_DELAY_PAD_X_ EQU 5d
MOUSE_DELAY_PAD_Y_ EQU 5d
MOUSE_DELAY1_THUMB_X_ EQU 3d
MOUSE_DELAY1_THUMB_Y_ EQU 3d
MOUSE_DELAY2_THUMB_X_ EQU 2d
MOUSE_DELAY2_THUMB_Y_ EQU 2d
MOUSE_DELAY3_THUMB_X_ EQU 1d
MOUSE_DELAY3_THUMB_Y_ EQU 1d
;------------------------------------------------------------------------------
;0.3.Function Variables (80 bytes in bank 0, 20h-6Fh)
;------------------------------------------------------------------------------
;0020 to 002F (16 bytes)
CBLOCK 0x20
psx_tx_byte_ ;the byte to be transmitted
psx_rx_byte_ ;the byte being received
psx_rx_byte1_
psx_rx_byte2_ ;
psx_rx_byte3_ ;Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 - PSX
psx_rx_byte4_ ;SLCT STRT UP RGHT DOWN LEFT
psx_rx_byte5_ ;L2 R2 L1 R1 /\ O X |_|
psx_rx_byte6_ ;RIGHT JOY, 0x00 = LEFT, 0xFF = RIGHT
psx_rx_byte7_ ;RIGHT JOY, 0x00 = UP, 0xFF = DOWN
psx_rx_byte8_ ;LEFT JOY, 0x00 = LEFT, 0xFF = RIGHT
psx_rx_byte9_ ;LEFT JOY, 0x00 = UP, 0xFF = DOWN
ENDC
;0030 to 003F (16 bytes)
CBLOCK 0x30
psx_byte4_tally_ ;we use this to gather our SELECT presses from the other buttons
psx_byte5_tally_ ;we use this to gather our SELECT presses from the fire buttons
psx_control_flags_ ; -------x ;0x00 = PSX_SELECT_CMD_FLAG_BUSY_
; ------x- ;0x01 = PSX_START_VAR_FLAG_BUSY_
; -----x-- ;0x02 =
; ----x--- ;0x03 =
; ---x---- ;0x04 = PSX_ANALOGUE_MODE_
; --x----- ;0x05 = PSX_REPEAT_LEFTRIGHT_
; -x------ ;0x06 = PSX_REPEAT_TOGGLE_
; x------- ;0x07 = PSX_COMMAND_AWAITING_
psx_byte4_select_cmd_ ;the command captured goes in here
psx_byte5_select_cmd_ ;the command captured goes in here
psx_byte4_start_var_ ;the variable captured goes in here
psx_byte5_start_var_ ;the variable captured goes in here
ENDC
;0040 to 004F (16 bytes)
CBLOCK 0x40
setup_button1_mask_ ;the following 9 bytes HAVE to always be here
setup_button2_mask_ ;as we're going to be writing straight into memory
setup_button3_mask_
setup_button1_repeat_mask_
setup_button2_repeat_mask_
setup_button3_repeat_mask_
setup_leftright_mask_
setup_repeat_rate_
setup_config_flags_
atari_tx_byte_ ;this byte is the shadow of PORTA
setup_mask_result_ ;we AND this with the current packet
setup_repeat_rate_counter_ ;this is what we compare to.
ENDC
;0050 to 005F (16 bytes)
CBLOCK 0x50
mouse_control_flags_ ; -------x ;0x00 = 0 = UP, 1 = DOWN
; ------x- ;0x01 = 0 = LEFT, 1 = RIGHT
; -----x-- ;0x02 =
; ----x--- ;0x03 =
; ---x---- ;0x04 =
; --x----- ;0x05 =
; -x------ ;0x06 =
; x------- ;0x07 = 0 = DIGITAL, 1 = ANALOGUE
mouse_pwm_xa_ ; these store the pwm quadrature counter
mouse_pwm_xb_ ; these store the pwm quadrature counter
mouse_pwm_ya_ ; these store the pwm quadrature counter
mouse_pwm_yb_ ; these store the pwm quadrature counter
mouse_delay_digital_x_ ; this is the delay applied to the digital pad
mouse_delay_digital_y_ ; this is the delay applied to the digital pad
mouse_delay_analogue_x_ ; this is the delay applied to the analogue stick
mouse_delay_analogue_y_ ; this is the delay applied to the analogue stick
mouse_value_thumb_x_ ;
mouse_value_thumb_y_ ;
ENDC
;------------------------------------------------------------------------------
;0.4.Global Variables (16 bytes in all banks, 70h-7Fh)
;------------------------------------------------------------------------------
;0070 to 007F (16 bytes)
CBLOCK 0x70
vec_pushed_w_buffer_ ;must be visible from every bank
vec_pushed_status_buffer_ ;must be visible from every bank
ee_byte_ ;must be visible from every bank
ee_pointer_ ;must be visible from every bank
bank1_pass_ ;must be visible from every bank
loop1_ ;must be visible from every bank
temp1_
rs232_byte_
rs232_ee_message_counter_
ENDC
;------------------------------------------------------------------------------
;1.0.Core Program Code begins (1024 bytes)
;------------------------------------------------------------------------------
ORG 0x000 ;(0d) 128bytes allocated
GOTO Start ;goto start of program
ORG 0x004 ;start of interupt vector
GOTO Interrupt_Vector
;------------------------------------------------------------------------------
;1.1.Start
;------------------------------------------------------------------------------
Start:
CLRW
CALL SETUP_LOAD_EEPROM ;load the SETUP0 defaults from EEPROM
CALL SETUP_VARS ;set everything to default start values, flags etc.
CALL SETUP_PORTS ;set the ports up, 7800 port etc.
MOVLW RS232_EE_MESSAGE_RESET_
CALL RS232_OUTPUT_EE_MESSAGE ;send our alive message
CALL SETUP_TMR0
;------------------------------------------------------------------------------
;1.2.Main
;-------------------------------------------------------------------------------
Main_loop_begins:
BTFSS psx_control_flags_, PSX_COMMAND_AWAITING_
GOTO Main_loop_ends
BCF INTCON, T0IE ;disable TIMER0 interrupt
BCF INTCON, GIE
BTFSS psx_byte4_select_cmd_, PSX_BYTE4_START_ ;is this an 01 command which doesn't have variables?
CALL CMD_HANDLER_01
BTFSC psx_byte4_select_cmd_, PSX_BYTE4_START_ ;is this an 09 command which does have variables?
CALL CMD_VAR_HANDLER_09
BCF psx_control_flags_, PSX_COMMAND_AWAITING_ ;don't come back here again
BSF INTCON, GIE
BSF INTCON, T0IE ;enable TIMER0 interrupt
Main_loop_ends:
GOTO Main_loop_begins
;------------------------------------------------------------------------------
;1.3.Interrupt Vector
;------------------------------------------------------------------------------
Interrupt_Vector:
Vec_push:
;W and STATUS will be pushed when these interrupts are branched to
MOVWF vec_pushed_w_buffer_ ;1;store W immiediately!!
MOVF STATUS, W ;store status
MOVWF vec_pushed_status_buffer_
BCF STATUS, RP0 ;ensure that we're actually in bank0 right now!!
CALL INT_SERVICE_INTERRUPTS ;we have to call as we need to pop afterwards
Vec_pop:
MOVF vec_pushed_status_buffer_, W ;in reverse order
MOVWF STATUS
MOVF vec_pushed_w_buffer_, W ;restore ready to return
RETFIE
;------------------------------------------------------------------------------
;1.4.Service Interrupts
;------------------------------------------------------------------------------
INT_SERVICE_INTERRUPTS
;all other interrupts we ignore, they shouldn't occur anyway
Int_service_disconnected:
CALL PSX_GET_PACKET
;If the controller is disconnected then 0xFF will be returned in psx_rx_byte_5
INCFSZ psx_rx_byte2_, F
GOTO Int_service_connected
MOVLW 'Q'
CALL RS232_SEND_BYTE
;MOVLW 0x11
;CALL RS232_OUTPUT_HEX_BYTE
;MOVLW 0x00
;CALL RS232_OUTPUT_HEX_BYTE
;CALL RS232_OUTPUT_CRLF
;CALL RS232_OUTPUT_CRLF
GOTO Int_service_disconnected
Int_service_connected:
DECF psx_rx_byte2_, F
;We have to decide here what to do.
;Firstly, is SELECT being pressed?
;If it is then we're not going to be doing anything else on this occasion.
;Ahhh, but have we already collected a command, and are now collecting the data?
;This bit is VERY important, as the only thing that can stop it now is START being pressed.
BTFSC psx_control_flags_, PSX_START_VAR_FLAG_BUSY_
GOTO Int_service_collecting_var
BTFSS psx_rx_byte4_, PSX_BYTE4_SELECT_ ;active low
GOTO Int_service_collecting_cmd ;go and collect a command
;We can also end up here if SELECT has just been released.
;psx_control_flags_, PSX_SELECT_FLAG_BUSY_ will still be set from when we were collecting the command
;Let's see if it's still set...
BTFSC psx_control_flags_, PSX_SELECT_CMD_FLAG_BUSY_ ;This will only be set if there's a new command waiting
GOTO Int_service_command_collected ;If it is, then go and do something about it!
;No, none of that lot up above, so let's carry on like we would 99% of the time
INCF setup_repeat_rate_counter_, F
MOVF setup_repeat_rate_, W ;this is our repeat rate to match against
XORWF setup_repeat_rate_counter_, W
BTFSC STATUS, Z
GOTO Int_service_repeat_toggle
GOTO Int_service_skip_repeat_toggle
Int_service_repeat_toggle:
MOVLW PSX_REPEAT_TOGGLE_XOR_
XORWF psx_control_flags_, F
CLRF setup_repeat_rate_counter_ ;start the counter again
;BTFSS psx_control_flags_, PSX_REPEAT_TOGGLE_
;MOVLW '0'
;BTFSC psx_control_flags_, PSX_REPEAT_TOGGLE_
;MOVLW '1'
;CALL RS232_SEND_BYTE
;MOVLW 'R'
;CALL RS232_SEND_BYTE
Int_service_skip_repeat_toggle:
BTFSS psx_control_flags_, PSX_ANALOGUE_MODE_ ;have we received an analogue packet?
GOTO Int_service_packet_is_digital
Int_service_packet_is_analogue:
CALL PSX_TO_MOUSE ;we're in analogue mode
BCF psx_control_flags_, PSX_ANALOGUE_MODE_ ;clear this occurance
GOTO Int_service_complete ;we're not gathering a command, so finish up
Int_service_packet_is_digital:
CALL PSX_TO_ATARI_JOY ;we're in digital mode
GOTO Int_service_complete ;we're not gathering a command, so finish up
Int_service_collecting_cmd:
CALL PSX_GATHER_SELECT_CMD_INPUT
GOTO Int_service_complete
Int_service_command_collected:
;We are here as a command has been collected
;So let's save that command
MOVF psx_byte4_tally_, W
MOVWF psx_byte4_select_cmd_
MOVF psx_byte5_tally_, W
MOVWF psx_byte5_select_cmd_
;We also won't be coming here again either
BCF psx_control_flags_, PSX_SELECT_CMD_FLAG_BUSY_ ;we won't come here again this time
;But is there variable data still to collect too before we finish here?
;If START "was" pressed, then yes there is
; CLRF psx_byte4_start_var_ ;these DO NOT have to actually be cleared here
; CLRF psx_byte5_start_var_ ;it's just that on RS232 it gets confusing if there's junk data!!
BTFSS psx_byte4_select_cmd_, PSX_BYTE4_START_
GOTO Int_service_command_ready
CLRF psx_byte5_tally_ ;clear the tally
CLRF psx_byte4_tally_
BSF psx_control_flags_, PSX_START_VAR_FLAG_BUSY_ ;
;Now we start collecting data next time round!!!!!
GOTO Int_service_complete
Int_service_collecting_var:
;We're here as we're collecting buttons
;The ONLY thing that can stop this is START
COMF psx_rx_byte5_, W
IORWF psx_byte5_tally_, F
COMF psx_rx_byte4_, W
IORWF psx_byte4_tally_, F
BTFSS psx_byte4_tally_, PSX_BYTE4_START_ ;Has START been pressed?
GOTO Int_service_complete
;Yes!!! It bloody well has!!
BCF psx_control_flags_, PSX_START_VAR_FLAG_BUSY_
MOVF psx_byte4_tally_, W
MOVWF psx_byte4_start_var_
MOVF psx_byte5_tally_, W
MOVWF psx_byte5_start_var_
;That's it!! We're done here!!!
Int_service_command_ready:
BSF psx_control_flags_, PSX_COMMAND_AWAITING_
Int_service_complete:
BCF INTCON, T0IF ;clear the TMR0 interrupt flag
RETURN
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;0.0.Setup, Support, and RS232 procedures begin (256 bytes)
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ORG 0300H
;------------------------------------------------------------------------------
;Subroutine : PSX_GET_PACKET
;------------------------------------------------------------------------------
;Passed : N/A
;Valid : N/A
;Uses : psx_rx_byte1_ thru psx_rx_byte9_
;Returns : psx_rx_byte?_ contains valid bytes
;Error Code : W contains FF in event of disconnected controller
;Error Trapping : N/A
;Outline : Receives DIGITAL 5-Byte or ANALOGUE 8-Byte packets
;------------------------------------------------------------------------------
PSX_GET_PACKET
BSF PORTB, PSX_CLK_PORTB_O_ ;set CLOCK high
BSF PORTB, PSX_CMD_PORTB_O_ ;set COMMAND high
BCF PORTB, PSX_ATN_PORTB_O_ ;bring ATTENTION low, start
MOVLW 0x01 ;psx start command
MOVWF psx_tx_byte_
CALL PSX_RW_BYTE
MOVWF psx_rx_byte1_
MOVLW 0x42 ;psx request data command
MOVWF psx_tx_byte_
CALL PSX_RW_BYTE
MOVWF psx_rx_byte2_
MOVLW 0xFF ;CMD idle, no command
MOVWF psx_tx_byte_
CALL PSX_RW_BYTE
MOVWF psx_rx_byte3_
MOVLW 0xFF ;idle, no command
MOVWF psx_tx_byte_
CALL PSX_RW_BYTE
MOVWF psx_rx_byte4_
MOVLW 0xFF ;idle, no command
CALL PSX_RW_BYTE
MOVWF psx_rx_byte5_
;0x41 = digital, 2 bytes data
;0x53 = analogue green, 6 bytes data
;0x73 = analogue red, 6 bytes data
BTFSS psx_rx_byte2_, 0x01 ;test for analogue pad
GOTO Psx_get_packet_done
BSF psx_control_flags_, PSX_ANALOGUE_MODE_ ;set the flag to identify analogue mode
MOVLW 0xFF ;idle, no command
CALL PSX_RW_BYTE
MOVWF psx_rx_byte6_
MOVLW 0xFF ;idle, no command
CALL PSX_RW_BYTE
MOVWF psx_rx_byte7_
MOVLW 0xFF ;idle, no command
CALL PSX_RW_BYTE
MOVWF psx_rx_byte8_
MOVLW 0xFF ;idle, no command
CALL PSX_RW_BYTE
MOVWF psx_rx_byte9_
Psx_get_packet_done:
BSF PORTB, PSX_CLK_PORTB_O_ ;bring clock high
BSF PORTB, PSX_ATN_PORTB_O_ ;bring ATTENTION high, finish
RETURN
;------------------------------------------------------------------------------
;Subroutine : PSX_RW_BYTE
;------------------------------------------------------------------------------
;Passed : W contains byte to be transmitted
;Valid : N/A
;Uses : psx_tx_byte_ , psx_rx_byte_ , loop1_
;Returns : Byte received in W and psx_rx_byte_
;Error Code : N/A
;Error Trapping : N/A
;Outline : SPI style byte transfer
;------------------------------------------------------------------------------
PSX_RW_BYTE
MOVWF psx_tx_byte_
MOVLW 8d ;we will be transferring 8 bits
MOVWF loop1_
Psx_rw_byte_next_bit:
BCF PORTB, PSX_CLK_PORTB_O_ ;bring clock low
RRF psx_tx_byte_, F ;put transmitted data on bus
BTFSS STATUS, C
BCF PORTB, PSX_CMD_PORTB_O_
BTFSC STATUS, C
BSF PORTB, PSX_CMD_PORTB_O_
BSF PORTB, PSX_CLK_PORTB_O_ ;bring clock high
BCF STATUS, C
BTFSC PORTB, PSX_DAT_PORTB_I_ ;get received data from bus
BSF STATUS, C
RRF psx_rx_byte_, F
DECFSZ loop1_, F
GOTO Psx_rw_byte_next_bit ;next bit
BSF PORTB, PSX_CMD_PORTB_O_ ;set COMMAND high
MOVF psx_rx_byte_, W ;value returned to caller
RETURN
;------------------------------------------------------------------------------
;Subroutine : SETUP_PORTS
;------------------------------------------------------------------------------
;Passed : N/A
;Valid : N/A
;Uses :
;Returns : N/A
;Error Code : N/A
;Error Trapping : N/A
;Outline : Sets the ports up for first time use
;------------------------------------------------------------------------------
SETUP_PORTS
MOVLW b'00000111' ;07 into register, port A pins
MOVWF CMCON ;Comparators off, all pins digital I/O
MOVF setup_config_flags_, W
MOVWF ee_byte_ ;put into a bank 1 variable
CLRF PORTA ;all ports low by default
CLRF PORTB ;all ports low by default
BSF STATUS, RP0 ;0003h, 0005h, select RAM bank 1
BCF OPTION_REG, NOT_RBPU ;enable portb weak pull-ups, clear=enable
CLRF TRISA ;all pins as outputs by default
BTFSS ee_byte_, SETUP_CONFIG_FLAG_PIN5_
BSF TRISA, ATARI_BUT3_PORTA_ ;set as an input
MOVLW PSX_MASK_TRISB_
MOVWF TRISB
;Setup baud rate = 19200, No Parity, 1 Stop Bit
MOVLW 0x19 ;0x19=9600 bps, 0x0C=19200 bps, 0x06=38400
MOVWF SPBRG
MOVLW b'00100100' ;brgh = high (2)
MOVWF TXSTA ;enable async transmission, set brgh
BCF STATUS, RP0 ;0003h, 0005h, select RAM bank 0
MOVLW b'10010000' ;enable async reception
MOVWF RCSTA
;allow RS232 to settle
MOVF RCREG, W
MOVF RCREG, W
MOVF RCREG, W ;flush receive buffer
RETURN
;------------------------------------------------------------------------------
;Subroutine : SETUP_7800_PORT
;------------------------------------------------------------------------------
;Passed : N/A
;Valid : N/A
;Uses :
;Returns : N/A
;Error Code : N/A
;Error Trapping : N/A
;Outline : Sets the ports up for first time use
;------------------------------------------------------------------------------
SETUP_7800_PORT
MOVF setup_config_flags_, W
MOVWF ee_byte_ ;put into a bank 1 variable
BSF STATUS, RP0 ;0003h, 0005h, select RAM bank 1
BTFSS ee_byte_, SETUP_CONFIG_FLAG_PIN5_
BSF TRISA, ATARI_BUT3_PORTA_ ;set as an input
BTFSC ee_byte_, SETUP_CONFIG_FLAG_PIN5_
BCF TRISA, ATARI_BUT3_PORTA_ ;set as an output
BCF STATUS, RP0 ;0003h, 0005h, select RAM bank 0
RETURN
;------------------------------------------------------------------------------
;Subroutine : SETUP_VARS
;------------------------------------------------------------------------------
;Passed : N/A
;Valid : N/A
;Uses :
;Returns : N/A
;Error Code : N/A
;Error Trapping : N/A
;Outline : Resets variables to their default first time values
;------------------------------------------------------------------------------
SETUP_VARS
CLRF mouse_control_flags_
MOVLW MOUSE_QA_STARTUP_
MOVWF mouse_pwm_xa_
MOVWF mouse_pwm_ya_
MOVLW MOUSE_QB_STARTUP_
MOVWF mouse_pwm_xb_
MOVWF mouse_pwm_yb_
CLRF mouse_delay_digital_x_
CLRF mouse_delay_digital_y_
CLRF mouse_delay_analogue_x_
CLRF mouse_delay_analogue_y_
MOVLW MOUSE_DELAY1_THUMB_X_ ;This is the longest delay
MOVWF mouse_delay_analogue_x_
MOVLW MOUSE_DELAY1_THUMB_Y_ ;This is the longest delay
MOVWF mouse_delay_analogue_y_
CLRF psx_control_flags_
CLRF psx_byte4_start_var_
CLRF psx_byte5_start_var_
RETURN
;------------------------------------------------------------------------------
;Subroutine : SETUP_TMR0
;------------------------------------------------------------------------------
;Passed : N/A
;Valid : N/A
;Uses : TMR0 , BANK1 (PSA , PS2 , PS1 , PS0 , T0CS) T0IF , T0IE
;Returns : N/A
;Error Code : N/A
;Error Trapping : N/A
;Outline : Resets and starts TIMER0
;------------------------------------------------------------------------------
SETUP_TMR0
CLRF TMR0
BSF STATUS, RP0 ;must enter bank 1 for OPTION reg
BCF OPTION_REG, PSA ;prescaler assigned to TMR0, start the timer
BSF OPTION_REG, PS2 ;
BCF OPTION_REG, PS1 ;
BCF OPTION_REG, PS0 ;
BCF OPTION_REG, T0CS ;clear = on, set = off
BCF STATUS, RP0 ;return to bank 0
BCF INTCON, T0IF ;clear the TMR0 interrupt flag
BSF INTCON, T0IE ;0x05, enable TMR0 interrupts
BSF INTCON, GIE ;enable global interrupts, that's what this is
RETURN
; --------------------------------
; DUMPS MESSAGE IN EEPROM TO RS232
; --------------------------------
RS232_OUTPUT_EE_MESSAGE
MOVWF rs232_ee_message_counter_ ;store the message number which we are to retrieve
;set our starting location of eeprom
;we shall start with location 0 as we are searching for b'1000000'
MOVLW 0x48 ;the start of the messages in EEPROM
Rs232_find_ee_message:
MOVWF ee_pointer_
BSF STATUS, RP0 ;select Bank 1
MOVWF EEADR
BSF EECON1, RD ;EE Read
MOVF EEDATA, W ;store value in W
BCF STATUS, RP0 ;back to Bank 0
;W will contain the value just read from eeprom
MOVWF ee_byte_
BTFSS ee_byte_, RS232_EE_MESSAGE_MARKER_ ;RS232_EE_MESSAGE_MARKER_
GOTO Rs232_find_ee_message
;we are here as we have found a message!!
;is the message we have found the right one?
DECFSZ rs232_ee_message_counter_, F
GOTO Rs232_find_ee_message
;we are here as we have found our message number x
;the next byte to be read will be part of the message
;the message will be terminated by another marker b'1000000'
Rs232_read_next_ee_byte:
INCF ee_pointer_, F ;point to the next location
MOVF ee_pointer_, W ;put the current location into W
BSF STATUS, RP0 ;select Bank 1
MOVWF EEADR
BSF EECON1, RD ;EE Read
MOVF EEDATA, W ;store value in W
BCF STATUS, RP0 ;back to Bank 0
;W contains the byte
;is it a message marker?
MOVWF ee_byte_
BTFSC ee_byte_, 0x07 ;RS232_EE_MESSAGE_MARKER_
GOTO rs232_ee_message_complete
;no, it isn't a marker, so it is safe to send the byte to the rs232 port
;it is still contained in W, so is compatiable with the rs232 send procedure
CALL RS232_SEND_BYTE
GOTO Rs232_read_next_ee_byte
rs232_ee_message_complete:
RETURN
; --------------------------------
; OUTPUT BYTE TO RS232 PORT
; --------------------------------
RS232_SEND_BYTE
MOVWF TXREG ;load our value passed in W
BSF STATUS, RP0 ;enter ram page 1
Rs_tx_still_low:
BTFSS TXSTA, TRMT ;tranmission complete when high
GOTO Rs_tx_still_low
BCF STATUS,RP0 ;enter ram page 0
RETURN
; --------------------------------
; OUTPUT BYTE IN HEX TO RS232 PORT
; --------------------------------
RS232_OUTPUT_HEX_BYTE
MOVWF rs232_byte_ ;store our value
SWAPF rs232_byte_, F ;swap our nibble round
CALL RS232_CALC_HEX_NIBBLE
CALL RS232_SEND_BYTE ;Output the ascii character
SWAPF rs232_byte_, F ;swap our nibble round
CALL RS232_CALC_HEX_NIBBLE
CALL RS232_SEND_BYTE ;Output the ascii character
RETURN
; ----------------------------------
; OUTPUT NIBBLE IN HEX TO RS232 PORT
; ----------------------------------
RS232_CALC_HEX_NIBBLE
MOVLW 0x03
MOVWF PCLATH ;select the 4th bank of 256
MOVLW b'00001111'
ANDWF rs232_byte_, W
ADDWF PCL, F
RETLW '0'
RETLW '1'
RETLW '2'
RETLW '3'
RETLW '4'
RETLW '5'
RETLW '6'
RETLW '7'
RETLW '8'
RETLW '9'
RETLW 'A'
RETLW 'B'
RETLW 'C'
RETLW 'D'
RETLW 'E'
RETLW 'F'
RETURN
; --------------------------------
; SEND CR+LF
; --------------------------------
RS232_OUTPUT_CRLF
MOVLW 0x0D ;CR
CALL RS232_SEND_BYTE
MOVLW 0x0A ;LF
CALL RS232_SEND_BYTE
RETURN
;------------------------------------------------------------------------------
;Subroutine : SETUP_LOAD_EEPROM
;------------------------------------------------------------------------------
;Passed : W contains location to load
;Valid : 0d, 9d, 18d, 27d, 36d, 45d, 54d, 63d (0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F)
;Uses :
;Returns : N/A
;Error Code : N/A
;Error Trapping : N/A
;Outline :
;------------------------------------------------------------------------------
SETUP_LOAD_EEPROM
; setup_button1_mask_
; setup_button2_mask_
; setup_button3_mask_
; setup_button1_repeat_mask_
; setup_button2_repeat_mask_
; setup_button3_repeat_mask_
; setup_leftright_mask_
; setup_repeat_rate_
; setup_config_flags_
MOVWF ee_pointer_ ;This is where we load the first byte from
MOVLW 9d ;This is how many bytes we're going to be reading
MOVWF loop1_
MOVLW 0x40 ;the point in RAM where the buffer sits
MOVWF FSR
Setup_load_eeprom_another_byte:
MOVF ee_pointer_, W ;get the pointer
BSF STATUS, RP0 ;select Bank 1
MOVWF EEADR
BSF EECON1, RD ;EE Read
MOVF EEDATA, W ;store value in W
BCF STATUS, RP0 ;back to Bank 0
;We need to save W STRAIGHT into memory...
MOVWF INDF ;Indirect Addressing straight into memory
INCF FSR,F ;Point to the next point in RAM
INCF ee_pointer_, F
DECFSZ loop1_, F ;Get another one if necessary
GOTO Setup_load_eeprom_another_byte
RETURN
;------------------------------------------------------------------------------
;Subroutine : SETUP_SAVE_EEPROM
;------------------------------------------------------------------------------
;Passed : W contains location to save
;Valid : 0d, 9d, 18d, 27d, 36d, 45d, 54d, 63d (0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F)
;Uses :
;Returns : N/A
;Error Code : N/A
;Error Trapping : N/A
;Outline :
;------------------------------------------------------------------------------
SETUP_SAVE_EEPROM
MOVWF ee_pointer_ ;This is where we load the first byte from
MOVLW 9d ;This is how many bytes we're going to be reading
MOVWF loop1_
MOVLW 0x40 ;the point in RAM where the buffer sits
MOVWF FSR
Setup_save_eeprom_another_byte:
MOVF INDF, W ;get the data we're going to write
INCF FSR, F ;Point to the next point in RAM
BSF STATUS, RP0 ;Bank 1
MOVWF EEDATA ;the data
MOVF ee_pointer_, W ;get the pointer
MOVWF EEADR ;the address in EEPROM
BSF EECON1, WREN ;enable EE Write
MOVLW 0x55
MOVWF EECON2 ;write 55h
MOVLW 0xAA
MOVWF EECON2 ;write AAh
BSF EECON1, WR ;set WR bit
Setup_save_eeprom_wait: ;begin write
BTFSC EECON1, WR
GOTO Setup_save_eeprom_wait
BCF EECON1, WREN ;disable EE Write
INCF ee_pointer_, F
BCF STATUS, RP0 ;Bank 0
DECFSZ loop1_, F ;Get another one if necessary
GOTO Setup_save_eeprom_another_byte
RETURN
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;0.0.EEPROM data contents (128 bytes)
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ORG 0x2100 ;(8448 dec)
; setup_button1_mask_ ;1
; setup_button2_mask_ ;2
; setup_button3_mask_ ;3
; setup_button1_repeat_mask_ ;4
; setup_button2_repeat_mask_ ;5
; setup_button3_repeat_mask_ ;6
; setup_leftright_mask_ ;7
; setup_repeat_rate_ ;8
; setup_config_flags_ ;9
; /\ ---------+ +--------- R1
; | |
; O -------+ | | +------- L1
; | | | |
; X -----+ | | | | +----- R2
; | | | | | |
; # ---+ | | | | | | +--- L2
; | | | | | | | |
; 0 0 0 0 0 0 0 0
;psx_rx_byte3_ ;Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 - PSX
;psx_rx_byte4_ ;SLCT STRT UP RGHT DOWN LEFT
;psx_rx_byte5_ ;L2 R2 L1 R1 /\ O X |_|
BUTTON_SETUP_00_
DE b'01000000' ;1 CROSS
DE b'10000000' ;2 SQUARE
DE b'00010000' ;3 TRIANGLE
DE b'00001111' ;4 L1
DE b'00000000' ;5 R1
DE b'00000000' ;6
DE b'00000000' ;7 L2
DE b'00000111' ;8 32
DE b'00000000' ;9
BUTTON_SETUP_01_
DE b'01000000' ;1
DE b'10000000' ;2
DE b'00010000' ;3
DE b'00000101' ;4
DE b'00001010' ;5
DE b'00000000' ;6
DE b'00000000' ;7
DE b'00001111' ;8
DE b'01000000' ;9
BUTTON_SETUP_02_
DE b'11110000' ;1
DE b'00000000' ;2
DE b'00000000' ;3
DE b'00001111' ;4
DE b'00000000' ;5
DE b'00000000' ;6
DE b'00000000' ;7
DE b'00000111' ;8
DE b'00000000' ;9
BUTTON_SETUP_03_
DE b'01000000' ;1
DE b'10000000' ;2
DE b'00010000' ;3
DE b'00000100' ;4
DE b'00000001' ;5
DE b'00001000' ;6
DE b'00000100' ;7
DE b'00000111' ;8
DE b'01000001' ;9
; -------x ;0x00 = 0 = ATARI ST Mouse, 1 = AMIGA Mouse
; ------x- ;0x01 =
; -----x-- ;0x02 =
; ----x--- ;0x03 =
; ---x---- ;0x04 =
; --x----- ;0x05 =
; -x------ ;0x06 = 0 = LEFT THUMBSTICK , 1 = RIGHTTHUMBSTICK
; x------- ;0x07 = Pin 5 / 7800 Enabled on DIGITAL
BUTTON_SETUP_04_
DE b'01000000' ;1 CROSS
DE b'10000000' ;2 SQUARE
DE b'00010000' ;3 TRIANGLE
DE b'00001111' ;4 L1
DE b'00000000' ;5 R1
DE b'00000000' ;6
DE b'00000000' ;7 L2
DE b'00000111' ;8 32
DE b'00000000' ;9
BUTTON_SETUP_05_
DE b'01000000' ;1
DE b'10000000' ;2
DE b'00010000' ;3
DE b'00000101' ;4
DE b'00001010' ;5
DE b'00000000' ;6
DE b'00000000' ;7
DE b'00001111' ;8
DE b'01000000' ;9
BUTTON_SETUP_06_
DE b'11110000' ;1
DE b'00000000' ;2
DE b'00000000' ;3
DE b'00001111' ;4
DE b'00000000' ;5
DE b'00000000' ;6
DE b'00000000' ;7
DE b'00000111' ;8
DE b'00000000' ;9
BUTTON_SETUP_07_
DE b'01000000' ;1
DE b'10000000' ;2
DE b'00010000' ;3
DE b'00000100' ;4
DE b'00000001' ;5
DE b'00001000' ;6
DE b'00000100' ;7
DE b'00000111' ;8
DE b'01000001' ;9
RS_MSG_01_
DE b'10000000' ;the first bit indicates the beginning of a message
DE 0x0D ;CR
DE 0x0A ;LF
DE 'R'
DE 'E'
DE 'S'
DE 'E'
DE 'T'
DE '_'
DE '0'
DE '0'
DE '6'
DE 0x0D ;CR
DE 0x0A ;LF
RS_MSG_02_
DE b'10000000'
DE 0x0D ;CR
DE 0x0A ;LF
RS_MSG_03_
DE b'10000000'
;------------------------------------------------------------------------------
;0.0.PDIP/SOIC Package - 16F627A - 16F628A - 16F648A
;------------------------------------------------------------------------------
;
; 16F628A
; +-----\_/-----+
; RA2/AN2/VREF - | 1 18 | - RA1/AN1
; RA3/AN3/CMP1 - | 2 17 | - RA0/AN0
; RA4/TOCKI/CMP2 - | 3 16 | - RA7/OSC1/CLKIN
; RA5/MCLR/VPP - | 4 15 | - RA6/OSC2/CLKOUT
; VSS - | 5 14 | - VDD
; RB0/INT - | 6 13 | - RB7/T1OSI/PGD
; RB1/RX/DT - | 7 12 | - RB6/T1OSO/PGC
; RB2/TX/CK - | 8 11 | - RB5
; RB3/CCP1 - | 9 10 | - RB4/PGM
; +-------------+
;
; 16F628A
; +-----\_/-----+
; YB < | 1 18 | > RIGHT BUTTON
; YA < | 2 17 | > XA
; - | 3 16 | > XB
; - | 4 15 | > LEFT BUTTON
; GND - | 5 14 | - 5V
; - | 6 13 | ^ PS2_DATA_PORTB_LIVE_
; - | 7 12 | ^ PS2_CLOCK_PORTB_LIVE_
; TX < | 8 11 | ^ PS2_DATA_PORTB_TESTING_
; | 9 10 | ^ PS2_CLOCK_PORTB_TESTING_
; +-------------+
END
Hope that helps to get you started somewhat. It's always easier to come back to. :)
rmteo
Mar 28, 2009, 02:08 PM
Download this BASIC compiler/simulator (it's free for 30 days), and test out your program in the simulator with the 8 LED's. You could be done in a matter of hours - or minutes, since you are already familiar with BASIC:
http://www.oshonsoft.com/pic.html
http://www.oshonsoft.com/picscreenshot.png
DubbleD
Mar 28, 2009, 10:39 PM
Thanks guys, it will take me some time to digest all this info.
robe uk: Thanks for your help, it helps me understand what some of the commands are really doing. I hope you don't mind me asking some more questions.
1. Is the org 0x00 command really necessary, or does that just ensure that the program will occupy memory from the beginning of the RAM? And does the org 0x04 do anything in this program? If so, what? And to what point does the return line send it?
2. When I try to add this code to my program, the del_lo and del_hi sections are causing me conflicts in the program that prevent it from compiling correctly, specifically it seems to be the clrf del_lo and clrf del_hi lines that initialize the counters. When I try to compile I get errors in the build that say that those lines are attempting to overwrite previously used memory addresses. If I put ; in front of them it compiles OK but the program doesn't work right. Do I just need to place them in a different register to prevent that? Are del_lo and del_hi something that is used by the program to count up or down like the FOR/NEXT loops we used to use in BASIC?
3. I already have a user register defined as "DELAY", and the subroutine named DELAY in Malc C's code also causes errors in compiling, so could I just rename the references to it to something else, like "PAUSE"?
I have a small amount of code already written that moves a servo from one side to the other with a significant delay, about 4 seconds from 1.0ms to 2.0ms. It also sets the bit on either GP4 or GP5 depending on which way the servo moves to turn on landing light LEDs. I've already assigned all the ports and stuff, and that part is working perfectly. I tried just pasting Malc C's code into mine, but it's creating conflicts that keeping it from compiling. I think I can make the new code flash the strobes just like I want them to if I can just figure out how to resolve them. I tried the new code by itself, and it works perfectly, too. I just have to figure out how to combine them.
BTW, Thanks ALison F for the link, I found a ton of material there I need to pour through.
And rmteo, I'll look at the compiler you suggested. Does it actually let you write in BASIC? I'd have to start all over I guess, but that might be good for future projects. Too much to learn, and I'm starting too late. ;)
rmteo
Mar 28, 2009, 11:35 PM
Yes, you write code in BASIC. Look at the window (at top left) for the BASIC compiler.
robe_uk
Mar 29, 2009, 08:18 AM
1. Is the org 0x00 command really necessary, or does that just ensure that the program will occupy memory from the beginning of the RAM? And does the org 0x04 do anything in this program? If so, what? And to what point does the return line send it?
0x00 is the reset vector used by the pic, ie when the pic is turned on or reset this is the first location it looks at, as there are only a few memory locations before 0x04 the interupt vector the only real code we put here is 'goto main', so i would say it is important as you want the pic to jump to the correct start loction.
The main program is at 0x21 so at the start of your main program you would do,
org 0x00
goto Main
org 0x04
return
cblock 0x20
define various things etc
endc
org 0x21
Main:
code
code
dont get mixed up with RAM memory and program memory
The org 0x04 is basically the same except this loction is where the pic jumps to when an interupt occurs.
I will look for some links to good info sites about programming pic when I get back to my main PC.
Rob
rich smith
Mar 29, 2009, 01:22 PM
1. Is the org 0x00 command really necessary
Not needed because you don't need interrupts to bllink LEDs. Program does not need to be anywhere near as complicated either.
dmccormick001
Mar 30, 2009, 10:37 AM
Thanks guys, I'm really learning a lot with your help. The links have been great because I can pick up little tidbits that, I guess because I'm familiar with BASIC, I can use to figure things out by trial and error. I'm really enjoying it.
Good news is that I've figured out how to accomplish at least part of what I wanted to do. The program does three different things, it slows a servo down for use as a retract or flap servo, it turns on landing lights when the servo moves, and it flashes the strobe constantly. Because it's always "looking" for an input to move the servo, I can't allow the part of the program that flashes the strobes to get hijacked by a subroutine or any kind of "delay" loop or it will cause the rest of the program to malfunction. The code was written in such a way that once it set or cleared the bit controlling the strobe LED, the whole program would continue to loop around with the LED on or off until it had looped a certain number of times, and then it would toggle the bit. I can change the speed of the flash by changing the variable controlling the number of loop cycles before it toggles, but it makes the LED flash instead of blink. The off time was the same as the on time, and no matter how fast or slow I made it, it didn't look right. So what I wanted to do was set the bit very briefly, like a flash, then clear it, and leave it clear for about 3-4 times longer than the flash, then set it again and repeat it. What I finally figured out how to do was to change the place at which the timer variable was restored. So now after the bit is cleared, I've added code to restore the timer with a new, larger variable amount, and after a little experimentation with the variables I've got it blinking just right! Once I figured out the logic of the program, it only took a few new lines of code to do it.
But I'm greedy, and what I really wanted was a double blink strobe, so now I'm trying to perfect adding a second timer and variable, so that it will set the bit once for a quick blink (like it does now), clear it briefly, blink it a second time quickly, and then clear it for a longer time to produce a scale-like double blink. I think I can do it, I've just got to scratch my head a little more.
Acetronics
Mar 30, 2009, 12:22 PM
Hi,
Correct me if I'm wrong ... but I think Mr CAM already did such a thing available, on the web ...
"Landtastic" called.
Hope it helps.
Alain
Malc C
Mar 30, 2009, 12:47 PM
LOL nothing like trying to re-invent the wheel :)
Dan Baldwin
Mar 30, 2009, 01:51 PM
Here's (http://www.rc-cam.com/ldtastic.htm) a link to RC-Cam's landtastic.
Dan
robe_uk
Mar 30, 2009, 05:54 PM
sometimes its nice to 'D'o 'I't 'Y'ourself just to see if you can, and its nice to learn along to way, here are a few links I promised earlier, am sure google will turn up more.
Rob
http://www.best-microcontroller-projects.com/12F675.html
http://www.winpicprog.co.uk/pic_tutorial.htm
http://www.dontronics.com/see.html
http://www.phanderson.com/PIC/index.html
http://www.gooligum.com.au/tut_baseline.html
DubbleD
Mar 31, 2009, 06:49 PM
I've actually built the Landtastic, and it worked great, exactly as it was supposed to. But I kinda wanted to play around a bit with the idea, and wanted to use some of the outputs of the PIC for some different things. One thing I wanted to do was to have one outpin HIGH for each direction of the servo's movement, so you could hook up landing lights that would come on correctly no matter how your flap channel is set up, without having to go through the programming sequence of the Landtastic. And I wanted to have two, asyncronous strobes, one on top and one on the bottom, so I started with the servo movement code, and went from there.
I'm proud to say I just last night figured it out and I have it working superbly with one strobe LED. I can alter the variables in the code to 1.change the speed of the servo's travel, 2. change the number of strobe flashes (1-blink, double-blink, etc.), 3.change the length of time between individual blinks and between the "pairs" or sets of flashes. The real trick was in figuring out where to decrement certain timers, and then where to restore them back to the right values to make the program do what I wanted it to do and keep looping around flashing while it still looked for servo input.
I've decided to go for broke now. I could be satisfied with just the one strobe, but now that I've got a handle on how to time it all, I'm going to add the second strobe and see if I can get it to double blink during the cycles while the first one is off. I've set it up so that I have defined separate variables for the length of the LED's ON state, the length of the pause between blinks, and the length of the pause between each pair of blinks. I think I can manipulate it so that while STRB1 is in the longer OFF state between it's two blinks, the other LED, STRB2, can be doing what STRB1 just got through doing. Sounds easy enough, don't it?!??
Just last week I couldn't even spell groprammer, and now I are one!
Thanks for all the explanations, advice, and links. I'm sure I'll have more.
DD
DubbleD
Apr 01, 2009, 11:09 PM
Hey guys, I need one more piece of advice. I can't find any reference in any of the manuals I've downloaded concerning some of the commands and their syntax/parameters. I have a list of some of the commands my PIC uses (PIC12F629), but there are several I don't see any info on. My compiler seems to accept some because the color changes on the command if it's a valid entry, but I can't figure out how I'm supposed to format the code. I need to enter a line in my program that says (in BASIC anyway) IF TMR8=0 GOTO xxxx. TMR8 is a timer I have set up in the define section and have initialized to "1" with a variable T8=1. That part compiles OK. The GOTO xxxx is a reference to a place in my code I want to branch to if TMR8 has counted down to zero. I have a line that decrements it at a certain point, but I can't branch it there, I need to do it in a different place. If I could make that IF....GOTO command work, I'd be home free. I know to add the ENDIF line after it, but my compiler gives me the error message that the GOTO is an "undefined character", and I don't know how to fix it. Can anybody help me figure it out? I'm hoping it's just a matter of syntax, because I really need to be able to read the value of the TMR8 register and branch if it's = zero.
Thanks if you can help!
DD
vBulletin® Copyright ©2000-2009, Jelsoft Enterprises Ltd.