📄 counter.lst
字号:
00C8 2D13 MOV R17,R3
00C9 2D24 MOV R18,R4
00CA 2D35 MOV R19,R5
00CB D184 RCALL lsl32
00CC 2F40 MOV R20,R16
00CD 2F51 MOV R21,R17
(0173)
(0174) // one loop takes 5 cpu cycles
(0175) for (i=0; i < delay_loops; i++) {};
00CE 2766 CLR R22
00CF 2777 CLR R23
00D0 C002 RJMP 0x00D3
00D1 5F6F SUBI R22,0xFF
00D2 4F7F SBCI R23,0xFF
00D3 1764 CP R22,R20
00D4 0775 CPC R23,R21
00D5 F3D8 BCS 0x00D1
(0176) }
00D6 D15D RCALL pop_gset2
00D7 9508 RET
(0177)
(0178)
(0179) //
(0180) // read 16 bit counter value
(0181) //
(0182) unsigned int read_counters(void)
(0183) {
(0184) unsigned int counter_value;
(0185)
(0186) // stop display refresh while reading counters
(0187) cli();
_read_counters:
counter_value --> R16
00D8 94F8 BCLR 7
(0188)
(0189) // turn off all segments
(0190) outp(inp(PORTB) | 0x07, PORTB);
00D9 B388 IN R24,0x18
00DA 6087 ORI R24,7
00DB BB88 OUT 0x18,R24
(0191)
(0192) // set high B port to input
(0193) outp(0x0f,DDRB);
00DC E08F LDI R24,0xF
00DD BB87 OUT 0x17,R24
(0194)
(0195) // set low D port to input
(0196) outp(0xf0,DDRD);
00DE EF80 LDI R24,0xF0
00DF BB81 OUT 0x11,R24
(0197)
(0198)
(0199) // activate OE_H
(0200) cbi(PORTD,OE_H);
00E0 9895 CBI 0x12,5
(0201) asm ("nop");
00E1 0000 NOP
(0202) sbi(PORTD,OE_H); // one pulse to latch count
00E2 9A95 SBI 0x12,5
(0203) asm("nop");
00E3 0000 NOP
(0204) cbi(PORTD,OE_H);
00E4 9895 CBI 0x12,5
(0205) asm ("nop");
00E5 0000 NOP
(0206)
(0207) // read hi
(0208) counter_value = (inp(PINB) & 0xf0);
00E6 B306 IN R16,0x16
00E7 2711 CLR R17
00E8 7F00 ANDI R16,0xF0
00E9 7010 ANDI R17,0
(0209) // read lo
(0210) counter_value |= (inp(PIND) & 0x0f);
00EA B380 IN R24,0x10
00EB 2799 CLR R25
00EC 708F ANDI R24,0xF
00ED 7090 ANDI R25,0
00EE 2B08 OR R16,R24
00EF 2B19 OR R17,R25
(0211) // deactivate OE_H
(0212) sbi(PORTD,OE_H);
00F0 9A95 SBI 0x12,5
(0213)
(0214)
(0215) counter_value <<= 8;
00F1 2F10 MOV R17,R16
00F2 2700 CLR R16
(0216)
(0217)
(0218) // activate OE_L
(0219) cbi(PORTD,OE_L);
00F3 9894 CBI 0x12,4
(0220) asm("nop");
00F4 0000 NOP
(0221) sbi(PORTD,OE_L); // one pulse to latch count
00F5 9A94 SBI 0x12,4
(0222) asm ("nop");
00F6 0000 NOP
(0223) cbi(PORTD,OE_L);
00F7 9894 CBI 0x12,4
(0224) asm ("nop");
00F8 0000 NOP
(0225)
(0226) // read hi
(0227) counter_value |= (inp(PINB) & 0xf0);
00F9 B386 IN R24,0x16
00FA 2799 CLR R25
00FB 7F80 ANDI R24,0xF0
00FC 7090 ANDI R25,0
00FD 2B08 OR R16,R24
00FE 2B19 OR R17,R25
(0228) // read lo
(0229) counter_value |= (inp(PIND) & 0x0f);
00FF B380 IN R24,0x10
0100 2799 CLR R25
0101 708F ANDI R24,0xF
0102 7090 ANDI R25,0
0103 2B08 OR R16,R24
0104 2B19 OR R17,R25
(0230) // deactivate OE_L
(0231) sbi(PORTD,OE_L);
0105 9A94 SBI 0x12,4
(0232)
(0233)
(0234) // set B port back to output
(0235) outp(0xff,DDRB);
0106 EF8F LDI R24,0xFF
0107 BB87 OUT 0x17,R24
(0236)
(0237) // set D port back to output
(0238) outp(0xff,DDRD);
0108 BB81 OUT 0x11,R24
(0239)
(0240) // re-enable display refresh
(0241) sei();
0109 9478 BSET 7
(0242) return counter_value;
010A 9508 RET
(0243) }
(0244)
(0245)
(0246) //
(0247) // do a capture
(0248) //
(0249) void capture(unsigned int compare)
(0250) {
(0251)
(0252) cbi(PORTD,CLEAR); // clear external counters
_capture:
compare --> R16
010B 9896 CBI 0x12,6
(0253) asm ("nop");
010C 0000 NOP
(0254) sbi(PORTD,CLEAR); // remove clear
010D 9A96 SBI 0x12,6
(0255)
(0256) outp(0,TCNT1H); // clear timer
010E 2422 CLR R2
010F BC2D OUT 0x2D,R2
(0257) outp(0,TCNT1L);
0110 BC2C OUT 0x2C,R2
(0258)
(0259) outp(compare >> 8,OCR1H); // set the compare1 register to the
0111 2E20 MOV R2,R16
0112 2E31 MOV R3,R17
0113 2C23 MOV R2,R3
0114 2433 CLR R3
0115 BC2B OUT 0x2B,R2
(0260) outp(compare,OCR1L); // required value
0116 BD0A OUT 0x2A,R16
(0261)
(0262) outp(0x40,TCCR1A); // set OC1 bit to toggle on compare
0117 E480 LDI R24,0x40
0118 BD8F OUT 0x2F,R24
(0263)
(0264) sbi(TIFR,OCF1A); // clear overflov/compare flags
0119 B788 IN R24,0x38
011A 6480 ORI R24,0x40
011B BF88 OUT 0x38,R24
(0265)
(0266) if (compare == 15625)
011C 3009 CPI R16,0x9
011D E3ED LDI R30,0x3D
011E 071E CPC R17,R30
011F F419 BNE 0x0123
(0267) outp(0x0C,TCCR1B); // start with fClk/256 (15625 Hz) and compare clear
0120 E08C LDI R24,0xC
0121 BD8E OUT 0x2E,R24
0122 C002 RJMP 0x0125
(0268) else
(0269) outp(0x0A,TCCR1B); // start with fClk/8 (500 kHz) and compare clear
0123 E08A LDI R24,0xA
0124 BD8E OUT 0x2E,R24
(0270)
(0271) while ( ! (unsigned char) ( inp(TIFR) & BV(OCF1A)) ); // wait for bit
0125 B788 IN R24,0x38
0126 2799 CLR R25
0127 7480 ANDI R24,0x40
0128 7090 ANDI R25,0
0129 2388 TST R24
012A F3D1 BEQ 0x0125
(0272) sbi(TIFR,OCF1A); // clear flags
012B B788 IN R24,0x38
012C 6480 ORI R24,0x40
012D BF88 OUT 0x38,R24
(0273)
(0274) // counter input now enabled
(0275) // for the specified time
(0276)
(0277) while ( ! (unsigned char) ( inp(TIFR) & BV(OCF1A)) ); // wait again for bit
012E B788 IN R24,0x38
012F 2799 CLR R25
0130 7480 ANDI R24,0x40
0131 7090 ANDI R25,0
0132 2388 TST R24
0133 F3D1 BEQ 0x012E
(0278)
(0279) outp(0,TCCR1B); // stop timer
0134 2422 CLR R2
0135 BC2E OUT 0x2E,R2
(0280)
(0281) // counter input disabled
(0282) }
0136 9508 RET
_main:
ms --> R10
dp --> Y+6
i --> R14
j --> R12
lv --> Y+0
count --> Y+4
0137 9727 SBIW R28,7
(0283)
(0284)
(0285)
(0286) /****************************************************************************/
(0287) /* main *******************************************************************/
(0288) /****************************************************************************/
(0289)
(0290) void main(void)
(0291) {
(0292) int i,j;
(0293) unsigned char dp,ms;
(0294) unsigned long lv;
(0295) unsigned int count;
(0296)
(0297) // set all PORTB as outputs
(0298) outp(0xff,DDRB);
0138 EF8F LDI R24,0xFF
0139 BB87 OUT 0x17,R24
(0299)
(0300) // set all bits hi
(0301) outp(0xff,PORTB);
013A BB88 OUT 0x18,R24
(0302)
(0303)
(0304) // set all PORTD as outputs
(0305) outp(0xff,DDRD);
013B BB81 OUT 0x11,R24
(0306)
(0307) // set all bits hi
(0308) outp(0xff,PORTD);
013C BB82 OUT 0x12,R24
(0309)
(0310)
(0311) // setup timer 0
(0312)
(0313) outp(0x03, TCCR0); // prescaler f/64 tPeriod = 1/62500 Hz -> 16 uS
013D E083 LDI R24,3
013E BF83 OUT 0x33,R24
(0314)
(0315)
(0316) // enable timer 0 interrupt
(0317) sbi(TIMSK, TOIE0);
013F B789 IN R24,0x39
0140 6082 ORI R24,2
0141 BF89 OUT 0x39,R24
(0318)
(0319) // start things running
(0320) sei();
0142 9478 BSET 7
(0321)
(0322)
(0323) /*
(0324) compare values at fclk/8 (500 kHz, 2 uS) :
(0325)
(0326) 500 = 1 mS
(0327) 5000 = 10 mS
(0328) 50000 = 100 mS
(0329)
(0330) at fclk/256 (15.625 kHz, 64 uS) :
(0331)
(0332) 15625 = 1 S
(0333)
(0334) */
(0335)
(0336)
(0337) // first make sure the OC1 pin is in a controlled state
(0338) // we want it to be HIGH initially
(0339)
(0340) // There's no way to set/clear it directly, but it can be forced to
(0341) // a defined state by a compare match, se by setting a low compare value
(0342) // and start the timer, it can be forced into set state
(0343)
(0344)
(0345) outp(0,TCNT1H); // clear timer
0143 2422 CLR R2
0144 BC2D OUT 0x2D,R2
(0346) outp(0,TCNT1L);
0145 BC2C OUT 0x2C,R2
(0347)
(0348) outp(0,OCR1H); // set compare to 200
0146 BC2B OUT 0x2B,R2
(0349) outp(200,OCR1L);
0147 EC88 LDI R24,0xC8
0148 BD8A OUT 0x2A,R24
(0350)
(0351) outp(0xC0,TCCR1A); // set OC1 bit to set on compare
0149 EC80 LDI R24,0xC0
014A BD8F OUT 0x2F,R24
(0352)
(0353) // start timer and wait for one compare match
(0354) outp(0x01,TCCR1B); // start with fClk/1 (4 MHz)
014B E081 LDI R24,1
014C BD8E OUT 0x2E,R24
(0355) while ( ! (unsigned char) ( inp(TIFR) & BV(OCF1A)) ); // wait for bit
014D B788 IN R24,0x38
014E 2799 CLR R25
014F 7480 ANDI R24,0x40
0150 7090 ANDI R25,0
0151 2388 TST R24
0152 F3D1 BEQ 0x014D
(0356) sbi(TIFR,OCF1A); // clear flags
0153 B788 IN R24,0x38
0154 6480 ORI R24,0x40
0155 BF88 OUT 0x38,R24
(0357)
(0358) outp(0,TCCR1B); // stop timer
0156 2422 CLR R2
0157 BC2E OUT 0x2E,R2
0158 C0A4 RJMP 0x01FD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -