📄 counter.s
字号:
.module counter.c
.area data(ram, con, rel)
_digits::
.blkb 2
.area idata
.byte 63,6
.area data(ram, con, rel)
.blkb 2
.area idata
.byte 91,'O
.area data(ram, con, rel)
.blkb 2
.area idata
.byte 'f,'m
.area data(ram, con, rel)
.blkb 2
.area idata
.byte 125,7
.area data(ram, con, rel)
.blkb 2
.area idata
.byte 127,'o
.area data(ram, con, rel)
.blkb 2
.area idata
.byte 1,64
.area data(ram, con, rel)
.blkb 1
.area idata
.byte 8
.area data(ram, con, rel)
.dbfile D:\频率计\counter.c
.dbsym e digits _digits A[13:13]c
_active_led::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile D:\频率计\counter.c
.dbsym e active_led _active_led c
_led_value::
.blkb 4
.area idata
.word 0,0
.area data(ram, con, rel)
.dbfile D:\频率计\counter.c
.dbsym e led_value _led_value l
_decimal_point::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile D:\频率计\counter.c
.dbsym e decimal_point _decimal_point c
_mode_setting::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile D:\频率计\counter.c
.dbsym e mode_setting _mode_setting c
.area vector(rom, abs)
.org 12
rjmp _timer0_ovf_isr
.area data(ram, con, rel)
.dbfile D:\频率计\counter.c
.area text(rom, con, rel)
.dbfile D:\频率计\counter.c
.dbfunc e timer0_ovf_isr _timer0_ovf_isr fV
; a -> R22
; b -> R20
.even
_timer0_ovf_isr::
st -y,R2
st -y,R3
st -y,R4
st -y,R5
st -y,R16
st -y,R17
st -y,R18
st -y,R19
st -y,R24
st -y,R25
st -y,R26
st -y,R27
st -y,R30
st -y,R31
in R2,0x3f
st -y,R2
rcall push_gset2
.dbline -1
.dbline 122
;
;
; /*
; Jesper Hansen <jesperh@telia.com>
;
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version 2
; of the License, or (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software Foundation,
; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
;
;
;
; Project: CounterMeasures
;
;
; 40 MHz Frequency Counter
; ------------------------
;
; CPU : At90S2313
;
; Date: 2001-03-02
;
; Author : Jesper Hansen
;
;
;
;
;
; Current consumption about 40-45 mA.
;
; Measures to > 50 MHz
;
;
; */
;
;
; #include <io2313v.h>
; #include <macros.h>
; #include "counter.h"
;
;
; // PORT D bits
;
; // al counter control bits active low
;
; #define CLEAR PD6
; #define OE_H PD5
; #define OE_L PD4
;
; // PD3..0 is lower data bus
;
;
; // PORT B
;
; // PB7..4 is high data bus
; // PB3 is OC1 output
; // PB2..0 is 74HC138 select bits for display common
;
;
;
; // constants/macros
; #define F_CPU 4000000 // 4MHz processor
; #define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond
;
;
; // display data
;
; #define SEG_a 0x01
; #define SEG_b 0x02
; #define SEG_c 0x04
; #define SEG_d 0x08
; #define SEG_e 0x10
; #define SEG_f 0x20
; #define SEG_g 0x40
; #define SEG_dot 0x80
;
;
; unsigned char digits[] = {
; (SEG_a|SEG_b|SEG_c|SEG_d|SEG_e|SEG_f), // 0
; (SEG_b|SEG_c), // 1
; (SEG_a|SEG_b|SEG_d|SEG_e|SEG_g), // 2
; (SEG_a|SEG_b|SEG_c|SEG_d|SEG_g), // 3
; (SEG_b|SEG_c|SEG_c|SEG_f|SEG_g), // 4
; (SEG_a|SEG_c|SEG_d|SEG_f|SEG_g), // 5
; (SEG_a|SEG_c|SEG_d|SEG_e|SEG_f|SEG_g), // 6
; (SEG_a|SEG_b|SEG_c), // 7
; (SEG_a|SEG_b|SEG_c|SEG_d|SEG_e|SEG_f|SEG_g), // 8
; (SEG_a|SEG_b|SEG_c|SEG_d|SEG_f|SEG_g), // 9
;
; (SEG_a), // mode 0 indicator (Hz)
; (SEG_g), // mode 1 indicator (kHz)
; (SEG_d), // mode 2 indicator (MHz)
; };
;
;
; /****************************************************************************/
;
;
; // timer 0 interrupt handles multiplex and refresh of the displays
; // timer is clocked at 62500 Hz
;
; #define TI0_L (256-125) // 500 Hz -> 2 mS
;
; volatile unsigned char active_led = 0;
;
; volatile unsigned long led_value = 0; // four BCD nibbles
; volatile unsigned char decimal_point = 0;
; volatile unsigned char mode_setting = 0;
;
;
; #pragma interrupt_handler timer0_ovf_isr:7
; void timer0_ovf_isr(void) //timer 0 overflow
; {
.dbline 126
; unsigned char a,b;
;
; // reload timer
; outp(TI0_L, TCNT0);
ldi R24,131
out 0x32,R24
.dbline 129
;
; // all displays off by setting all commons high
; outp(inp(PORTB) | 0x07, PORTB);
in R24,0x18
ori R24,7
out 0x18,R24
.dbline 131
;
; if (active_led == 5)
lds R24,_active_led
cpi R24,5
brne L2
.dbline 132
; {
.dbline 133
; b = digits[10 + mode_setting];
ldi R24,<_digits+10
ldi R25,>_digits+10
lds R30,_mode_setting
clr R31
add R30,R24
adc R31,R25
ldd R20,z+0
.dbline 134
; }
rjmp L3
L2:
.dbline 136
; else
; {
.dbline 137
; a = led_value >> (( 4 - active_led ) * 4);
lds R2,_active_led
clr R3
ldi R24,4
ldi R25,0
sub R24,R2
sbc R25,R3
lsl R24
rol R25
lsl R24
rol R25
lds R4,_led_value+2
lds R5,_led_value+2+1
lds R2,_led_value
lds R3,_led_value+1
st -y,R24
mov R16,R2
mov R17,R3
mov R18,R4
mov R19,R5
rcall lsr32
mov R22,R16
.dbline 139
;
; b = digits[a & 0x0f];
ldi R24,<_digits
ldi R25,>_digits
mov R30,R22
clr R31
andi R30,15
andi R31,0
add R30,R24
adc R31,R25
ldd R20,z+0
.dbline 141
;
; if (decimal_point == (4 - active_led) )
lds R2,_active_led
ldi R24,4
sub R24,R2
lds R2,_decimal_point
cp R2,R24
brne L5
.dbline 142
; b |= SEG_dot;
ori R20,128
L5:
.dbline 143
; }
L3:
.dbline 145
;
; a = b & 0xf0; // hi part
mov R22,R20
andi R22,240
.dbline 146
; b = b & 0x0f; // lo part
andi R20,15
.dbline 149
;
; // set digit data on port
; outp( (inp(PORTB) & 0x0f) | a, PORTB); // high part
in R24,0x18
andi R24,15
or R24,R22
out 0x18,R24
.dbline 150
; outp( (inp(PORTD) & 0xf0) | b, PORTD); // low part
in R24,0x12
andi R24,240
or R24,R20
out 0x12,R24
.dbline 153
;
; // set common
; outp( (inp(PORTB) & 0xf8) | active_led, PORTB);
lds R2,_active_led
in R24,0x18
andi R24,248
or R24,R2
out 0x18,R24
.dbline 155
;
; active_led = (active_led+1) % 6;
ldi R17,6
lds R16,_active_led
subi R16,255 ; addi 1
rcall mod8u
sts _active_led,R16
.dbline -2
.dbline 156
; }
L1:
rcall pop_gset2
ld R2,y+
out 0x3f,R2
ld R31,y+
ld R30,y+
ld R27,y+
ld R26,y+
ld R25,y+
ld R24,y+
ld R19,y+
ld R18,y+
ld R17,y+
ld R16,y+
ld R5,y+
ld R4,y+
ld R3,y+
ld R2,y+
.dbline 0 ; func end
reti
.dbsym r a 22 c
.dbsym r b 20 c
.dbend
.dbfunc e delay _delay fV
; delay_loops -> R20,R21
; i -> R22,R23
; us -> R20,R21
.even
_delay::
rcall push_gset2
mov R20,R16
mov R21,R17
.dbline -1
.dbline 168
;
;
;
;
;
; /****************************************************************************/
; /* helpers ****************************************************************/
; /****************************************************************************/
;
;
; void delay(unsigned short us)
; {
.dbline 172
; unsigned short delay_loops;
; register unsigned short i;
;
; delay_loops = (us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty)
ldi R18,5
ldi R19,0
mov R16,R20
mov R17,R21
subi R16,253 ; offset = 3
sbci R17,255
rcall div16u
mov R2,R16
mov R3,R17
clr R4
clr R5
ldi R24,2
ldi R25,0
st -y,R24
mov R16,R2
mov R17,R3
mov R18,R4
mov R19,R5
rcall lsl32
mov R20,R16
mov R21,R17
.dbline 175
clr R22
clr R23
rjmp L11
L8:
.dbline 175
.dbline 175
L9:
.dbline 175
subi R22,255 ; offset = 1
sbci R23,255
L11:
.dbline 175
;
; // one loop takes 5 cpu cycles
; for (i=0; i < delay_loops; i++) {};
cp R22,R20
cpc R23,R21
brlo L8
.dbline 175
.dbline -2
.dbline 176
; }
L7:
rcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r delay_loops 20 s
.dbsym r i 22 s
.dbsym r us 20 s
.dbend
.dbfunc e read_counters _read_counters fi
; counter_value -> R16,R17
.even
_read_counters::
.dbline -1
.dbline 183
;
;
; //
; // read 16 bit counter value
; //
; unsigned int read_counters(void)
; {
.dbline 187
; unsigned int counter_value;
;
; // stop display refresh while reading counters
; cli();
cli
.dbline 190
;
; // turn off all segments
; outp(inp(PORTB) | 0x07, PORTB);
in R24,0x18
ori R24,7
out 0x18,R24
.dbline 193
;
; // set high B port to input
; outp(0x0f,DDRB);
ldi R24,15
out 0x17,R24
.dbline 196
;
; // set low D port to input
; outp(0xf0,DDRD);
ldi R24,240
out 0x11,R24
.dbline 200
;
;
; // activate OE_H
; cbi(PORTD,OE_H);
cbi 0x12,5
.dbline 201
; asm ("nop");
nop
.dbline 202
; sbi(PORTD,OE_H); // one pulse to latch count
sbi 0x12,5
.dbline 203
; asm("nop");
nop
.dbline 204
; cbi(PORTD,OE_H);
cbi 0x12,5
.dbline 205
; asm ("nop");
nop
.dbline 208
;
; // read hi
; counter_value = (inp(PINB) & 0xf0);
in R16,0x16
clr R17
andi R16,240
andi R17,0
.dbline 210
; // read lo
; counter_value |= (inp(PIND) & 0x0f);
in R24,0x10
clr R25
andi R24,15
andi R25,0
or R16,R24
or R17,R25
.dbline 212
; // deactivate OE_H
; sbi(PORTD,OE_H);
sbi 0x12,5
.dbline 215
;
;
; counter_value <<= 8;
mov R17,R16
clr R16
.dbline 219
;
;
; // activate OE_L
; cbi(PORTD,OE_L);
cbi 0x12,4
.dbline 220
; asm("nop");
nop
.dbline 221
; sbi(PORTD,OE_L); // one pulse to latch count
sbi 0x12,4
.dbline 222
; asm ("nop");
nop
.dbline 223
; cbi(PORTD,OE_L);
cbi 0x12,4
.dbline 224
; asm ("nop");
nop
.dbline 227
;
; // read hi
; counter_value |= (inp(PINB) & 0xf0);
in R24,0x16
clr R25
andi R24,240
andi R25,0
or R16,R24
or R17,R25
.dbline 229
; // read lo
; counter_value |= (inp(PIND) & 0x0f);
in R24,0x10
clr R25
andi R24,15
andi R25,0
or R16,R24
or R17,R25
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -