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

📄 spokepov.lss

📁 旋转16个LED灯控制程序
💻 LSS
📖 第 1 页 / 共 5 页
字号:

spokepov.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000007da  00000000  00000000  00000094  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000002  00800060  000007da  0000086e  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000013  00800062  00800062  00000870  2**0
                  ALLOC
  3 .noinit       00000000  00800075  00800075  00000870  2**0
                  CONTENTS
  4 .eeprom       00000000  00810000  00810000  00000870  2**0
                  CONTENTS
  5 .stab         00000354  00000000  00000000  00000870  2**2
                  CONTENTS, READONLY, DEBUGGING
  6 .stabstr      00000084  00000000  00000000  00000bc4  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_aranges 00000028  00000000  00000000  00000c48  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_pubnames 000001f6  00000000  00000000  00000c70  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_info   000005d8  00000000  00000000  00000e66  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_abbrev 000001f2  00000000  00000000  0000143e  2**0
                  CONTENTS, READONLY, DEBUGGING
 11 .debug_line   00000767  00000000  00000000  00001630  2**0
                  CONTENTS, READONLY, DEBUGGING
 12 .debug_str    00000263  00000000  00000000  00001d97  2**0
                  CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:

00000000 <__vectors>:
   0:	12 c0       	rjmp	.+36     	; 0x26 <__ctors_end>
   2:	60 c0       	rjmp	.+192    	; 0xc4 <__vector_1>
   4:	17 c1       	rjmp	.+558    	; 0x234 <__vector_2>
   6:	28 c0       	rjmp	.+80     	; 0x58 <__bad_interrupt>
   8:	ab c1       	rjmp	.+854    	; 0x360 <__vector_4>
   a:	26 c0       	rjmp	.+76     	; 0x58 <__bad_interrupt>
   c:	26 c0       	rjmp	.+76     	; 0x5a <__vector_6>
   e:	24 c0       	rjmp	.+72     	; 0x58 <__bad_interrupt>
  10:	23 c0       	rjmp	.+70     	; 0x58 <__bad_interrupt>
  12:	22 c0       	rjmp	.+68     	; 0x58 <__bad_interrupt>
  14:	21 c0       	rjmp	.+66     	; 0x58 <__bad_interrupt>
  16:	20 c0       	rjmp	.+64     	; 0x58 <__bad_interrupt>
  18:	1f c0       	rjmp	.+62     	; 0x58 <__bad_interrupt>
  1a:	1e c0       	rjmp	.+60     	; 0x58 <__bad_interrupt>
  1c:	1d c0       	rjmp	.+58     	; 0x58 <__bad_interrupt>
  1e:	1c c0       	rjmp	.+56     	; 0x58 <__bad_interrupt>
  20:	1b c0       	rjmp	.+54     	; 0x58 <__bad_interrupt>
  22:	1a c0       	rjmp	.+52     	; 0x58 <__bad_interrupt>
  24:	19 c0       	rjmp	.+50     	; 0x58 <__bad_interrupt>

00000026 <__ctors_end>:
  26:	11 24       	eor	r1, r1
  28:	1f be       	out	0x3f, r1	; 63
  2a:	cf ed       	ldi	r28, 0xDF	; 223
  2c:	cd bf       	out	0x3d, r28	; 61

0000002e <__do_copy_data>:
  2e:	10 e0       	ldi	r17, 0x00	; 0
  30:	a0 e6       	ldi	r26, 0x60	; 96
  32:	b0 e0       	ldi	r27, 0x00	; 0
  34:	ea ed       	ldi	r30, 0xDA	; 218
  36:	f7 e0       	ldi	r31, 0x07	; 7
  38:	03 c0       	rjmp	.+6      	; 0x40 <.do_copy_data_start>

0000003a <.do_copy_data_loop>:
  3a:	c8 95       	lpm
  3c:	31 96       	adiw	r30, 0x01	; 1
  3e:	0d 92       	st	X+, r0

00000040 <.do_copy_data_start>:
  40:	a2 36       	cpi	r26, 0x62	; 98
  42:	b1 07       	cpc	r27, r17
  44:	d1 f7       	brne	.-12     	; 0x3a <.do_copy_data_loop>

00000046 <__do_clear_bss>:
  46:	10 e0       	ldi	r17, 0x00	; 0
  48:	a2 e6       	ldi	r26, 0x62	; 98
  4a:	b0 e0       	ldi	r27, 0x00	; 0
  4c:	01 c0       	rjmp	.+2      	; 0x50 <.do_clear_bss_start>

0000004e <.do_clear_bss_loop>:
  4e:	1d 92       	st	X+, r1

00000050 <.do_clear_bss_start>:
  50:	a5 37       	cpi	r26, 0x75	; 117
  52:	b1 07       	cpc	r27, r17
  54:	e1 f7       	brne	.-8      	; 0x4e <.do_clear_bss_loop>
  56:	5b c2       	rjmp	.+1206   	; 0x50e <main>

00000058 <__bad_interrupt>:
  58:	d3 cf       	rjmp	.-90     	; 0x0 <__vectors>

0000005a <__vector_6>:
// anything.  Is this vestigial code from when you were using
// Pin Change Interrupts?  Or is it debugger code so you
// can monitor the pins and tell when something happens.

SIGNAL (SIG_TIMER0_OVF) {
  5a:	1f 92       	push	r1
  5c:	0f 92       	push	r0
  5e:	0f b6       	in	r0, 0x3f	; 63
  60:	0f 92       	push	r0
  62:	11 24       	eor	r1, r1
  64:	2f 93       	push	r18
  66:	8f 93       	push	r24
  68:	9f 93       	push	r25

  PORTB |= 0x1;
  6a:	c0 9a       	sbi	0x18, 0	; 24

  if (hall_debounce != 0xFF)
  6c:	80 91 69 00 	lds	r24, 0x0069
  70:	8f 3f       	cpi	r24, 0xFF	; 255
  72:	29 f0       	breq	.+10     	; 0x7e <__vector_6+0x24>
    hall_debounce++;
  74:	80 91 69 00 	lds	r24, 0x0069
  78:	8f 5f       	subi	r24, 0xFF	; 255
  7a:	80 93 69 00 	sts	0x0069, r24
  
  if (sensor_timer != 0xFFFF)
  7e:	80 91 6a 00 	lds	r24, 0x006A
  82:	90 91 6b 00 	lds	r25, 0x006B
  86:	8f 5f       	subi	r24, 0xFF	; 255
  88:	9f 4f       	sbci	r25, 0xFF	; 255
  8a:	49 f0       	breq	.+18     	; 0x9e <__vector_6+0x44>
    sensor_timer++;
  8c:	80 91 6a 00 	lds	r24, 0x006A
  90:	90 91 6b 00 	lds	r25, 0x006B
  94:	01 96       	adiw	r24, 0x01	; 1
  96:	90 93 6b 00 	sts	0x006B, r25
  9a:	80 93 6a 00 	sts	0x006A, r24

  PORTB &= ~0x1;
  9e:	c0 98       	cbi	0x18, 0	; 24
  a0:	9f 91       	pop	r25
  a2:	8f 91       	pop	r24
  a4:	2f 91       	pop	r18
  a6:	0f 90       	pop	r0
  a8:	0f be       	out	0x3f, r0	; 63
  aa:	0f 90       	pop	r0
  ac:	1f 90       	pop	r1
  ae:	18 95       	reti

000000b0 <delay_ms>:

}

// The current EEPROM address gets incremented by 4 (the number of
// bytes in a pixel line) each time the pixel timer fires.  This
// steps us through the bitmap we need to display.

volatile uint16_t curr_eeprom_addr = 0;

// This routine gets called every time the pixel timer runs down;
// in other words, once per "scan line", 256 times per revolution
// of the SpokePOV.  Its purpose is to update the LEDs.

SIGNAL (SIG_TIMER1_COMPA) {

  uint16_t eepromaddr;				// local copy of the eprom address 

  // When an interrupt routine is called, interrupts are disabled.
  // but it's important to let other interrupts interrupt us, so
  // they need to be re-enabled.
	
  sei();

  PORTB |= 0x2;

  // We need a local copy of the EEPROM address because we
  // muck with it a bit.
  
  eepromaddr = curr_eeprom_addr;

  // If it has been less than STANDBY_TIMEOUT seconds since the last time we
  // got a Hall Effect sensor update, then proceed as normal and
  // update the LEDs
  
  // QUESTION: what is F_CPU?
  
  if (sensor_timer < ((F_CPU/NUM_PIXELS)/256 * STANDBY_TIMEOUT)) {    
    
    PORTA |= 0x1;
    
    // Since cur_eeprom_addr can go past a 1K boundary depending on
    // the rotation offset, we need to modulo it to a 0-1023 value.
    
    eepromaddr %= NUM_PIXELS * 4;
    
    // Then the bytes we want to plonk into the LEDs will be this
    // address, plus the animation offset (0,1024,2048 or 3072).
    
    // This routine is in eeprom.c.  As far as I can tell, it's doing
    // a really cute trick, causing the EEPROM to send the desired
    // pixel bytes to both the ATMEL and the pixel shift registers
    // at the same time.
    
    spieeprom_read_into_leds(eepromaddr + anim_eeprom_offset, FRONT);
    
    // If we are mirroring the image onto the backside LEDs, then we
    // have to output the lines of pixels in reverse order
    
    if (mirror) {

      spieeprom_read_into_leds(anim_eeprom_offset + (1024UL-eepromaddr), BACK);

    } else {

	  // Otherwise, currently, turn off the backside LEDs
	  
      LATCH_SELECT_PORT |= _BV(BACK);
      NOP; NOP; NOP; NOP;
      LATCH_SELECT_PORT &= ~_BV(BACK);
    
    }
      
    // Now we increment the curr_eeprom_addr variable.  However, we
    // only do it IF it hasn't already been touched by some other part
    // of the code while we were displaying the pixels.  Also, we
    // turn interrupts off so that nobody else can touch it while
    // we are updating it.
    
    cli();
    
    if (eepromaddr == (curr_eeprom_addr%(NUM_PIXELS*4))) {

      curr_eeprom_addr = eepromaddr+4;
      
      }

    sei();
    
    PORTA &= ~0x1;
    
  } else {
    
    // We have not seen the magnet in a while, so turn off the
    // pixel timer...
    
    PORTA |= 0x2;

    // Turn off this pixel timer
    // Question: this is different from the code in SIG_INT1.  Why?
    
    cli();
    TCCR1B &= ~0x7;
    sei();

    // Turn off all but one LED
    
    set_led(2, FRONT);
    set_led(2, BACK);

    PORTA &= ~0x2;
  }

  PORTB &= ~0x2;
}

// Interrupt 0 executes when the button is pressed.

// QUESTION: unlike the pixel output interrupt, this one
// doesn't sei().  Why?

SIGNAL (SIG_INT0) {
  
  uint16_t timer;

  PORTB |= 0x4;
  
  // Twiddle our thumbs until the user releases the
  // button - but measure how long he takes...
  
  timer = 0;
  while (! (BUTTON_PIN & _BV(BUTTON))) {
    timer++;
    delay_ms(1);
  }
  
  // A short (<500ms) press will just restart the watchdog
  // timer.  I think this explains the structure of the
  // main() function; it doesn't have a loop to keep it
  // listening for commands if it times out, but pressing
  // the button will restart it.
  
  // We do expect that the button will be down at least
  // a small period of time...
  
  if (timer > BUTTON_DEBOUNCE) {
  
  	// If a quick press...
  	
    if (timer < 500UL) {
      
      // Re-enable the watchdog timer, then loop until
      // it fires off.
      
      WDTCSR = _BV(WDE);
      while (1);
      
    } else {
      
      // We want to shut everything down.  Setting sensor_timer
      // to the pin value will cause both the communications
      // loop and the regular timeout loop in the main() to
      // give up, which results in the device going to sleep.
      
      sensor_timer = 0xFFFF;
      
    }
  }
  
  PORTB &= ~0x4;

}

// Interrupt 1 executes when the hall effect sensor fires

// QUESTION: unlike the pixel output interrupt, this one
// doesn't sei().  Why?

SIGNAL (SIG_INT1) {
  
  PORTB |= 0x8;

  // The first issue we need to deal with when the hall-effect
  // sensor tells us it sees the magnet is to avoid doing any
  // processing if we get an interrupt too soon after the previous
  // interrupt.
  
  // hall_debounce is incremented by TIMER0, which fires every 3ms
  // or so.  At the current setting of 4, this means that at least
  // 15ms must elapse per trigger, which translates to about 4000
  // rpm.
  
  if (hall_debounce > HALL_DEBOUNCE_THRESH) {
    stopcomputertx = 1;

#ifdef ANIMATE

  // increment the animation timer, and move
  // to the next image every animation_time rotations
  
  if (anim_timer != animation_time) {

    anim_timer++;

  } else {

    anim_timer = 0;
    anim_eeprom_offset += 1024;

  }

#endif

    // We know the number of ms since the last hall sensor trigger
    // and there are 128 radial 'pixels' per sweep so divide to get
    // the necessary ms between the pixel interrupts
    
    // QUESTION: 128 or 256?
    
    // Then we just make TIMER1 trigger at that rate!
    
    // Reset the Timer Count Register for TIMER1 to 0, so it will
    // begin counting up.
    
    TCNT1 = 0;
    
    // sensor_timer contains the number of TIMER0 interrupts since
    // the last time we updated TIMER1.  If it has a reasonable
    // value, then we use it to reset the TIMER1 clock.
    
    if ((sensor_timer < 0xFF) && (sensor_timer > 0x3)) {
    
      // TIMER1 works differently from TIMER0.  It's a 16-bit timer
      // that apparently increments at the system clock rate.
      //
      // Because TIMER0 increments at 1/256 of the clock rate, and
      // fires the interrupt only when it overflows, sensor_timer
      // is incremented once ever 256*256 cycles.
      //
      // We want TIMER1 to fire off 256 times around the loop, so
      // we can display 256 lines of pixels.  We do this by putting
      // sensor_timer into the high byte of TIMER1's comparator
      // value, and the residual of TIMER0 (what it's counted up
      // to since the last time sensor_timer was incremented) into
      // the low byte, effectively a fractional value!
      //
      // Since TIMER0 is incrementing at 1/256 of the rate of TIMER1,

⌨️ 快捷键说明

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