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

📄 midimmcm8.asm

📁 用ATMEGA8开发的MMC程式,可用AVR-GCC开发
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;********************************************************************
;*
;* MIDI Rekorder v2
;* "Mr. MIDI" 
;* MMC/SD-card, LCD display, 5 buttons, 2 LEDs, MIDI I/O
;*
;*

;*** Includes
.include "m8def.inc"
.include "mmc.asm"
.include "lcd.asm"

;*** Constants
.equ	CPUFRQ	=1000000
.equ	BR	=31250
.equ	BAUDRC	=1		; CPUFRQ/(16*BR)-1
.equ	SECTOR	=113
.equ	T0SCL	=0x05
.equ	T0FST	=0x04
.equ	T1SCL	=0x04
.equ	T1FST	=0x03
.equ	T2SCL	=0x05
.equ	CHRLN	=24
.equ	KEYDELAY=4
; Midi Befehle
.EQU	GMreset	=255
.EQU	MIDIalv	=0xFE
.EQU	MIDIclk	=0xF8
.EQU	MIDIstop=0xFC
; Modi
.EQU	smPLAY	=0x01
.EQU	mPLAY	=0
.EQU	smREC	=0x02
.EQU	mREC	=1
.EQU	smFULL	=0x04
.EQU	mFULL	=2
.EQU	smEOS	=0x08
.EQU	mEOS	=3
.EQU	smMMCBS	=0x10
.EQU	mMMCBS	=4
.EQU	smMMCWR	=0x20
.EQU	mMMCWR	=5
.EQU	smPAUSE	=0x40
.EQU	mPAUSE	=6
.EQU	smFFWD	=0x80
.EQU	mFFWD	=7


;*** Addresses in SRAM
.equ	CMD	=0x0060		; MMC command (5 bytes)
.equ	RXBUF	=0x0100		; MIDI RxBuffer
.equ	BUFSIZE	=3


;*** Ports & Pins
; PORT D
.equ	RxD	=0		; HW-UART
.equ	TxD	=1		; -"-
.equ	KEYs	=PIND
.equ	KEY1	=2		; Play
.equ	KEY2	=3		; Stop
.equ	KEY3	=4		; Rec
.equ	KEY4	=5		; Up
.equ	KEY5	=6		; Down
.equ	KEYMASK	=0x7C
; PORT C
.equ	LCD	=PORTC
; PORT B
.equ	LEDr	=6		; Record LED
.equ	LEDp	=7		; Play LED
.equ	LEDs	=PORTB
.equ	KEY6	=0		; FFW
.equ	KEY7	=1		; RWD
.equ	KEYs2	=PINB
.equ	KEYMSK2	=0x03


;*** REG defs
.def	null	=r1		; 0
.def	oldkey	=r2
.def	work	=r16		; General working register
.def	temp	=r17		; -"-
.def	cnt	=r18		; General counter
.def	inreg	=r3
.def	mode	=r19		; Mode of state machine
.def	t2	=r5		; Timer 1 is used as counter t0, t1
.def	p0	=r6		; Set of midi data and timing
.def	p1	=r7
.def	p2	=r8
.def	sd	=r9
.def	regs	=r10		; Saves SREG
.def	mcntl	=r11		; Bytecounter im Sektor
.def	mcnth	=r12
.def	scntl	=r13		; Sektorcounter in MMC
.def	scnth	=r14
.def	scnts	=r15
.def	dcnt	=r20
.def	cfilel	=r21
.def	cfileh	=r22
;.def	t0cntl	=r23
;.def	t0cnth	=r24
.def	PCLK	=r23
.def	SL	=r24
.def	SH	=r25

.ESEG
.ORG	1
.DB	1
.ORG	2
.DB	0
.ORG	3
.DB	SECTOR

.CSEG
;***********************************************************
;* 	INT table
;*

.ORG	0
	rjmp	RESET

.ORG	OVF1addr
	rjmp	T1_OVF

.ORG	OVF0addr
	rjmp	T0_OVF

.ORG	OVF2addr
	rjmp	T2_OVF

.ORG	URXCaddr
	rjmp	UART_RXCP

.ORG	UTXCaddr
	rjmp	UART_TXCP



;***********************************************************
;* 	INT routines
;*


T0_OVF:	; Timer 0 overflow
;	in	regs,	SREG
;	inc	t0cntl
;	brne	ET0
;	inc	t0cnth
;  ET0:	out	SREG,	regs
	reti

T2_OVF:	; Timer 2 overflow
	reti


T1_OVF:	; Timer 1 overflow
	in	regs,	SREG
	inc 	t2
	out	SREG,	regs
	reti


UART_RXCP: ; Received a midi event
	in	regs,	SREG
	in 	inreg, 	UDR		; fetch byte from UART data reg. 
	sbrc	mode,	mREC
	  rcall	RECMIDI
	out	SREG,	regs
	set
	reti


UART_TXCP: ; Sent a midi event
	set
	reti



;***********************************************************
;* 	The program
;*

RESET:	; Start up
	ldi 	work, 	LOW(RAMEND)	; set up stack
	out 	SPL, 	work
	ldi 	work, 	HIGH(RAMEND)
	out 	SPH, 	work					 

	clr	mode
	clr	scntl
	clr	scnth
	clr	scnts
	clr	cfilel
	clr	cfileh

	rcall	INIT_HW

	in	work,	KEYs
	andi	work,	KEYMASK
	in	temp,	KEYs2
	andi	temp,	KEYMSK2
	or	work,	temp
	mov	oldkey,	work


MAIN:	in	work,	KEYs		; get keys
	andi	work,	KEYMASK
	in	temp,	KEYs2
	andi	temp,	KEYMSK2
	or	work,	temp

	cp	work,	oldkey
	brne	KEY_HDL
;	cpi	work,	KEYMASK|KEYMSK2
;	brne	H_T0

  RK:	sbrc	mode,	mPLAY
	  rcall	PLAY1
	sbrc	mode,	mREC
	  rcall	BUF2MMC
	sbrc	mode,	mREC
	  rcall	CALCTIME

	ldi	work,	(1<<SE)
	out	MCUCR,	work
	sbrs	mode,	mPLAY
	  sleep
	clt
	rjmp	MAIN

;H_T0:	cpi	t0cnth,	KEYDELAY
;	brlo	RK
;	ldi	work,	T0FST
;	out	TCCR0,	work
;	clr	t0cntl
;	clr	t0cnth
;	ldi	work,	KEYMASK|KEYMSK2
;	mov	oldkey,	work
;	rjmp	MAIN

H_FAST:	;out	TCCR0,	null
	;clr	t0cntl
	;clr	t0cnth
	sbrs	mode,	mFFWD
	  rjmp	RH
	cbr	mode,	smFFWD
	ldi	work,	T1SCL
	sbrc	mode,	mPLAY
	  out	TCCR1B,	work
	rjmp	RH

KEY_HDL:mov	oldkey,	work
	cpi	work,	KEYMASK|KEYMSK2
	breq	H_FAST
	clr	PCLK

	sbis	PIND,	2
	  rjmp	PLAY
	sbis	PIND,	4
	  rjmp	REC
	sbis	PIND,	3
	  rjmp	STOP
	sbis	PIND,	5
	  rjmp	INCFN
	sbis	PIND,	6
	  rjmp	DECFN
	sbis	PINB,	0
	  rjmp	FFW
	sbis	PINB,	1
	  rjmp	RWD

  RH:	rcall	delay
	rjmp	RK



; *** PLAY Taste

PLAY:	sbrc	mode,	mREC
	  rjmp	RH
	sbrc	mode,	mPAUSE
	  rjmp	H_PAUSE
	sbrc	mode,	mPLAY
	  rjmp	H_PLAY

	; Modus Play
	sbr 	mode, 	smPLAY

	cbi	LEDs,	LEDp
	sbi	LEDs,	LEDr

	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_play<<1)
	ldi	ZH,	HIGH(t_play<<1)
	rcall	ROM_LINE
	rcall	SHOWFILENR
	; Pointer auf song start
	rcall	INITMIDI
	; Lies ersten Datensatz
	rcall	READ_SECTOR_START
 PLAYOK:rcall	READMIDI
	mov	t2,	p2
	out	TCNT1H,	p1
	out	TCNT1L,	p0
	; Timer start
	ldi 	work, 	T1SCL
	out 	TCCR1B,	work
	rjmp	RH

 H_PLAY:sbr	mode,	smPAUSE
	out	TCCR1B,	null
	rcall	SENDALLOFF
	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_pause<<1)
	ldi	ZH,	HIGH(t_pause<<1)
	rcall	ROM_LINE
	rcall	CALCTIME
	rjmp	RH

 H_PAUSE:cbr	mode,	smPAUSE
	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_play<<1)
	ldi	ZH,	HIGH(t_play<<1)
	rcall	ROM_LINE
	ldi 	work, 	T1SCL
	out 	TCCR1B,	work
	rjmp	RH


; *** REC Taste

REC:	sbrc	mode,	mPLAY
	  rjmp	RH
	sbrc	mode,	mREC
	  rjmp	RH
	; Modus Record
	sbr 	mode, 	smREC
	cbi	LEDs,	LEDr
	sbi	LEDs,	LEDp
	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_recsb<<1)
	ldi	ZH,	HIGH(t_recsb<<1)
	rcall	ROM_LINE
	rcall	SHOWFILENR
	; Z鋒ler reset
	rcall	INITMIDI
	ldi	YH,	HIGH(RXBUF)
	ldi	ZH,	HIGH(RXBUF)
	clr	YL
	clr	ZL
	rcall	WRITE_SECTOR_START
RECOK:	sbr	mode,	smMMCWR
	in	work,	UDR
	sbi 	UCSRB, 	RXCIE
	rjmp	RH


; *** STOP Taste

STOP:	; Stoppt REC und PLAY
	out	TCCR1B,	NULL
	; Wenn im Rec Mode, schreibe STOPP Event und RxInt Disable
	sbrs	mode,	mREC
	  rjmp	ST_
;	ldi	ZL,	LOW(t_stop<<1)
;	ldi	ZH,	HIGH(t_stop<<1)
;	rcall	SENDSTRING

	rcall	WRITESTOP
	cbi 	UCSRB, 	RXCIE
  STP:	ldi	work,	MIDISTOP
	rcall	WCHAR
	cpi	work,	0
	brne	STP	
	cbr	mode,	smMMCWR
	rcall	WRITE_SECTOR_END
  ST_:	sbrc	mode,	mPLAY
	  rcall	READ_SECTOR_END
	sbi	MMC_Write,	MMC_Chip_Select
	clr	mode
	sbi	LEDs,	LEDr
	sbi	LEDs,	LEDp
	rcall	CALCSECTOR
	rcall	delay
	rcall	INIT_MMC
	; Midiger鋞 ausmachen
	rcall	SENDALLOFF
	ldi	work,	CHRLN
	ldi	ZL,	LOW(t_stop<<1)
	ldi	ZH,	HIGH(t_stop<<1)
	rcall	ROM_LINE

	rcall	INIT_MMC
	rjmp	RH


; *** UP Taste
INCFN:	sbrc	mode,	mREC
	  rjmp	RH
	sbrc	mode,	mPLAY
	  rjmp	RH
;	ldi	work,	T0SCL
;	out	TCCR0,	work

	inc	cfilel
	brne	CEQ
	inc	cfileh

  CEQ:	mov	work,	cfilel
	ldi	temp,	1
	rcall	EEwrite
	mov	work,	cfileh
	ldi	temp,	2
	rcall	EEwrite

	rcall	CALCSECTOR
	rjmp	RH


; *** DOWN Taste
DECFN:	sbrc	mode,	mREC
	  rjmp	RH
	sbrc	mode,	mPLAY
	  rjmp	RH
;	ldi	work,	T0SCL
;	out	TCCR0,	work

	subi	cfilel,	1
	brsh	CSH
	dec	cfileh

  CSH:	mov	work,	cfilel
	ldi	temp,	1
	rcall	EEwrite
	mov	work,	cfileh
	ldi	temp,	2
	rcall	EEwrite

	rcall	CALCSECTOR
	rjmp	RH

CALCSECTOR:; Calculates sector address for current file
	ldi	temp,	3
	rcall	EEread			; Read sector offset
	mov	scntl,	work
	mov	scnth,	cfilel
	mov	scnts,	cfileh
	rcall	SHOWFILENR

;	com	work
;	out	LEDs,	work
	ret


; *** FFWD Taste
FFW:	sbrc	mode,	mREC
	  rjmp	RH
	sbrc	mode,	mPLAY
	  rjmp	SPDUP
;	ldi	work,	T0SCL
;	out	TCCR0,	work

	inc	scntl
	brne	EFFW
	inc	scnth
	brne	EFFW
	inc	scnts
  EFFW:	rcall	SHOWSECTOR
	rjmp	RH

 SPDUP:	sbrc	mode,	mPAUSE
	  rjmp	P_FWD
	ldi	work,	T1FST
	out	TCCR1B,	work
	sbr	mode,	smFFWD
	rjmp	RH

 P_FWD:	inc	scntl
	brne	EPF
	inc	scnth
	brne	EPF
	inc	scnts
  EPF:	rcall	SHOWSECTOR
	rcall	RESR
	rjmp	RH


; *** RWD Taste
RWD:	sbrc	mode,	mREC
	  rjmp	RH
;	ldi	work,	T0SCL
;	out	TCCR0,	work

	ldi	work,	1
	sub	scntl,	work
	brsh	ERWD
	sub	scnth,	work
	brsh	ERWD
	dec	scnts
  ERWD:	rcall	SHOWSECTOR

	sbrs	mode,	mPLAY
	  rjmp	RH
	rcall	RESR
	ldi	work,	T1SCL
	out	TCCR1B,	work
	rjmp	RH
		
 RESR:	
	out	TCCR1B,	null
	rcall	SENDALLOFF
  RLS:	rcall	Read_Byte_MMC
	rcall	INCMCNT
	cpi	work,	0
	breq	RLS
	rcall	READ_SECTOR_END
;	sbi	MMC_Write,	MMC_Chip_Select
	rcall	delay
	rcall	READ_SECTOR_START
	rcall	SHOWSECTOR
	rcall	READMIDI
	mov	t2,	p2
	out	TCNT1H,	p1
	out	TCNT1L,	p0
	rcall	CALCTIME
	ret


; *** PLAY Polling

PLAY1:	sbrs	mode,	mPLAY		; Check Modus Play
	  ret
	sbrc	mode,	mREC		; Check Modus Play
	  ret
	sbrc	mode,	mPAUSE		; Check Modus Pause
	  ret
	;Timer t2 check
	;rcall	compT1
	;Vergleiche t (Timerstand) mit p (Liedposition)
;	ldi	ZL,	LOW(t_playpoll<<1)
;	ldi	ZH,	HIGH(t_playpoll<<1)
;	rcall	SENDSTRING

	in	work,	TCNT1L
	in	temp,	TCNT1H
	cp	t2,	p2
	breq	NCHK1
	brlo	PEXIT
	rjmp	POSOK
 NCHK1:	cp	temp,	p1
 	breq	NCHK2
	brlo	PEXIT
	rjmp	POSOK
 NCHK2:	cp	work,	p0
	brlo	PEXIT
	; Pos. passt: Gebe Daten wieder, lade neue Daten
 POSOK:	;cbr	intf,	sUTX
	clt
	out	UDR,	sd

 WPLAY:	brtc	WPLAY
;	cbr	intf,	sUTX
	clt

	rcall	READMIDI
 PEXIT:	inc	PCLK
	brne	PPEX
	rcall	CALCTIME
  PPEX:	ret





;***********************************************************
;* 	Additional routines
;*

INIT_HW: ; Inits the micro; no params
	clr 	null

	; Timer setup
	out 	TCCR1B,	NULL		; T1SCL to start
	out	TCNT1H,	NULL
	out 	TCNT1L,	NULL		; Timer 0.5ms
	ldi	work,	T2SCL
	out	TCCR2,	work
	out	TCCR0,	NULL
;	clr	t0cnth
	ldi 	work,	(1<<TOIE1)|(1<<TOIE2)|(1<<TOIE0)
	out 	TIMSK,	work		; Timer interrupts

	; UART setup
	ldi 	work, 	BAUDRC		; baudrate constant
	out 	UBRRL, 	work		; prepare baud rate register
	sbi 	UCSRB, 	RXEN		; set "receive enable flag"
	sbi 	UCSRB, 	TXEN		; set "transmitter enable flag"
	cbi 	UCSRB, 	RXCIE		; and "received character interrupt enable flag"
	sbi 	UCSRB, 	TXCIE		; and "received character interrupt enable flag"
	sei
	in	inreg,	UDR
	clt
	
	; PORT setup
	ldi	work,	0xEC
 	out	DDRB,	work		; //PB7=SCK,PB6=MISO,PB5=MOSI,PB4=MMC_CS,PB3..0 not used
	ldi	work,	0xC7
	out	PORTB,	work

⌨️ 快捷键说明

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