freq.asm

来自「8051 进行加解密的源代码」· 汇编 代码 · 共 314 行

ASM
314
字号
;***************************************************************;Simple frequency counter for Infinion 80c515 ;designed for 12 MHz Xtals;this code can be addapted to all x52 cores which support;a 16 bit timer in autoreload mode and a 16 bit counter;max frequency @ 12 MHz is 500 kHz (6 Digits resolution);GateTime is 1 s;***************************************************************;***************************************************************;V0.1 Notes;***************************************************************;This example works for 80c535 only;frequency must be connected at T0 Pin;there is a error which comes from irq processing time;this error will increase at higher frequencies;Simulation shows 50001 Hz at 50000 Hz ;this error can be corrected by the outputfunction ;This is because the last reload should be a few clocks ;shorter to compensate the exec Time;***************************************************************;V0.2 notes;***************************************************************;using a reload value of -49999 instead of -500000;shows much better results, this was a bug in V0.1 :-);Simulation now shows 499.999 kHz at 500.000 kHz;added a simple Outputfunktion which actually;fills a buffer with frequency as HexAscii;***************************************************************;toDo List;***************************************************************;support for generic x52 ;support for decimal output;support for LCD or RS232 output;support for different crystals;support for 10 s GateTime$NOMOD51 		; disable predefined 8051 registers$DEBUG			;$INCLUDE(reg515.inc)	;;this is for memory PlacementProg     equ     0000h 	;Starting address for the programBitVar   equ     0	;where the Bitsegment startsDataVar  equ     024h   ;were the Data Segment starts;some ConstantsT0_MASK  equ	 0F0hT1_MASK  equ     00Fh;Symbol definitions used in "main" to control the LCD display.;not used at allLCD_CLR equ 	01AH 	;clear LCD commandLCD_LF 	equ 	0AH 	;LCD line feed (next line)LCD_CR 	equ 	0DH 	;LCD carriage return;some port definitions to make the code more readableRAM_A16  Bit	P5.0EEP_ENA  Bit    P5.2bMode    Bit    P5.3    ;Check this PortPin to read Mode of op ;Place for data vars ;**************************************************************DSEG at DataVar		;start at DataSeg GateTime:  DS 1		;the GateOVCounterOverFlow:  DS 1		;frequency: DS 4		;actually a UINT32 Valuebufindex:  DS 1		;outbuffer: DS 16   T0Vect:	   DS 2 	;for saving the actual Irq VectT2Vect:	   DS 2		;STACK:	   DS 1		;stack starts here;**************************************************************BSEG  at BitVar		;place first bit here bReady:    dBit 1	;1:  ready for output;Code starts here;*****************************************************************CSEG at Prog			;opens the code segmentORG Prog + 0         LJMP   Init     	;should be placed here CSEG at PROG +0Bh		;Timer 0 overflow interrupt	PUSH  T0Vect		;Attention this is very tricky	PUSH  T0Vect+1	RET			;ret starts the IRQ CSEG at PROG+02Bh 		;Timer 2 overflow interrupt         PUSH  T2Vect 		;both Functions need 6 clocks	PUSH  T2Vect+1		;to start the IRQ	RETCSEG at PROG +100hInit:	CLR	EAL;	SETB 	RAM_A16 		;Make bit A16 of 128K Ram "high".;	CLR 	EEP_ENA			;Disable EEPROM.;	CLR     P5.1	MOV	SP,#STACK-1		;init the stack V0.1 STACK-1;since we have a stack now Rest should be placed in Sub routinesMain:;	CALL	INIT_LCD		;make all neccesarry LCD Inits;	JB      bMode,Main1             ;0 Frequ Mode 1 Period Mode 	CALL    InitIrqVectorsFreq	;Init Freq Irq Vectors	CALL    InitT0Freq		;T0 to Timer Frequency Mode	Call    InitT2Freq 		;T2 to Counter Mode        SJMP	Main2Main1:;	CALL    InitIrqVectorsPeriod;       CALL    InitT0Period;	CALL    InitT2PeriodMain2:		CLR	bReady		SETB	TR0			;both Timers are runing	SETB	T2I0	SETB	EALMainLoop:	JNB	bReady,$		;wait for Result	CALL	HandleFreqOutput	JMP	MainLoop;DispalyHandler when executing Frequency HandleFreqOutput:	CLR	A	MOV	TL0,A	MOV	TH0,A			;clear the counter	MOV	Overflow,A	MOV	GateTime,#20		MOV	TL2,   # Low (-49999)   ;V0.2 new ReloadValue -49999   	MOV     TH2,   # High(-49999)	SETB	T2I0	SETB	TR0			;restart both Timers	CLR	bReady	;now you have 1 s to format the output as you want;you will need some 32 Bit Division Functions;here a short example for doing hex out to a buffer	MOV	bufindex,#OutBuffer	CALL	BufHexOut	RET;*****************************************************************************	;subroutinesInitT0Freq:	MOV 	A, TMOD 		;initialize Timer 0 to Counter mode	ANL 	A, # T0_MASK		;change only T0	ORL 	A, # 5			;Mode 1 16 Bit Counter	MOV	TMOD,A	CLR	A	MOV	TL0, A	MOV	TH0, A			;Timer0 to zero	SETB	ET0			;allow T0 Irq	RETInitT2Freq:	MOV	GateTime,# 20 	MOV     T2CON,#00010000b	;0001 0000  	MOV	CRCL, # Low (-49999)	;0xAF;  //  50 ms Reload  3CAF = -50000  	MOV	CRCH, # High(-49999)	;0x3C;  	MOV	TL2,  # Low (-49999)	;V0.2 new ReloadValue -49999   	MOV     TH2,  # High(-49999)       	SETB	ET2  			;Interupt Timer 2 enable;	MOV	IP,    # 20h		;T2 (GateTime) high priority this should be checked  	RET				;for 80c535;*******************************************************************************;IRQ Functions for frequency measurement onlyInitIrqVectorsFreq:	MOV    T0Vect+0,# Low (T0FreqIrq)	;T0 for Frequ Counter Mode	MOV    T0Vect+1,# High(T0FreqIrq)	MOV    T2Vect+0,# Low (T2FreqIrq)	;T2 for Frequ Counter Mode	MOV    T2Vect+1,# High(T2FreqIrq)        RETT0FreqIrq:	INC     OverFlow			;count the overflows	RETIT2FreqIrq:	PUSH   PSW	PUSH   ACC		DEC    GateTime	MOV    A,GateTime	JNZ    T2FreqIrq1		CLR    TR0			;stop counter	CLR    T2I0			;stop timer we have the freq	SETB   bReady			;indicate valid freq value	MOV    frequency+0, #0		;MSB always zero 	MOV    Frequency+1, Overflow	;MSB-1 overflow	MOV    frequency+2, TH0		;MSB-2	MOV    frequency+3, TL0		;LSBT2FreqIrq1:        CLR    TF2			;clear always the IRQ Flag	POP    ACC	POP    PSW	RETI;example for doing nothing at IRQsNoVectors:	MOV    T0Vect+0,# Low (DoNothingIrq)	;	MOV    T0Vect+1,# High(DoNothingIrq)	MOV    T2Vect+0,# Low (DoNothingIrq)	;	MOV    T2Vect+1,# High(DoNothingIrq)        RETDoNothingIrq:	RETI;V0.2 	;some example Output Functions;sends 'f=0xxxxxh Hz' to OutBufferBufHexOut:	MOV    A,#'f'			CALL   BufWriteChar	MOV    A,#'='			CALL   BufWriteChar        MOV    A,frequency+1	;LSB+2        CALL   BufWrite2Digits                MOV    A,frequency+2	;Lsb +1        CALL   BufWrite2Digits                MOV    A,frequency+3    ;LSB        CALL   BufWrite2Digits	MOV    A,#'h'			CALL   BufWriteChar	MOV    A,#' '			CALL   BufWriteChar	MOV    A,#'H'	CALL   BufWriteChar		MOV    A,#'z'	CALL   BufWriteChar	MOV    A,#0		;end of buffer	CALL   BufWriteChar        		RET	;sends ACC as 2 Hex Digits to Buffer 	BufWrite2Digits:	PUSH   ACC	SWAP   A	CALL   Bin2Hex	CALL   BufWriteChar		POP    ACC	CALL   Bin2Hex;	CALL   BufWriteChar;	RET;Buffer Output FunctionBufWriteChar:;	PUSH	AR0        MOV	R0,bufindex        MOV	@R0,A        INC	R0        MOV	bufindex,R0;       POP	AR0	RET        	;Return Ascii Equivalent  of ACC 0..3Bin2Hex:;       PUSH	DPH;       PUSH	DPL	MOV	DPTR, # AsciiTab	ANL	A,# 0Fh	MOVC	A,@A+DPTR	;	POP	DPL	;	POP     DPH	RET	        	  	AsciiTab:	DB     '0'	DB     '1'	DB     '2'	DB     '3'   		DB     '4'	DB     '5'	DB     '6'	DB     '7'   		DB     '8'	DB     '9'	DB     'A'	DB     'B'   		DB     'C'	DB     'D'	DB     'E'	DB     'F'   	END

⌨️ 快捷键说明

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