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

📄 atmega32_project.asm

📁 Home Automation System (Source Code)
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;---------------------------------------------------------
;	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 + -