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

📄 datalog.asm

📁 该应用软件可以实现大多数单片机的仿真实验
💻 ASM
📖 第 1 页 / 共 2 页
字号:
LIST p=18F458 ;PIC18F458 is the target processor

#include "P18f458.INC" ;Include header file

;====================================================================
; Macros
;--------------------------------------------------------------------

#define CLK_FREQ	D'20000000'
#define BAUD(x)	((CLK_FREQ/x)/D'64')-1

#define BRG_VAL	BAUD(D'9600')	;Baud rate configuration value

;====================================================================
; Uninitialised data
;--------------------------------------------------------------------

; General temps
TMP1		equ	0x000000
TMP2		equ	0x000001

; Current LBA sector address for reading/wring
ATA_A0		equ	0x000002
ATA_A1		equ	0x000003
ATA_A2		equ	0x000004
ATA_A3		equ	0x000005

; Counter used to track data words read/written to/from ATA
ATA_CNT		equ	0x000006

; High priority interrupt temps
STATUS_TEMP_H	equ	0x000007
WREG_TEMP_H	equ	0x000008
BSR_TEMP_H	equ	0x000009

; Low priority interrupt temps
STATUS_TEMP_L	equ	0x00000A
WREG_TEMP_L	equ	0x00000B
BSR_TEMP_L	equ	0x00000C

; Countdown number of timer 0 overflows
T0COUNT		equ	0x00000D

; End of logged data
END_POSL	equ	0x00000E
END_POSH	equ	0x00000F
END_ATA_A0	equ	0x000010
END_ATA_A1	equ	0x000011
END_ATA_A2	equ	0x000012
END_ATA_A3	equ	0x000013

; Temp for log data to be displayed
INPDATA_L	equ	0x000014
INPDATA_H	equ	0x000015

; Countdoen the number of log entries on a display line
OUT_COUNT	equ	0x000016

; ATA data transfer buffer
ATA_BUF		equ	0x000400
ATA_BUF_END	equ	0x000600

;====================================================================
; Interrupt vectors
;--------------------------------------------------------------------
	org	0x000000	;Reset vector
	bra	START

	org	0x000008	;High priority interrupt vector
	bra	INT_HIGH

	org	0x000018	;Low priority interrupt vector
	bra	INT_LOW

;====================================================================
; Main program
;--------------------------------------------------------------------
START
	rcall	INIT		; Program initialisation
	rcall	OUT_VERSION	; Version message
REHELP
	rcall	OUT_HELP	; Help message
MLOOP
	rcall	OUT_COMMAND	; Command prompt

	rcall	UART_Getch	; Get user input
	movwf	TMP1		; and store

	rcall	OUT_CRLF	; Newline
	movlw	'h'		; Check for help
	xorwf	TMP1, W
	bz	REHELP
	movlw	'H'
	xorwf	TMP1, W
	bz	REHELP
	movlw	'v'		; Check for version
	xorwf	TMP1, W
	bz	VERSION
	movlw	'V'
	xorwf	TMP1, W
	bz	VERSION
	movlw	'l'		; Check for log start
	xorwf	TMP1, W
	bz	LOG
	movlw	'L'
	xorwf	TMP1, W
	bz	LOG
	movlw	'd'		; Check for log dump
	xorwf	TMP1, W
	bz	DUMP
	movlw	'D'
	xorwf	TMP1, W
	bz	DUMP
	rcall	OUT_UNKNOWN	; Command is unknown
	goto	MLOOP

VERSION	rcall	OUT_VERSION	; Version message
	goto	MLOOP

LOG	rcall	OUT_LOG		; Log start message
	rcall	LOG_START	; Enable logging under interrupt
	rcall	UART_Getch	; Wait for any user input
	rcall	LOG_STOP	; Terminate logging
	rcall	OUT_CRLF
	goto	MLOOP

DUMP	rcall	OUT_DUMP	; Dump start message
	rcall	DUMP_ALL	; Dump data
	goto	MLOOP

;====================================================================
; Program initialisation
;--------------------------------------------------------------------
INIT
	;Setup serial comms
	movlw	b'10010000'	;Enable USART in continous receive mode
	movwf	RCSTA
	movlw	b'00100010'	;Async, TX enabled, low baud rate
	movwf	TXSTA
	movlw	BRG_VAL		;Set baud rate
	movwf	SPBRG
	movf	RCREG, W	;Flush out RX buffer
	movf	RCREG, W

	;Setup I/O ports
	clrf	PORTA
	setf	TRISA		; Port A all input
	clrf	PORTB
	setf	TRISB		; Port B all input, ATA D0-7
	clrf	PORTC
	movlw	B'11100000'	; Port C lower bits for ATA adressing
	movwf	TRISC
	movlw	B'00000111'	; Turn off comparitor
	movwf	CMCON		; On PORTD bits 0-3
	clrf	PORTD
	setf	TRISD		; Port D all input, ATA D8-15
	movlw	B'00000011'
	movwf	PORTE
	movlw	B'00000100'	; Port E lower two bits output for ATA
	movwf	TRISE		; read and write
	rcall	LOG_RESET	; Reset log pointers
	rcall	LOG_UPDATE
	return

;====================================================================
; High priority intrrupt handler
;--------------------------------------------------------------------
INT_HIGH
	movff	STATUS, STATUS_TEMP_H
	movff	BSR, BSR_TEMP_H
	movwf	WREG_TEMP_H

	bcf	INTCON, TMR0IF	;Clear timer 0 overflow interrupt flag
	decfsz	T0COUNT
	bra	INT_HIGH_EXIT1
	movlw	D'20'		;Only start conversion every 20 timer 0 timeouts
	movwf	T0COUNT
	bsf	ADCON0, GO	;Start ADC conversion

INT_HIGH_EXIT1
	movf	WREG_TEMP_H, W
	movff	BSR_TEMP_H, BSR
	movff	STATUS_TEMP_H, STATUS
	retfie

;====================================================================
; Low prority interrupt handler
;--------------------------------------------------------------------
INT_LOW
	movff	STATUS, STATUS_TEMP_L
	movff	BSR, BSR_TEMP_L
	movwf	WREG_TEMP_L

	movf	ADRESL, W	;Copy ADC result to buffer
	movwf	POSTINC2
	movf	ADRESH, W	;Copy ADC result to buffer
	movwf	POSTINC2

	bcf	PIR1, ADIF	;Clear ADC interrupt flag

	movlw	HIGH(ATA_BUF_END)	; Check if at end of buffer
	cpfseq	FSR2H
	bra	INT_LOW_EXIT1
	movlw	LOW(ATA_BUF_END)
	cpfseq	FSR2L
	bra	INT_LOW_EXIT1

	rcall	ATA_Block_Write
	rcall	ATA_A_INC
	lfsr	FSR2, ATA_BUF	; Point to start of data capture buffer

INT_LOW_EXIT1
	movf	WREG_TEMP_L, W
	movff	BSR_TEMP_L, BSR
	movff	STATUS_TEMP_L, STATUS
	retfie

;====================================================================
; Read a byte from the serial port
;--------------------------------------------------------------------
; W contains the byte that was received
;--------------------------------------------------------------------
UART_Getch
	clrwdt
	btfss	PIR1, RCIF	; Wait for RX buffer full
	bra	UART_Getch
	movf	RCREG, W
	return

;====================================================================
; Write a byte to the serial port
;--------------------------------------------------------------------
; W contains the byte to be sent
;--------------------------------------------------------------------
UART_Putch
	btfss	PIR1, TXIF	; Wait for TX buffer empty
	bra	UART_Putch
	movwf	TXREG
	return

;====================================================================
; Write null terminated string to serial port from
; program memory
;--------------------------------------------------------------------
; TBLPTR Points to the start of the string
;--------------------------------------------------------------------
UART_Puts_loop
	rcall	UART_Putch	
UART_Puts
	tblrd*+
	movf	TABLAT, W
	bnz	UART_Puts_loop
	return

;====================================================================
; Read a sector from the ATA drive
;--------------------------------------------------------------------
ATA_Block_Read
	rcall	ATA_BSY_Wait	; Drive ready for command
	rcall	ATA_Send_LBA
	movlw	0x20		; Read sectors command
	movwf	TMP1
	movlw	0x17		; ATA Command regsiter
	rcall	ATA_Reg8_Write
	clrf	ATA_CNT
	lfsr	FSR0, ATA_BUF
ATA_Block_Read_Lp1
	rcall	ATA_DRQ_Wait	; Drive data waiting
	movlw	0x10
	rcall	ATA_Reg16_Read
	movf	TMP1, W
	movwf	POSTINC0
	movf	TMP2, W
	movwf	POSTINC0
	incfsz	ATA_CNT
	bra	ATA_Block_Read_Lp1
	return

;====================================================================
; Write a sector too the ATA drive
;--------------------------------------------------------------------
ATA_Block_Write
	rcall	ATA_BSY_Wait	; Drive ready for command
	rcall	ATA_Send_LBA
	movlw	0x30		; Write sectors command
	movwf	TMP1
	movlw	0x17		; ATA Command regsiter
	rcall	ATA_Reg8_Write
	clrf	ATA_CNT
	lfsr	FSR0, ATA_BUF

ATA_Block_Write_Lp1
	rcall	ATA_DRQ_Wait	; Drive ready for data
	movf	POSTINC0, W
	movwf	TMP1
	movf	POSTINC0, W
	movwf	TMP2
	movlw	0x10
	rcall	ATA_Reg16_Write
	incfsz	ATA_CNT
	bra	ATA_Block_Write_Lp1

	return

;====================================================================
; Wait for DRQ to indicate drive is ready for data
;--------------------------------------------------------------------
ATA_DRQ_Wait
	movlw	0x17		; Drive status register
	rcall	ATA_Reg8_Read
	btfss	TMP1, 3		; DRQ bit (data request)
	bra	ATA_DRQ_Wait
	return

;====================================================================
; Wait for BSY to indicate drive is ready for a command
;--------------------------------------------------------------------
ATA_BSY_Wait
	movlw	0x17		; Drive status register
	rcall	ATA_Reg8_Read
	btfsc	TMP1, 7		; BSY bit (busy)
	bra	ATA_BSY_Wait
	return

;====================================================================
; Zero out LBA address
;--------------------------------------------------------------------
ATA_A_RESET
	clrf	ATA_A0		; Point to first sector
	clrf	ATA_A1
	clrf	ATA_A2
	clrf	ATA_A3
	return

;====================================================================
; Increment LBA address by one
;--------------------------------------------------------------------
ATA_A_INC
	incfsz	ATA_A0		; Point to next sector
	bra	ATA_A_INC_EXIT
	incfsz	ATA_A1
	bra	ATA_A_INC_EXIT
	infsnz	ATA_A2
	incf	ATA_A3
ATA_A_INC_EXIT
	return

;====================================================================
; Transfer LBA address to drive
;--------------------------------------------------------------------
ATA_Send_LBA
	movlw	0x01		; Sector count
	movwf	TMP1
	movlw	0x12		; ATA Sector count
	rcall	ATA_Reg8_Write
	movff	ATA_A0, TMP1
	movlw	0x13		; ATA LBA 0-7 register
	rcall	ATA_Reg8_Write
	movff	ATA_A1, TMP1
	movlw	0x14		; ATA LBA 8-15 register
	rcall	ATA_Reg8_Write
	movff	ATA_A2, TMP1
	movlw	0x15		; ATA LBA 16-23 register
	rcall	ATA_Reg8_Write
	movf	ATA_A3, W
	iorlw	B'01000000'	; Indicate address is LBA not CHS
	movwf	TMP1
	movlw	0x16		; ATA LBA 24-27 register
	rcall	ATA_Reg8_Write
	return
;====================================================================
; Read a register from the ATA drive (8 bit)
;--------------------------------------------------------------------
; W    contains address
; TMP1 contains data

⌨️ 快捷键说明

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