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

📄 serial.asm

📁 uart-I2C, working on PIC18F2420
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;==============================================================
;       Knoll Uart to I2C converter
;       Original Version: 1.0
;       Original Release Date: 
;==============================================================
;       Version Description:
; Version 1.01P - TDA's are working, Channels 1-3 and Inputs 1-3 can be selected
; Version 1.02P - Added 6K7 support, tested channels 1-7 out of amps 1-6
; Version 1.03P - Changed command structure to (xxx!nnn)
; Version 1.04P - Vol and Input Sel Functional
; Veriosn 1.05P - First debugged version sent to Knoll, all zones tested.
; Version 1.06P - Chnaged to 18F2420, fixed bugs in A/D POR
; Version 1.07P - added Bass and Treble commands
; Version 1.08P - added read volume command
; Version 1.09P = fixed bug in "all" commands by resetting all TDA's before any
;				  command is sent to them.
;Version 1.10P = Added basic keypad responses and ack
;Version 1.11P = Added full command set from keypads.

;Version 1.00 - first production version with all debugging. 
;Version 1.01 - fixed bug in bass/treble translate from keypad
;Version 1.02 - more fixes
;Version 1.03 - amp now saves bass/treble settings, can auto-calibrate with keypad
;Version 1.04 - implemented talk routine, fixed all up/down volumes
;Version 2.00 - changed timing, removed ack
;Version 2.01 - added "all off" (aof) command through serial
;Version 2.02 - 5/2/7 buglist
;				started reflecting UART commands out through com wire. Volume does not!
;				changed trigger output - any channel on,  port B7 goes high.
;				removed external osc.
;				RESET TDA on ACK ERROR! Allows transparent recovert from keypress....

;				Other changes in keypad firmware
;Version 2.03 - Changed send2TDA timing, added wait states
;Version 2.04 - Fixed bug in "all" from keypad, reset of TDA's new implemented.
;Version 2.05 - Fixed bug in resetting TDA's - was sending wrong volume and not 
;				clearing "b_tdaonly" when completed.
;Version 3.00 - Added Balance feature, clean up "nops" for crossing PCH alignment
;Version 3.01 - Fixed bug from balance feature in "all" function
;Version 3.02 - Working at Leviton Labs, implemented party mode, all v jump to speed volume
;Version 3.04 - Changed for version control
;Version 3.05 - fixed minor bugs, all vol down ch 4, p mode ch 5, added comma between commands
;	


;==============================================================

;Used for developing the Sensor Controller Serial Routines
;for I2C router

;==============================================================
;	File INCLUDES
;	Include the Standard Microchip Include Files 
;	by Processor Type
;==============================================================	

;Set the processor variables
	list p=18F2420
	include	"p18F2420.inc"
	include "myconfig.inc"		;adapted for config bits
	include	"system_var.inc"
	include	"RAM.inc"

;Program Configuration Register 1H
;		__CONFIG    _CONFIG1H, _XT_OSC_1H
;		__CONFIG    _CONFIG2L, _BOR_ON_2L & _BORV_42_2L & _PWRT_ON_2L
;		__CONFIG    _CONFIG2H, _WDT_OFF_2H

;==============================================================
;This is the start of the actual running code ....
;==============================================================

	ORG	0			;Power on reset address

	nop				;nop for ICD
	bra		START	;jump to program start

;==============================================================
;Here is the interrupt vector
;==============================================================
	ORG	0x008		;Interrupt service routines (no priority)

INT?1	
	btfss	PIR1,RCIF			;check for an interrupt flag from the UART
	goto	INT?2				;skip if none
	movf	RCREG,W				;pull into W, auto clears flag
	movwf	RECBUFF				;Save copy in RECBUFF
	bsf		FLAG1,b_IPENDING	;set service request flag
	goto	INTDONE

INT?2		

INTDONE
	retfie	FAST				;Return from interrupt(s)

;===========================================================
;Start of Program
;===========================================================

START
	call	BOOT

;******************************************************************
;Main code loop. Check for serial commands, execute, and loop back
;wait.
;******************************************************************

MAIN
	btfsc	FLAG1,b_IPENDING	;check for a serial command interrupt
	goto	GETCHAR
	btfsc	FLAG1,b_pending		;state machine
	call	states

;test loop for I2C to keypads
;	bcf		TRISA,2
;	bcf		TRISA,3
;testloop
;	btg		SDA1	;PORTA,3 - RC7 on keypad
;	movlw	0x0f
;	call	LONG_DELAY
;	btg		SCK1	;PORTA,2 - RB1/INT1 on keypad
;	movlw	0x0f
;	call	LONG_DELAY
;	bra		testloop	



	btfss	SDA1		;look for SDA to drop
	call	I2C_get

;look for paging input....
	btfss	PAGE_IN
	call	paged
;look for trigger.....
	movf	CHANNELS,f
	bz		MAIN_1
	bsf		PORTB,7
	bra		MAIN
MAIN_1
	bcf		PORTB,7	
	bra		MAIN

;*********************************************************
;*********************************************************
;STATE MACHINE
;*********************************************************
;*********************************************************

states

	movf	PCL,w					;false read to update PCU,PCH
	movf	current_state,w
	addwf	PCL,F					;jump to next state!

	bra		state0					;current_state = "0", first char decode
	bra		state1					;current_state = "2", ACK test to keypads
	bra		statev					;current_state = "4", char is a v
	bra		statevr					;currnet_state = "6", char is vr - version)
	bra		statevr?				;current_state = "8", char is vr? - send version after ")"
	bra		statevl					;current_state = "10", char is vl (volume)
	bra		statevlx				;12
	bra		a_statevlxx				;14
	bra		a_statevlxx_end			;16
	bra		a_state3					;current_state = "18", system reset
	bra		a_staterx_end				;current_state = "20", look for ) on reset
;	bra		state4					;current_state = "8", set keypad zone
;	bra		state5					;current_state = "10",internal TDA ack test
	bra		a_state6				;current_state = "22",turn on individual amps
	bra		a_state_on				;24 - turn on a,ps
	bra		a_state_off				;26	- turn off amps
	bra		a_statem					;28 - look for mute
	bra		a_statem_end				;30
	bra		a_stateu					;32
	bra		a_stateu_end				;34
	bra		a_state8					;36 current_state = "36", send command to TDA's
									;Do NOT USE STATE 8 for INPUT SELECT! for 6K7!!!!!!!

	bra		a_state9					;38 - setup looking for "l" after s (sl)
	bra		a_state_sl				;40
	bra		a_state_slx				;42
	bra		a_state_sl_end			;44 input has been decoded and sent to the 16F627A,

									;you MUST still use STATE 8
	
	bra		statebx					;46 - bass value
	bra		statebx_end				;48 - end bass
	bra		statetx					;50	- treble value
	bra		statetx_end				;52 - treble end
	bra		a_statevl?_end			;54 - request volume

	bra		stateax					;56
	bra		state_am				;58
	bra		state_au				;60
	bra		state_av				;62
	bra		state_as				;64
	bra		state_amu				;66
	bra		state_aum				;68
	bra		state_avlx				;70
	bra		state_aslx				;72
	bra		state_avlxx				;74
	bra		state_avlxx_end			;76
	bra		state_asl_end			;78
	bra		state_ao				;80	- all off
	bra		state_aof				;82	- all off

;have to extend addressing...........
a_statevl?_end
	goto	statevl?_end
a_state_slx
	goto	state_slx
a_state_sl_end
	goto	state_sl_end
a_state6
	goto	state6
a_state_on
	goto	state_on
a_state_off
	goto	state_off
a_statem
	goto	statem
a_statem_end
	goto	statem_end
a_stateu
	goto	stateu
a_stateu_end	
	goto	stateu_end
a_state8
	goto	state8
a_state9
	goto	state9
a_state_sl
	goto	state_sl
a_staterx_end
	goto	staterx_end
a_state3
	goto	state3
a_statevlxx
	goto	statevlxx
a_statevlxx_end
	goto	statevlxx_end




;*********************************************************
; STATE0, main entry point
;*********************************************************

;state 0 will decode command character, and also inital decimal (amp select).
;Following states can just look in var current_channel to view amp.
;entry command char ( is decoded by get_char, but ending ) must be manually 
;decoded and b_tilda cleared at end of states.


state0
	bcf		FLAG1,b_pending
	movlw	"k"
	cpfseq	RECBUFF
	bra		s0_1
	goto	state1		;I2C ACK test - SINGLE KEYPAD ON ANY ZONE (0-16) ONLY!
s0_1
	movlw	"v"
	cpfseq	RECBUFF
	bra		s0_2
	goto	statev		;Char is v, could be version or volume
s0_2
	movlw	"r"
	cpfseq	RECBUFF
	bra		s0_3
	goto	state3		;System Reset
s0_3
	movlw	"c"			;dummy placement - there is no "c"
	cpfseq	RECBUFF
	bra		s0_4
	goto	state4		;set zone - SINGLE KEYPAD ONLY!
s0_4
	movlw	"i"	
	cpfseq	RECBUFF
	bra		s0_5
	goto	state5		;internal ack test - look for TDA's
s0_5
	movlw	"o"			
	cpfseq	RECBUFF
	bra		s0_6
	goto	state6		;on or off, need to further decode
s0_6
	movlw	"e"
	cpfseq	RECBUFF
	bra		s0_7
;	goto	state7		;disabled
s0_7
	movlw	"1"
	cpfseq	RECBUFF
	bra		s0_8
	movlw	0x01
	movwf	current_channel
	return
s0_8
	movlw	"2"
	cpfseq	RECBUFF
	bra		s0_9
	movlw	0x02
	movwf	current_channel
	return
s0_9
	movlw	"3"
	cpfseq	RECBUFF
	bra		s0_10
	movlw	0x03
	movwf	current_channel
	return
s0_10
	movlw	"4"
	cpfseq	RECBUFF
	bra		s0_11
	movlw	0x4
	movwf	current_channel
	return
s0_11
	movlw	"5"
	cpfseq	RECBUFF
	bra		s0_12
	movlw	0x05
	movwf	current_channel
	return
s0_12
	movlw	"6"
	cpfseq	RECBUFF
	bra		s0_13
	movlw	0x06
	movwf	current_channel
	return
s0_13
	movlw	"s"
	cpfseq	RECBUFF
	bra		s0_14
	goto	state9
s0_14
	movlw	"m"
	cpfseq	RECBUFF
	bra		s0_15
	goto	statem		;mute
s0_15
	movlw	"u"
	cpfseq	RECBUFF
	bra		s0_16
	goto	stateu		;unmute
s0_16
	movlw	"b"
	cpfseq	RECBUFF
	bra		s0_17
	goto	stateb		;bass or balance....
s0_17
	movlw	"t"
	cpfseq	RECBUFF
	bra		s0_18
	goto	statet		;treble
s0_18
	movlw	"a"
	cpfseq	RECBUFF
	bra		s0_19
	goto	statea
s0_19


command_error
	call	String_ERROR2	;unrecognized command
	bcf		FLAG3,b_TILDA	;get ready for next command
	bcf		FLAG1,b_pending
	clrf	current_state
	return

state1
	clrf	zones				;clear zones register
	bcf		FLAG3,b_ACKERROR	;start with ack error clear

	movlw	zone1_add			;load address of zone1
	call	checkzone			;check for keypad
	btfsc	FLAG3,b_ACKERROR	;check for ack error
	bra		s1_0				;if ack error, skip response
	call	String_ZONE1		;if no error, send zone
	bsf		zones,zone1			;set bit for zone1 here
s1_0	
	bcf		FLAG3,b_ACKERROR	;do same for zones 2,3,4
	movlw	zone2_add
	call	checkzone
	btfsc	FLAG3,b_ACKERROR
	bra		s1_1
	call	String_ZONE2
	bsf		zones,zone2
s1_1
	bcf		FLAG3,b_ACKERROR
	movlw	zone3_add
	call	checkzone
	btfsc	FLAG3,b_ACKERROR
	bra		s1_2
	call	String_ZONE3
	bsf		zones,zone3
s1_2
	bcf		FLAG3,b_ACKERROR
	movlw	zone4_add
	call	checkzone
	btfsc	FLAG3,b_ACKERROR
	bra		s1_3
	call	String_ZONE4
	bsf		zones,zone4
s1_3
	movf	zones,w
	bz		S1_4
	return
S1_4
	call	String_ERROR3		;if no zones ack'd, then error code
	return


checkzone
	
	movwf	I2CBUF				;start with address 0 in I2C buff

	bcf		SDA1				;drop SDA, (send START) condition
	call	WAIT_STATE			;give slaves time to respond
	bcf		SCK1				;drop SCK so we can change SDA
								;without getting a stop condition
	call	SEND_I2C			;call send I2C routine
	bcf		SDA1				;make sure SDA is low (send STOP)
	call	WAIT_STATE
	bsf		SCK1				;raise SCK
	call	WAIT_STATE
	bsf		SDA1				;raise SDA
	btfss	FLAG3,b_ACKERROR	;if no error, skip jmp
	bsf		zones,zone1		

	return


	call	String_ERROR3	;no keypad detected
	bcf		FLAG2,b_TILDA
	return

;--------------------------------------------------------------------------------------------------------------
statea
;--------------------------------------------------------------------------------------------------------------
;we have a a, so is all command. We have no zone number!
;now decipher command!
	bcf		FLAG1,b_pending
	movlw	d'56'	
	movwf	current_state
	return

;-----------
; ax - what is x?
stateax
	bcf		FLAG1,b_pending
	movlw	"m"
	cpfseq	RECBUFF
	bra		ax_0
	bra		am
ax_0
	movlw	"u"
	cpfseq	RECBUFF
	bra		ax_1
	bra		au
ax_1
	movlw	"v"
	cpfseq	RECBUFF
	bra		ax_2
	bra		av
ax_2
	movlw	"s"
	cpfseq	RECBUFF
	bra		ax_3
	bra		as
ax_3
	movlw	"o"
	cpfseq	RECBUFF
	bra		ax_4
	bra		ao
ax_4
	goto	command_error


as
	movlw	d'64'
	movwf	current_state
	return
am
	movlw	d'58'
	movwf	current_state
	return
au
	movlw	d'60'
	movwf	current_state
	return
av
	movlw	d'62'
	movwf	current_state
	return

ao	movlw	d'80'
	movwf	current_state
	return


;-----------------------
state_am
	bcf	FLAG1,b_pending
	movlw	"u"
	cpfseq	RECBUFF
	goto	command_error
	movlw	d'66'
	movwf	current_state
	return
state_au
	bcf	FLAG1,b_pending
	movlw	"m"
	cpfseq	RECBUFF
	goto	command_error
	movlw	d'68'
	movwf	current_state
	return
state_av
	bcf	FLAG1,b_pending
	movlw	"l"
	cpfseq	RECBUFF
	goto	command_error
	movlw	d'70'
	movwf	current_state
	return
state_as
	bcf	FLAG1,b_pending
	movlw	"l"
	cpfseq	RECBUFF
	goto	command_error
	movlw	d'72'
	movwf	current_state
	return
state_ao
	bcf		FLAG1,b_pending
	movlw	"f"
	cpfseq	RECBUFF
	goto	command_error
	movlw	d'82'
	movwf	current_state
	return

;--------------------------
state_amu
	bcf		FLAG1,b_pending
	movlw	")"
	cpfseq	RECBUFF
	goto	command_error
;now send mute on
	bsf		FLAG2,b_tdaonly
	movlw	0x06
	movwf	current_subadd
	movlw	0x00
	movwf	current_data
	movlw	1
	movwf	current_channel
	call	send2TDA			;ch 1
	incf	current_channel,f
	call	wait_4
	call	send2TDA			;ch 2
	incf	current_channel,f
	call	wait_4
	call	send2TDA			;ch 3
	incf	current_channel,f
	call	wait_4
	call	send2TDA			;ch 4
	incf	current_channel,f
	call	wait_4
	call	send2TDA			;ch 5
	incf	current_channel,f
	call	wait_4
	call	send2TDA			;ch 6
;don't forget to clear the state....
	bcf		FLAG2,b_tdaonly
	clrf	current_state
	bcf		FLAG3,b_TILDA

⌨️ 快捷键说明

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