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

📄 smscmd.asm

📁 Tiny Planet is small device connected to a GSM cell phone. When the mobile receives a predefined SMS
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;*
;* "uart_tx_byte"
;*
;* void uart_tx_byte(unsigned char val)
;*                         DataReg
;*
;* This routine transmits the byte stored in the "UartData" register
;* the data format is 9600 8N1
;*
;* Registers used	: CounterL, DataReg, temp
;*
;***************************************************************************

uart_tx_byte:	ldi	CounterL,1+8+1	;1 start 8 data 1 stop
		com	DataReg		;Invert everything
		sec			;Start bit

utx_loop:	brcc	utx_1		;If carry set
		nop
		cbi	PORTB, TXD_PIN	;    send a '0'
		rjmp	utx_2		;else	

utx_1:		sbi	PORTB, TXD_PIN	;    send a '1'
		rjmp	utx_2

utx_2:		UART_DELAY_TX temp	;One bit delay

		lsr	DataReg		;Get next bit
		dec	CounterL	;If not all bit sent
		brne	utx_loop	;   send next
					;else
		ret			;   return




;***************************************************************************
;*
;* "uart_rx_byte"
;*
;* unsigned char uart_rx_byte(void)
;*     DataReg
;*
;* This routine receives one byte and returns it in the "DataReg" register
;* Returns Carry Set if a timeout occurs or in case of a bad start bit
;* Returns Carry Cleared and the result in DataReg if a valid byte is received
;*
;* Registers used	: DataReg, CounterL, CounterH, temp
;*
;***************************************************************************

uart_rx_byte:
		ldi	CounterL, LOW(UART_RX_TIMEOUT)
		ldi	CounterH, HIGH(UART_RX_TIMEOUT)
		wdr
urx_loop1:	subi	CounterL,1
		sbci	CounterH,0
		breq	urx_timeout
		sbis 	PINB, RXD_PIN	;Wait for start bit
		rjmp 	urx_loop1

		;wait 1/2 bit delay (for sampling point)
		mov	temp,bit_delay
		lsr	temp
urx_delay1:	dec	temp
		brne	urx_delay1

		sbis	PINB,RXD_PIN	;check for good start
		rjmp	urx_err

		wdr			;timing adjusting delay
		rjmp	PC+1		;timing adjusting delay

		ldi	DataReg,0x80	;Set msb and then we'll check
					; the carry after any rotation
					; to know when all 8 bits shifted

urx_loop2:	;1 bit delay
		mov	temp,bit_delay
urx_delay2:	dec	temp
		brne	urx_delay2
		rjmp	PC+1		;timing adjusting delay

		clc			;clear carry
		sbis 	PINB,RXD_PIN	;if RX pin high
		sec			;

		ror 	DataReg		;   shift bit into Rxbyte
		brcc	urx_loop2	;next bit

		;1/2 bit delay
		mov	temp,bit_delay
		lsr	temp
urx_delay3:	dec	temp
		brne	urx_delay3
urx_ok:
		clc
		ret
urx_timeout:
		wdr
		sec
		ret
urx_err:
		wdr
		clr	DataReg
		rjmp	urx_ok





;***************************************************************************
;*
;* "send_cmd" send a command string to the GSM. The string is stored in
;*            flash memory
;*
;* void send_cmd(unsigned char cmd_address, unsigned char index)
;*                          Arg1                     Arg2
;*
;* cmd_address: is the address of the command string to send
;* index: is the message index in ASCII. Many command refers ot a particular
;*        SMS memory, and index select the memory involved.
;*
;* Registers used : DataReg, ZL, ZH, r0
;* Calls          : uart_tx_byte()
;*
;***************************************************************************
send_cmd:
		clr	ZH
		mov	ZL, Arg1	;we use only low byte of address pointer since
					;we put command strings in the first 256 bytes
scmd_loop:	lpm
		tst	r0
		breq	scmd_ok
		mov	DataReg,r0
		rcall	uart_tx_byte
		inc	ZL
		rjmp	scmd_loop
scmd_ok:
		tst	Arg2		;test if there's a parameter
		breq	scmd_cr
		mov	DataReg, Arg2
		rcall	uart_tx_byte
scmd_cr:
		ldi	DataReg, CR	;send command terminator
		rcall	uart_tx_byte
		ldi	DataReg, LF
		rcall	uart_tx_byte

		ret


;************************************************************************
;*
;* "wait_for_ok" wait for the acknowledge string OK from the phone
;*
;* int wait_for_ok(void)
;* Carry
;*
;* Return Carry set if it doesn't receive OK string
;*
;* Registers used: Buf0, Buf1, temp, DataReg
;* Calls         : uart_rx_byte()
;*
;***************************************************************************
wait_for_ok:
		clr	Buf0
		clr	Buf1

		;Wait for reply
cok_loop1:
		rcall	uart_rx_byte
		brcs	cok_err
cok_rxok:
		mov	Buf0, Buf1
		mov	Buf1, DataReg

		ldi	temp, 'O'
		ldi	DataReg, 'K'

		sub	temp, Buf0
		sbc	DataReg, Buf1
		brne	cok_loop1

		;got it, receive extra data
cok_loop2:	rcall	uart_rx_byte
		brcc	cok_loop2

		clc
		ret
		
cok_err:	sec
		ret



;***************************************************************************
;*
;* "receive_sms" send a SMS_READ command to the phone and receives the message
;* on the serial line, and compare last bytes against the key in eeprom
;*
;* int receive_sms(unsigned char Index)
;* Carry                      Arg1
;*
;* Return Carry set if it doesn't receive OK string
;*
;* Index may have the following values:
;*
;* 0) Test the phone memory #7 for a new received message. If there's a msg
;*    compare the last bytes of the msg against the eeprom. If we find a match
;*    we execute the relative action (pulse, set output, reset output, send status)
;* 1) Read the msg in the phone memory #3 and store the last bytes in eeprom for
;*    future compare
;* 2) Read the msg in the phone memory #4 and store the last bytes in eeprom for
;*    future compare
;* 3) Read the msg in the phone memory #5 and store the last bytes in eeprom for
;*    future compare
;* 4) Read the msg in the phone memory #6 and store the last bytes in eeprom for
;*    future compare
;*
;* Registers used: ZL, ZH, temp, DataReg, EepAdr, Index, Buf0-Buf7,
;*                 CounterL, Arg1, Arg2
;* Calls         : send_cmd(), wait_for_ok(), uart_rx_byte()
;*
;***************************************************************************

receive_sms:
		;Test the Index values and load Arg2 with the memory location
		; to read
		mov	Index, Arg1
		ldi	Arg2, '7'		;#7
		tst	Index
		breq	rcs_1
		ldi	Arg2, '2'
		add	Arg2, Index		;#3 - #6
rcs_1:
		SMS_READ

		;Read all the messages and leave the last N bytes in buf0-buf7
		clr	Buf0
		clr	Buf1
		clr	Buf2
		clr	Buf3
		clr	Buf4
		clr	Buf5
		clr	Buf6
		clr	Buf7

		;Read first byte, in case of no answer from the phone (rx timeout)
		; exit
		rcall	uart_rx_byte
		brcc	rcs_loop1
		rjmp	rcs_end
rcs_loop1:
		cpi	DataReg, '0'	;Skip ASCII below '0' (non digit values, i.e. CR and LF)
		brcs	rcs_2

		mov	Buf0, Buf1
		mov	Buf1, Buf2
		mov	Buf2, Buf3
		mov	Buf3, Buf4
		mov	Buf4, Buf5
		mov	Buf5, Buf6
		mov	Buf6, Buf7
		mov	Buf7, DataReg
rcs_2:		rcall	uart_rx_byte
		brcc	rcs_loop1

		;Check for the OK string in the tail of the uart Rx buffer
		ldi	temp, 'O'
		ldi	DataReg, 'K'
		sub	temp, Buf6
		sbc	DataReg, Buf7
		breq	rcs_2_2
		rjmp	rcs_err
rcs_2_2:		
		;;Test index to know if we have to store message keys in eeprom (config) or
		;;   check for a new message in #7
		tst	Index
		breq	rcs_1key


rcs_3:		;;If (index != 0) we read every message and store the message keys in eeprom
		dec	Index
		breq	rcs_3_2			;skip mul if operand is 0
		ldi	CounterL, EEP_KEYSIZE
		MUL8	Index, CounterL, temp	;Index = Index * EEP_KEYSIZE
rcs_3_2:
		ldi	EepAdr, first_key
		add	EepAdr, Index
		clr	ZH
		ldi	ZL, 1		;Address of r1 (Buf0)
		ldi	CounterL, EEP_KEYSIZE
rcs_loop2:
		ld	DataReg, Z
		EEPROM_WRITE EepAdr, DataReg
		inc	EepAdr
		inc	ZL
		dec	CounterL
		brne	rcs_loop2

		rjmp	rcs_end


rcs_1key:	;;If (index == 0) we compare the new message with every message keys in eeprom
		;;Test against First KEY
		ldi	EepAdr, first_key
		clr	ZH
		ldi	ZL, 1		;Address of r1

rcs_loop01:	EEPROM_READ DataReg, EepAdr
		ld	temp, Z
		cp	DataReg, temp
		brne	rcs_2key
		inc	ZL
		inc	EepAdr
		cpi	EepAdr, second_key
		brne	rcs_loop01

		;Found first key: send the input status SMS
		SMS_SEND

		;the Send SMS command may take some time, so
		;  call wait_for_ok() several times for a
		;  long timeout
		ldi	ZH, 10
rcs_loop01_b:	rcall	wait_for_ok
		brcc	rcs_4
		dec	ZH
		brne	rcs_loop01_b
rcs_4:
		rjmp	rcs_5


rcs_2key:	;;Test against Second KEY
		ldi	EepAdr, second_key
		clr	ZH
		ldi	ZL, 1		;Address of r1

rcs_loop02:	EEPROM_READ DataReg, EepAdr
		ld	temp, Z
		cp	DataReg, temp
		brne	rcs_3key
		inc	ZL
		inc	EepAdr
		cpi	EepAdr, third_key
		brne	rcs_loop02

		;Found second key: Send Pulse to OUTPUT
		wdr
		cbr	output_copy, (1 << OUTPUT1)
		sbi	PORTB, OUTPUT1
		rjmp	rcs_5


rcs_3key:	;;Test against Third KEY
		ldi	EepAdr, third_key
		clr	ZH
		ldi	ZL, 1		;Address of r1

rcs_loop03:	EEPROM_READ DataReg, EepAdr
		ld	temp, Z
		cp	DataReg, temp
		brne	rcs_4key
		inc	ZL
		inc	EepAdr
		cpi	EepAdr, fourth_key
		brne	rcs_loop03
		
		;Found third key: Reset OUTPUT
		cbr	output_copy, (1 << OUTPUT1)
		out	PORTB, output_copy
		rjmp	rcs_5


rcs_4key:	;;Test against Fourth KEY
		ldi	EepAdr, fourth_key
		clr	ZH
		ldi	ZL, 1		;Address of r1

rcs_loop04:	EEPROM_READ DataReg, EepAdr
		ld	temp, Z
		cp	DataReg, temp
		brne	rcs_5
		inc	ZL
		inc	EepAdr
		cpi	EepAdr, end_key
		brne	rcs_loop04
		
		;Found fourth key: Set OUTPUT
		sbr	output_copy, (1 << OUTPUT1)
		out	PORTB, output_copy
rcs_5:
rcs_end:
		clc
		ret
rcs_err:
		sec
		ret


;***************************************************************************
;*
;* "auto_baud" calibrate the bit delay since the oscillator frequency change
;*             with the battery voltage
;*
;* int auto_baut(void)
;* Carry
;*
;* Return Carry set if it doesn't find the correct value (GSM off or disconnected?)
;*
;* Registers used: old_delay, bit_delay, temp, EepAdr, Arg1, Arg2
;* Calls         : wait_for_ok(), send_cmd()
;*
;***************************************************************************
auto_baud:
		mov	old_delay, bit_delay	;save current bit delay

		ldi	temp, BDELAY_MIN*2-1
		mov	bit_delay, temp

		;Start the loop: send AT, wait for an answer, in case of no
		; answer from the phone increment the bit_delay and try again
aub_loop1:
		inc	bit_delay
		ldi	temp, BDELAY_MAX*2
		cp	bit_delay, temp
		brcc	aub_err

		SEND_AT
		rcall	wait_for_ok
		brcc	aub_ok

		SEND_AT
		rcall	wait_for_ok
		brcc	aub_ok

		rjmp	aub_loop1
aub_ok:
		;;Correct Baudrate found: save to eeprom and returns
		ldi	EepAdr, bdelay_adr
		EEPROM_WRITE EepAdr, bit_delay

		clc
		ret
aub_err:
		mov	bit_delay, old_delay	;restore bit_delay
		sec
		ret

⌨️ 快捷键说明

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