📄 atmega32_project.asm
字号:
;---------------------------------------------------------
; HOME AUTOMATION THROUGH SMS (HARDWARE CODE)
; WRITTEN BY YASIR KARIM QURESHI AND GROUP
;
; CHIP TYPE: ATMEL AVR ATMEGA32
; 1KB OF EEPROM
; 2KB OF SRAM
; 32KB OF FLASH MEM
; WRITTEN IN: AVR STUDIO 2005
; PURPOSE: FINAL YEAR THESIS PROJECT 05CS MUET
;---------------------------------------------------------
;INCLUDE BIT DEFINITION FILE WITH INCLUDE DIRECTIVE
.NOLIST
.INCLUDE "m32def.inc"
.LIST
;---------------------------------------------------------
; DATA INITIALIZATION GO HERE
;---------------------------------------------------------
.DEF TEMP = R16 ; DEFINE R16 AS TEMPORARY REGISTER
.DEF LCD_CHAR = R17
.DEF EEPROM_DATA = R18
.DEF EADD_LOW = R19
.DEF EADD_HIGH = R20
.DEF USART_DATA = R21
.DEF COUNT_IT = R22 ; TEMPORARY REGISTER FOR COUNTING ETC
.DEF BUZZER_STATUS = R23
.EQU USER_STATUS_BYTE = 1
.EQU USER_DEVICE_BYTE = 2
.EQU USER_DEVICE_LOCK_BYTE = 3
.EQU USER_BUZZER_BYTE = 4
.EQU USER_PASSWORD_AREA = 10
.EQU USER_NAME_AREA1 = 21
.EQU USER_CONTACT_AREA1 = 45
.EQU USER_NAME_AREA2 = 61
.EQU USER_CONTACT_AREA2 = 85
.EQU USER_NAME_AREA3 = 101
.EQU USER_CONTACT_AREA3 = 125
.EQU USER_DEVICE_STATUS_BYTES = 150
.EQU SMS_TIME_STAMP = 200
.EQU RAM_AREA_FOR_SMS = 101
.EQU SMS_SENDER_DETAILS_START = 124
.EQU SMS_SENDER_DETAILS_END = 136
.EQU SMS_MESSAGE_START = 166
.EQU SMS_MESSAGE_END = 172
.EQU EN = PD4
.EQU RS = PD2
.EQU WR = PD3
.SET LCD_PORT = PORTC
.MACRO WAIT
NOP
NOP
NOP
NOP
.ENDM
.CSEG
.ORG $0000 ; STARTING POSITION AFTER RESET
RJMP START ; JUMP TO START POSITION
.ORG URXCaddr
RJMP USART_RX_INT
;---------------------------------------------------------
; USART INTERRUPTS AND DATA TRANSMIT GO HERE
;---------------------------------------------------------
USART_RX_INT:
IN USART_DATA, UDR ; COPY RECIEVED BYTE IN USART_DATA(R21)
CPI USART_DATA, '+'
BREQ REC_DATA
CPI USART_DATA, '!'
BREQ HANDLE_IT
RJMP QUIT_RX_INT
REC_DATA:
CBI UCSRB, RXEN
RCALL BUZZER
RCALL SET_SMS_READ
RJMP QUIT_RX_INT
HANDLE_IT:
CPI R24, '#'
BREQ ALLREADY_CONN
RCALL PC_RESPONSE
RJMP QUIT_RX_INT
ALLREADY_CONN:
MOV TEMP, R4
RCALL TRANSMIT
QUIT_RX_INT:
RETI
INITIALIZE_USART:
OUT UBRRL, TEMP ; INIT BAUD RATE
LDI TEMP, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE) ; ENABLE RECIEVER, TRANSMITTER AND RXCint
OUT UCSRB, TEMP ; INIT USART CONTROL REGISTER
SEI ; GLOBAL INTERRUPT ENABLE
RET ; RETURN BACK
TRANSMIT:
SBIS UCSRA, UDRE ; READY TO SEND?
RJMP TRANSMIT ; NO? JUMP TO TRANSMIT
OUT UDR, TEMP ; YES? COPY BYTE IN USART DATA REGISTER
ADIW Y, 1
RET
;---------------------------------------------------------
; TRANSMIT AT COMMANDS AND BYTES IN LOOP TILL 0X00
TRANSMIT_LOOP:
LPM TEMP, Z+
CPI TEMP, 0X00
BREQ QUIT_TRANSMIT_LOOP
RCALL TRANSMIT
RJMP TRANSMIT_LOOP
RJMP QUIT_TRANSMIT_LOOP
TRANSMIT_LOOP_CLEAR:
LDI TEMP, 0X08
MOVW X, Y
CLEAR_LOOP:
RCALL TRANSMIT
SBIW X, 1
BRNE CLEAR_LOOP
QUIT_TRANSMIT_LOOP:
RET
;---------------------------------------------------------
; LCD INITIALIZATION AND DATA TRANSMIT GO HERE
;---------------------------------------------------------
INIT_LCD: ; LCD INITIALIZATION SUBROUTINE
RCALL DELAY_LCD
CLR TEMP
LDI TEMP, 0XFF ; LOAD VALUE FOR DATA DIRECTION OF PORTC
OUT DDRC, TEMP ; SET PORTC DATA DIRECTION REGISTER
SBI DDRD, PD2
SBI DDRD, PD3
SBI DDRD, PD4
LDI LCD_CHAR, 0X38 ; LOAD VALUE FOR 2 LINE, 5X7 SETTINGS
RCALL LCD_CTRL ; TRANSMIT CONTROL BYTE
LDI LCD_CHAR, 0X0C ; LOAD VALUE FOR LCD 'ON' AND CURSOR 'OFF'
RCALL LCD_CTRL ; TRANSMIT CONTROL BYTE
RCALL LCD_CLEAR ; CLEAR LCD FOR FURTHER USE
RCALL LCD_LINE1 ; FORCE CURSOR TO BE AT LINE 1
RET
LCD_CLEAR: ; (SUBROUTINE) CLEAR THE LCD SCREEN
LDI LCD_CHAR, 0X01
RCALL LCD_CTRL
RCALL DELAY_SHORT
RET
LCD_LINE1: ; (SUBROUTINE) FORCE LCD CURSOR TO LINE 1
LDI LCD_CHAR, 0X80
RCALL LCD_CTRL
RET
LCD_LINE2: ; (SUBROUTINE) FORCE LCD CURSOR TO LINE 2
LDI LCD_CHAR, 0XC0
RCALL LCD_CTRL
RET
LCD_CTRL: ; SUBROUTINE FOR SENDING CONTROL BYTES TO LCD
CBI PORTD, EN
CBI PORTD, RS
CBI PORTD, WR
OUT LCD_PORT, LCD_CHAR
SBI PORTD, EN
RCALL DELAY_LCD
CBI PORTD, EN
SBI PORTD, RS
RET
LCD_DATA: ; SUBROUTINE FOR SENDING DATA BYTES TO LCD
CBI PORTD, EN
SBI PORTD, RS
CBI PORTD, WR
OUT LCD_PORT, LCD_CHAR
SBI PORTD, EN
RCALL DELAY_LCD
CBI PORTD, EN
RET
LCD_STRING:
LPM LCD_CHAR, Z+
CPI LCD_CHAR, 0X00
BREQ QUIT_LCD_STRING
CPI LCD_CHAR, 0X0D
BREQ NEW_LINE
RCALL LCD_DATA
RJMP LCD_STRING
NEW_LINE:
RCALL LCD_LINE2
RJMP LCD_STRING
QUIT_LCD_STRING:
RET
;---------------------------------------------------------
; EEPROM READ AND WRITE INITIALIZATION GO HERE
;---------------------------------------------------------
EEPROM_WRITE: ; SUBROUTINE FOR WRITING EEPROM
SBIC EECR, EEWE ; SKIP NEXT INSTRUCTION IF EEPROM WRITE COMPLETED
RJMP EEPROM_WRITE ; IF NOT COMPLETED THEN LET IT BE COMPLETED FIRST
OUT EEARH, EADD_HIGH ; LOAD EEPROM HIGH BYTE OF ADDRESS
OUT EEARL, EADD_LOW ; LOAD EEPROM LOW BYTE OF ADDRESS
OUT EEDR, EEPROM_DATA ; LOAD DATA TO BE WRITTEN ON EEPROM DATA REGISTER
SBI EECR, EEMWE ; ENABLE EEPROM MEMORY WRITE OPERATION
SBI EECR, EEWE ; ENABLE EEPROM WRITE
RET ; RETURN BACK FROM WHERE IT WAS CALLED.
EEPROM_READ: ; SUBROUTINE FOR READING EEPROM
SBIC EECR, EERE ; SKIP NEXT INSTRUCTION IF EEPROM READ COMPLETED
RJMP EEPROM_READ ; IF NOT COMPLETED THEN LET IT BE COMPLETED FIRST
OUT EEARH, EADD_HIGH ; LOAD EEPROM HIGH BYTE OF ADDRESS
OUT EEARL, EADD_LOW ; LOAD EEPROM LOW BYTE OF ADDRESS
SBI EECR, EERE ; ENABLE EEPROM READ OPERATION
IN EEPROM_DATA, EEDR ; COPY DATA TO USER EEPROM_DATA FROM EEPROM DATA REGISTER
RET ; RETURN BACK FROM WHERE IT WAS CALLED
;---------------------------------------------------------
; MAIN PROGRAM CODE GO HERE
;---------------------------------------------------------
START:
LDI TEMP, LOW(RAMEND) ; LOAD LOW RAMEND IN TEMP
OUT SPL, TEMP ; LOAD STACK POINTER LOW BYTE WITH TEMP
LDI TEMP, HIGH(RAMEND) ; LOAD HIGH RAMEND IN TEMP
OUT SPH, TEMP ; LOAD STACK POINTER HIGH BYTE WITH TEMP
LDI TEMP, 47 ; VALUE 11 TO SET BAUD RATE 19200 bps
RCALL INITIALIZE_USART ; INITILIZE THE USART
RCALL INIT_LCD
RCALL INTRO_LCD
RCALL SET_DEFAULTS
RCALL DELAY
LDI TEMP, 0B00000011
OUT DDRB, TEMP
OUT PORTB, TEMP
LDI TEMP, 0XFF
OUT DDRA, TEMP
RCALL SET_ACTIVE_DEFAULTS
RCALL OUTPUT_TO_PORTA
CLI
RCALL INIT_CELL_PHONE
RCALL DISPLAY_SWITCHES_ON_LCD
RCALL BUZZER
SEI
FOREVER:
RJMP FOREVER ; KEEP IN INFINITE LOOP
;---------------------------------------------------------
; INIT_CELL_PHONE (SUBROUTINE)
INIT_CELL_PHONE:
CBI UCSRA, RXC
LDI TEMP, 'A'
RCALL TRANSMIT
LDI TEMP, 'T'
RCALL TRANSMIT
LDI TEMP, 0X0D
RCALL TRANSMIT
RCALL DELAY
RCALL SET_ECHO_OFF
RCALL DELAY
RCALL SET_MEM_SEL
RCALL DELAY
RCALL SET_SMS_HOOK
RCALL DELAY
RCALL SET_SMS_FORMAT
RCALL DELAY
; RCALL SET_SMS_DETAILS
; RCALL DELAY
SBI UCSRA, RXC
RET
MAKE_RCALL:
LDI ZH, HIGH(AT_CALL*2)
LDI ZL, LOW(AT_CALL*2)
CLR TEMP
RCALL TRANSMIT_LOOP
RET
;---------------------------------------------------------
; INTRO TEXT ON LCD (SUBROUTINE)
INTRO_LCD:
LDI ZH, HIGH(LCD_INTRO_STR*2)
LDI ZL, LOW(LCD_INTRO_STR*2)
RCALL LCD_CLEAR
RCALL LCD_STRING
RET
;---------------------------------------------------------
; SET PORTA OUTPUTS FOR RELAYS (SUBROUTINE)
OUTPUT_TO_PORTA:
CLR EADD_HIGH
LDI EADD_LOW, USER_DEVICE_BYTE
RCALL EEPROM_READ
COM EEPROM_DATA
OUT PORTA, EEPROM_DATA
RET
;---------------------------------------------------------
; DISPLAY SWITCHES STATUS ON LCD AT IDLE STATE
DISPLAY_SWITCHES_ON_LCD:
CLR EADD_HIGH
LDI EADD_LOW, USER_DEVICE_BYTE
RCALL EEPROM_READ
RCALL LCD_CLEAR
LDI ZH, HIGH(LCD_SWITCHES_STATUS_STR*2)
LDI ZL, LOW(LCD_SWITCHES_STATUS_STR*2)
RCALL LCD_STRING
LDI COUNT_IT, 8
DISPLAY_SWITCHES_ON_LCD_LOOP:
LDI LCD_CHAR, 0XDB
SBRC EEPROM_DATA, 0
LDI LCD_CHAR, 0XFF
SKIP_CHAR_ON_LCD:
RCALL LCD_DATA
ROR EEPROM_DATA
DEC COUNT_IT
CPI COUNT_IT, 0X00
BRNE DISPLAY_SWITCHES_ON_LCD_LOOP
QUIT_DISPLAY_SWITCHES_ON_LCD:
RET
;---------------------------------------------------------
; SET DEFAULTS IN EEPROM (SUBROUTINE)
SET_DEFAULTS:
CLR EADD_HIGH
LDI EADD_LOW, 0
RCALL EEPROM_READ
MOV TEMP, EEPROM_DATA
CPI TEMP, 0B01110011
BREQ QUIT_SET_DEFAULTS
CPI TEMP, 0XFF
BREQ LOAD_NEW_STATUS
RJMP CONTINUE_HERE
LOAD_NEW_STATUS:
LDI EADD_LOW, USER_STATUS_BYTE
LDI EEPROM_DATA, 0X00
RCALL EEPROM_WRITE
CONTINUE_HERE:
LDI EADD_LOW, USER_STATUS_BYTE
CLR EEPROM_DATA
RCALL EEPROM_READ
MOV TEMP, EEPROM_DATA
SBRS TEMP, 0
RCALL SET_DEFAULT_PASSWORD
SBRS TEMP, 1
RCALL SET_DEFAULT_USER
SBRS TEMP, 4
RCALL SET_BUZZER_OPTION
SBRS TEMP, 5
RCALL SET_DEVICE_BYTE
SBRS TEMP, 6
RCALL SET_DEVICE_LOCK_BYTE
RJMP SET_FOR_FUTURE_ALLERT
SET_FOR_FUTURE_ALLERT:
CLR EADD_HIGH
LDI EADD_LOW, 0
LDI EEPROM_DATA, 0B01110011
RCALL EEPROM_WRITE
RJMP QUIT_SET_DEFAULTS
QUIT_SET_DEFAULTS:
RET
SET_DEFAULT_PASSWORD:
LDI ZH, HIGH(DEFAULT_USER_PASSWORD*2)
LDI ZL, LOW(DEFAULT_USER_PASSWORD*2)
CLR EADD_HIGH
LDI EADD_LOW, USER_PASSWORD_AREA
RCALL DEFAULT_WRITE
ORI TEMP, 0B00000001
MOV EEPROM_DATA, TEMP
LDI EADD_LOW, USER_STATUS_BYTE
RCALL EEPROM_WRITE
RET
SET_DEFAULT_USER:
CLR EADD_HIGH
LDI EADD_LOW, USER_NAME_AREA1
LDI ZH, HIGH(DEFAULT_USER_NAME*2)
LDI ZL, LOW(DEFAULT_USER_NAME*2)
RCALL DEFAULT_WRITE
RJMP SET_DEFAULT_CONTACT
SET_DEFAULT_CONTACT:
CLR EADD_HIGH
LDI EADD_LOW, USER_CONTACT_AREA1
LDI ZH, HIGH(DEFAULT_USER_CONTACT*2)
LDI ZL, LOW(DEFAULT_USER_CONTACT*2)
RCALL DEFAULT_WRITE
ORI TEMP, 0B00000010
MOV EEPROM_DATA, TEMP
LDI EADD_LOW, USER_STATUS_BYTE
RCALL EEPROM_WRITE
RET
SET_BUZZER_OPTION:
CLR EADD_HIGH
LDI EADD_LOW, USER_BUZZER_BYTE
LDI EEPROM_DATA, '1'
RCALL EEPROM_WRITE
CLR EEPROM_DATA
ORI TEMP, 0B00010000
MOV EEPROM_DATA, TEMP
LDI EADD_LOW, USER_STATUS_BYTE
RCALL EEPROM_WRITE
RET
SET_DEVICE_BYTE:
CLR EADD_HIGH
LDI EADD_LOW, USER_DEVICE_BYTE
CLR EEPROM_DATA
RCALL EEPROM_WRITE
CLR EEPROM_DATA
ORI TEMP, 0B00100000
MOV EEPROM_DATA, TEMP
LDI EADD_LOW, USER_STATUS_BYTE
RCALL EEPROM_WRITE
RET
SET_DEVICE_LOCK_BYTE:
CLR EADD_HIGH
LDI EADD_LOW, USER_DEVICE_LOCK_BYTE
CLR EEPROM_DATA
RCALL EEPROM_WRITE
CLR EEPROM_DATA
ORI TEMP, 0B01000000
MOV EEPROM_DATA, TEMP
LDI EADD_LOW, USER_STATUS_BYTE
RCALL EEPROM_WRITE
RET
DEFAULT_WRITE:
LPM EEPROM_DATA, Z+
WAIT
RCALL EEPROM_WRITE
WAIT
CPI EEPROM_DATA, 0X00
BREQ QUIT_DEFAULT_WRITE
INC EADD_LOW
RJMP DEFAULT_WRITE
QUIT_DEFAULT_WRITE:
RET
;---------------------------------------------------------
; SET ACTIVE DEFAULT SETTINGS
SET_ACTIVE_DEFAULTS:
CLR EADD_HIGH
LDI EADD_LOW, USER_BUZZER_BYTE
RCALL EEPROM_READ
CPI EEPROM_DATA, '0'
BREQ SET_BUZZER_OFF
SBI DDRB, PB2
SER BUZZER_STATUS
RJMP LOCK_SWITCH_SETTINGS
SET_BUZZER_OFF:
CLR BUZZER_STATUS
LOCK_SWITCH_SETTINGS:
RJMP QUIT_SET_ACTIVE_DEFAULTS
QUIT_SET_ACTIVE_DEFAULTS:
RET
BUZZER:
CPI BUZZER_STATUS, 0XFF
BRNE QUIT_BUZZER
SBI PORTB, PB2
RCALL DELAY_SHORT
CBI PORTB, PB2
QUIT_BUZZER:
RET
;---------------------------------------------------------
; ECHO OFF SUBROUTINE (ATE = 0)
SET_ECHO_OFF:
LDI ZH, HIGH(AT_ECHO_OFF*2)
LDI ZL, LOW(AT_ECHO_OFF*2)
CLR TEMP
RCALL TRANSMIT_LOOP
RET
;---------------------------------------------------------
; MEMORY SELECT SUBROUTINE (AT+CPMS = "ME","ME","ME")
SET_MEM_SEL:
LDI ZH, HIGH(AT_MEM_SEL*2)
LDI ZL, LOW(AT_MEM_SEL*2)
CLR TEMP
RCALL TRANSMIT_LOOP
RET
;---------------------------------------------------------
; SET SMS HOOK SUBROUTINE (AT+CNMI = 2,1,0,0,0)
SET_SMS_HOOK:
LDI ZH, HIGH(AT_SMS_HOOK*2)
LDI ZL, LOW(AT_SMS_HOOK*2)
CLR TEMP
RCALL TRANSMIT_LOOP
RET
;---------------------------------------------------------
; SMS DELETE FROM MOBILE SUBROUTINE (AT+CMGD = 1)
SET_SMS_DELETE:
LDI ZH, HIGH(AT_SMS_DEL*2)
LDI ZL, LOW(AT_SMS_DEL*2)
CLR TEMP
RCALL TRANSMIT_LOOP
RET
;---------------------------------------------------------
; SET SMS FORMAT SUBROUTINE (AT+CMGF = 1) TEXT MODE
SET_SMS_FORMAT:
LDI ZH, HIGH(AT_SMS_FORMAT*2)
LDI ZL, LOW(AT_SMS_FORMAT*2)
CLR TEMP
CLR COUNT_IT
SMS_FORMAT_CONT:
LPM TEMP, Z+
CPI TEMP, 0X00
BREQ QUIT_SMS_FORMAT
RCALL TRANSMIT
RJMP SMS_FORMAT_CONT
QUIT_SMS_FORMAT:
RET
;---------------------------------------------------------
; SET TYPE OF SMS DISPLAYED SUBROUTINE
SET_SMS_TYPE: ; MESSAGE TYPE AS 'UNREAD'
LDI ZH, HIGH(AT_SMS_TYPE*2)
LDI ZL, LOW(AT_SMS_TYPE*2)
CLR TEMP
CLR COUNT_IT
SMS_TYPE_CONT:
LPM TEMP, Z+
CPI TEMP, 0X00
BREQ QUIT_SMS_TYPE
RCALL TRANSMIT
RJMP SMS_TYPE_CONT
QUIT_SMS_TYPE:
RET
;---------------------------------------------------------
; SET DETAILS OF SMS DISPLAYED SUBROUTINE
SET_SMS_DETAILS:
LDI ZH, HIGH(AT_SMS_TEXT_DETAILED*2)
LDI ZL, LOW(AT_SMS_TEXT_DETAILED*2)
CLR TEMP
CLR COUNT_IT
RCALL TRANSMIT_LOOP
RET
;---------------------------------------------------------
; READ SMS FROM FIRST LOCATION (AT+CMGR = 1)
SET_SMS_READ:
CLI
RCALL DELAY_SHORT
LDI XH, HIGH(RAM_AREA_FOR_SMS)
LDI XL, LOW(RAM_AREA_FOR_SMS)
SBI UCSRB, RXEN
LDI ZH, HIGH(AT_MSG_READ*2)
LDI ZL, LOW(AT_MSG_READ*2)
RCALL TRANSMIT_LOOP
GET_SMS_DATA_FROM_CELL:
SBIS UCSRA, RXC
RJMP GET_SMS_DATA_FROM_CELL
IN USART_DATA, UDR
ST X+, USART_DATA
CPI USART_DATA, 'K'
BREQ SMS_READY
RJMP GET_SMS_DATA_FROM_CELL
SMS_READY:
CBI UCSRB, RXEN
LDI TEMP, 0X00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -