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

📄 spokepov.lss

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

spokepov.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000077e  00000000  00000000  00000094  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000022  00800060  0000077e  00000812  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          0000000f  00800082  00800082  00000834  2**0
                  ALLOC
  3 .noinit       00000000  00800091  00800091  00000834  2**0
                  CONTENTS
  4 .eeprom       00000000  00810000  00810000  00000834  2**0
                  CONTENTS
  5 .stab         00000354  00000000  00000000  00000834  2**2
                  CONTENTS, READONLY, DEBUGGING
  6 .stabstr      00000084  00000000  00000000  00000b88  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_aranges 00000028  00000000  00000000  00000c0c  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_pubnames 000001e6  00000000  00000000  00000c34  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_info   000005dc  00000000  00000000  00000e1a  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_abbrev 000001e9  00000000  00000000  000013f6  2**0
                  CONTENTS, READONLY, DEBUGGING
 11 .debug_line   00000737  00000000  00000000  000015df  2**0
                  CONTENTS, READONLY, DEBUGGING
 12 .debug_str    0000024d  00000000  00000000  00001d16  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:	f7 c0       	rjmp	.+494    	; 0x1f4 <__vector_2>
   6:	28 c0       	rjmp	.+80     	; 0x58 <__bad_interrupt>
   8:	55 c1       	rjmp	.+682    	; 0x2b4 <__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:	ee e7       	ldi	r30, 0x7E	; 126
  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 38       	cpi	r26, 0x82	; 130
  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 e8       	ldi	r26, 0x82	; 130
  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:	a1 39       	cpi	r26, 0x91	; 145
  52:	b1 07       	cpc	r27, r17
  54:	e1 f7       	brne	.-8      	; 0x4e <.do_clear_bss_loop>
  56:	3a c2       	rjmp	.+1140   	; 0x4cc <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 8a 00 	lds	r24, 0x008A
  70:	8f 3f       	cpi	r24, 0xFF	; 255
  72:	29 f0       	breq	.+10     	; 0x7e <__vector_6+0x24>
    hall_debounce++;
  74:	80 91 8a 00 	lds	r24, 0x008A
  78:	8f 5f       	subi	r24, 0xFF	; 255
  7a:	80 93 8a 00 	sts	0x008A, r24
  
  if (sensor_timer != 0xFFFF)
  7e:	80 91 8b 00 	lds	r24, 0x008B
  82:	90 91 8c 00 	lds	r25, 0x008C
  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 8b 00 	lds	r24, 0x008B
  90:	90 91 8c 00 	lds	r25, 0x008C
  94:	01 96       	adiw	r24, 0x01	; 1
  96:	90 93 8c 00 	sts	0x008C, r25
  9a:	80 93 8b 00 	sts	0x008B, 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>:

}

// As we sweep around the circle, we display 256 radial pixel
// lines, once per TIMER1 interrupt.  This is broken down into
// 16 16-pixel wide characters, and we have two characters
// stacked vertically.  To save time, we keep track of the
// character number, pixel number (in the character), and
// pointers into the eeprom for each of the two chars being
// displayed.

volatile uint16_t topChar = 0;		// top character being displayed (address in EEPROM of data)
volatile uint16_t botChar = 0;		// bottom character being displayed
volatile uint8_t charNum = 0;		// character number
volatile uint8_t pixelNum = 0;		// pixel number
volatile uint8_t clean = 0;			// have these values been changed outside TIMER1?

// 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 tChar;					// local copies of the values
  uint16_t bChar;
  uint8_t cNum;
  uint8_t pNum;

  uint8_t cCode;					// character code to display
  
  // 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;

  // Copy the volatile variables into their local equivalents
  
  tChar = topChar;
  bChar = botChar;
  cNum = charNum;
  pNum = pixelNum;

  // 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;
    
    // The first thing we do is increment our character position; this
    // is done here to avoid code duplication.  This means that the
    // Hall Effect interrupt routine must set them up so they "wrap"
    // into the first valid values.
    
    // Move to the next pixel in the character
    
    pNum++;
    
    // If we have moved off the edge of the character, then
    // we need to move to the next character
    
    if (pNum == 16) {
    
      pNum = 0;					// reset to first pixel
      cNum = (cNum+1) % 16;		// move, with wrap, to next character position
      
      // Now we need to reset the pointers to the correct addresses
      // in the EEPROM for the characters they display.  The earlier
      // decision to store these in a format that makes them display
      // nicely on the original SpokePOV software makes this a little
      // bit difficult.
      
      cCode = topLine[cNum]-32;		// character number for the top char, 0-95
      
      // In the character set, 2 characters are stored vertically stacked.
      // So each group of 2 characters takes up 64 bytes (4x16).
      
      tChar = ((cCode >> 1) << 6) | ( (cCode & 0x01) << 1 );
      
      // Ditto for bChar...
      
      cCode = botLine[cNum]-32;
      bChar = ((cCode >> 1) << 6) | ( (cCode & 0x01) << 1 );
    
    } else {
    
      // If we haven't wrapped around a character boundary, we just move
      // to the next line in the character set, which is 4 pixels offset
      // in each case
      
      tChar += 4;
      bChar += 4;
      
    }
     
    // Unfortunately, we can't do the cute "read from the EEPROM right
    // into the LEDs trick" that limor can do in SpokePOV.  We have to
    // read the data into the ATMEL and then write it out.
    
    spieeprom_read(tChar,fleds,2);		// the top 2 bytes
    spieeprom_read(bChar,fleds+2,2);	// and the bottom 2
    
    clock_leds();						// and send them to the LEDs
    
    // Now we increment the variables.  However, we
    // only do it IF haven't 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 them
    // while we are at it
    
    cli();
    
    if (clean) {

	  topChar = tChar;
	  botChar = bChar;
	  charNum = cNum;
	  pixelNum = pNum;
      
    } else {
    
      // Since we didn't update the data, we know it was changed, and
      // we know that next time, we CAN update the data.  So everything
      // is clean now!
      
      clean = 1;
      
    }

    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);

    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

⌨️ 快捷键说明

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