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 + -
显示快捷键?