; a bus circuit. push a button on one end and the light turns on on the other end. identical code for both ends. check interrupt flag pin, data in pin, data out pin, clock pin, cs pin on both pics, also loan bus oscilator. LIST P=16F84 errorlevel 0,-305 INCLUDE "P16F84.inc" __CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON ;---------------------------------------------------------------------------------------------- poser equ 0c ; toggle bit for what the button state was the last time i checked lit equ 0d ; toggle bit for what the light was the last time i checked addressbyte equ 3b ; var for passing addy byte to wribyte databyte equ 3c ; var for passing data byte to wribyte IDlow equ H'00' ; low byte of this node's standard CAN ID IDhigh equ H'00' ; high byte of this node's standard CAN ID ; NB above also sets standard mode only handler equ 3d ; serial shift register value cbit equ 3e ; for the eight cycle to send an entire byte swalo equ 3f ; delay for the clock ;---------------------------------------------------------------------------------------------- setup org 0 clrf portb ; clears all the bits in portb clrf porta ; clears all the bits in porta clrf status ; clears all the bits in status bsf status, rp0 ; switches to the right hand collum movlw 0 ; --> movwf trisb ; sets portb as output movlw H'ff' ; --> movwf trisa ; sets porta as input bcf status, rp0 ; switches back to left hand collum bsf portb, 5 ; taking cs high so bus controller doesn't listen movlw H'0f' ; --> movwf databyte ; --> movlw H'0c' ; --> movwf addressbyte ; --> call wribyte ; putting bus into pin interrupt mode movlw H'f0' ; --> movwf databyte ; --> movlw H'60' ; --> movwf addressbyte ; --> call wribyte ; setting bus filters such that all bus messages show up in buffer 0 movlw H'ff' ; --> movwf databyte ; --> movlw H'2a' ; --> movwf addressbyte ; --> call wribyte ; make it the slowest bit rate on the bus ;....new movlw H'ff' ; --> movwf databyte ; --> movlw H'29' ; --> movwf addressbyte ; --> call wribyte ; make it the slowest bit rate on the bus movlw H'07' ; --> movwf databyte ; --> movlw H'28' ; --> movwf addressbyte ; --> call wribyte ; make it the slowest bit rate on the bus ;.....t here movlw H'04' ; --> movwf databyte ; --> movlw H'0f' ; --> movwf addressbyte ; --> call wribyte ; set it into normal mode ;---------------------------------------------------------------------------------------------- init movlw 01 ; --> movwf poser ; starts knowing that the button is up. note: when the button is up i'm gettin a 1 movwf H'40' ; starts knowing that the datalength it is going to send will ALLWAYS be 1 movwf H'41' ; starts knowing that the data it is going to send will ALLWAYS be 1 movlw 00 ; --> movwf lit ; starts knowing that the light is off loop btfsc porta, 0 ; --> goto up ; --> goto down ; see if the button is up or down up btfss poser, 0 ; --> goto tellu ; see if this qualifies as a change of state goto noth ; ie: now that i am recieving a 0, was i recieving a 1 before down btfsc poser, 0 ; --> goto telld ; see if this qualifies as a change of state goto noth ; ie: now that i am recieving a 1, was i recieving a 0 before tellu movlw 01 ; note: when it is up, pin recieves a 1 movwf poser ; record that the state has chaged from down to up call sendmsg ; goes to subroutine at bottom of document goto noth telld movlw 00 ; note: when it is down, pin recievs a 0 movwf poser ; record that the state has chaged from up to down call sendmsg ; goes to subroutine at bottom of document noth btfsc porta, 1 ; check if there is an interrupt on the bus goto deth ; there is no message so go to the bottom call getmsg ; --> btfss H'33', 0 ; evaluate the message goto deth ; if the message does not have a 1 in the zeroth bit then ignore it btfss lit, 0 ; check the current state of the led goto ton ; if it was off, turn it on toff movlw 00 ; --> movwf lit ; record that we turned it off bcf portb, 3 ; turn it off goto deth ; done everyting, go to end of program ton movlw 01 ; --> movwf lit ; record that we turned it on bsf portb, 3 ; turn it on deth goto loop ; back to begining ;----------------------------------------------------------------------------------------------- ;-----------------{sendmsg subroutine } sendmsg movlw H'30' ; address of first byte in CAN transmit buffer movwf addressbyte ; pass to addressbyte param of wribyte movlw 0 ; write a 0 data to this (priority 0, don't send yet) movwf databyte ; pass to databyte param of wribyte call wribyte ; write 0 to 30h in CAN controller movlw H'31' ; standard ID high byte register address movwf addressbyte ; send addy movlw IDhigh ; standard ID CAN high node address (be very sure to ; declare these differently for each node movwf databyte ; send the CAN node byte call wribyte ; SID low byte reg address incf addressbyte ; movlw IDlow ; movwf databyte ; call wribyte ; skip regs 32-33h (extended ID bytes) ;----------------------- ; next we have to get our data length value from ; 40h (passed into sendmsg there) and put it into ; the DLC register in the transmit buffer. ; then we have to read that number of data bytes ; from the param array (41-48h) and save them to ; the buffer (36-3dh) movlw H'35' ; addy of DLC register movwf addressbyte ; movf 40,w ; get data length movwf databyte ; call wribyte ; store it incf addressbyte ; movf 41,w ; movwf databyte ; call wribyte ; store data byte 1 incf addressbyte ; movf 42,w ; movwf databyte ; call wribyte ; store data byte 2 incf addressbyte ; movf H'43',w ; movwf databyte ; call wribyte ; store data byte 3 incf addressbyte ; movf H'44',w ; movwf databyte ; call wribyte ; store data byte 4 incf addressbyte ; movf H'45',w ; movwf databyte ; call wribyte ; store data byte 5 incf addressbyte ; movf H'46',w ; movwf databyte ; call wribyte ; store data byte 6 incf addressbyte ; movf H'47',w ; movwf databyte ; call wribyte ; store data byte 7 incf addressbyte ; movf H'48',w ; movwf databyte ; call wribyte ; store data byte 8 ; now set transmit flag high movlw H'30' ; address of buffer byte 1 movwf addressbyte ; movlw H'08' ; turn bit 4 high to transmit movwf databyte ; call wribyte ; transmit entire packet. movlw H'81' movwf handler call outbyte return ; -- ;----------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------- ;----{"wribyte" subroutine manages the delivery of three bytes to the bus, one of which is data} ;--!!{"addressbyte" holds the address to which you write ... "databyte" holds the data you send} ;---------------------------{portb, 5 is /cs ... portb, 6 is clock pin ... portb, 7 is data pin} wribyte bcf portb, 5 ; taking cs low so bus controller listens movlw H'02' ; --> movwf handler call outbyte ; sends a byte that tells the bus we want to WRITE movf addressbyte, w ; !!you must name a register "addressbyte" and have it holding the address you are writing to movwf handler call outbyte ; sends byte determining the register we are writing to on the bus movf databyte, w ; !!you must name a register "databyte" and have it holding the data you wish to send movwf handler call outbyte ; sends our data byte bsf portb, 5 ; taking cs high so bus controller stops listening return ; -- ;----------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------- ;---------------{"outbyte" subroutine sends to the bus the byte that is in the handler} ;---------------------------{portb, 5 is /cs ... portb, 6 is clock pin ... portb, 7 is data pin} outbyte movlw H'08' ; --> movwf cbit ; set up the eight cycle for sending 8 bits bloop btfsc handler, 7 ; check the seventh bit of w bsf portb, 7 ; if it is 1 put a one on the pin btfss handler, 7 ; if it was 1, it needs to skip the command for if it was zero bcf portb, 7 ; if it is 0 put a zero on the pin bsf portb, 6 ; clock goes up bcf portb, 6 ; clock goes down and the bus has taken the bit rlf handler,1 ; line up the next bit decfsz cbit, f ; -- goto bloop ; -- return ; -- ;----------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------- ;-----------------{getmsg subroutine } getmsg movlw H'65' ; address of first byte in CAN transmit buffer movwf addressbyte ; pass to addressbyte param of wribyte call reabyte ; write 0 to 30h in CAN controller movf databyte, w andlw H'0f' movwf H'32' incf addressbyte call reabyte movf databyte, w movwf H'33' incf addressbyte call reabyte movf databyte, w movwf H'34' incf addressbyte call reabyte movf databyte, w movwf H'35' incf addressbyte call reabyte movf databyte, w movwf H'36' incf addressbyte call reabyte movf databyte, w movwf H'37' incf addressbyte call reabyte movf databyte, w movwf H'38' incf addressbyte call reabyte movf databyte, w movwf H'39' incf addressbyte call reabyte movf databyte, w movwf H'3A' movlw H'2c' ; --> movwf addressbyte ; --> movlw H'00' ; --> movwf databyte ; --> call wribyte ; put the interrupt pin back return ; -- ;----------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------- ;--{"reabyte" subroutine manages the sending two bytes to the bus and retreval of one data byte} ;-!!{"addressbyte" holds the address from which you read ... "databyte" holds the data you read} ;---------------------------{portb, 5 is /cs ... portb, 6 is clock pin ... porta, 3 is data pin} reabyte bcf portb, 5 ; taking cs low so bus controller listens movlw H'03' ; --> movwf handler ; --> call outbyte ; sends a byte that tells the bus we want to READ movf addressbyte, 0 ; !!you must name a register "addressbyte" and have it holding the address you are reading from movwf handler call outbyte ; sends byte determining the register we are reading from on the bus call inbyte ; gets our data byte bsf portb, 5 ; taking cs high so bus controller stops listening return ; -- ;----------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------- ;---------------{"inbyte" subroutine gets a byte from the bus} ;---------------------------{portb, 5 is /cs ... portb, 6 is clock pin ... porta, 3 is data pin} inbyte movlw H'08' ; --> movwf cbit ; set up the eight cycle for sending 8 bits cloop bsf portb, 6 ; clock goes up btfss porta, 3 ; check data bcf databyte,0 ; if data was a 0 record a 0 btfsc porta, 3 ; if data was a 0 don't do command for if data was a 1 bsf databyte,0 ; if data was a 1 record a 1 bcf portb, 6 ; clock goes down and we have taken the bit rlf databyte,1 ; line up the next bit decfsz cbit, f ; -- goto cloop ; -- rrf databyte,1 ; line up the next bit return ; -- ;----------------------------------------------------------------------------------------------- end ; --