📄 smscmd.asm
字号:
;*
;* "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 + -