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

📄 spokepov.lss

📁 旋转16个LED灯控制程序
💻 LSS
📖 第 1 页 / 共 4 页
字号:
 43e:	81 bb       	out	0x11, r24	; 17
 440:	8f ed       	ldi	r24, 0xDF	; 223
 442:	87 bb       	out	0x17, r24	; 23
 444:	80 e1       	ldi	r24, 0x10	; 16
 446:	88 bb       	out	0x18, r24	; 24
 448:	8c e4       	ldi	r24, 0x4C	; 76
 44a:	82 bb       	out	0x12, r24	; 18
 44c:	98 e0       	ldi	r25, 0x08	; 8
 44e:	95 bf       	out	0x35, r25	; 53
 450:	80 ec       	ldi	r24, 0xC0	; 192
 452:	8b bf       	out	0x3b, r24	; 59
 454:	10 be       	out	0x30, r1	; 48
 456:	84 e0       	ldi	r24, 0x04	; 4
 458:	83 bf       	out	0x33, r24	; 51
 45a:	89 b7       	in	r24, 0x39	; 57
 45c:	82 60       	ori	r24, 0x02	; 2
 45e:	89 bf       	out	0x39, r24	; 57
 460:	1f bc       	out	0x2f, r1	; 47
 462:	9e bd       	out	0x2e, r25	; 46
 464:	10 92 7c 00 	sts	0x007C, r1
 468:	10 92 7e 00 	sts	0x007E, r1
 46c:	10 92 7d 00 	sts	0x007D, r1
 470:	08 95       	ret

00000472 <main>:
}

int main(void) {
 472:	cf ed       	ldi	r28, 0xDF	; 223
 474:	d0 e0       	ldi	r29, 0x00	; 0
 476:	de bf       	out	0x3e, r29	; 62
 478:	cd bf       	out	0x3d, r28	; 61

  uint8_t cmd;			// the reason we reset

  // MCUSR is the MCU Status Register (page 40).  It tells us
  // why we reset, and a reset is the only way to get here.
  
  cmd = MCUSR;
 47a:	84 b7       	in	r24, 0x34	; 52
  
  // The first order of business is to tell the chip that
  // we've got things under control.
  
  MCUSR = 0;
 47c:	14 be       	out	0x34, r1	; 52
  
  // Turn on watchdog timer immediately, this protects against
  // a 'stuck' system by resetting it.
  
  // WDTCSR is the Watchdog Timer Control Register (page 45).
  // We set it so that it'll generate a watchdog interrupt
  // every second.  The idea is that if things mess up,
  // the watchdog will kickstart us.
  
  WDTCSR = _BV(WDE) | _BV(WDP2) | _BV(WDP1); // 1 second
 47e:	8e e0       	ldi	r24, 0x0E	; 14
 480:	81 bd       	out	0x21, r24	; 33
  
  // Initialize the various pins of the ATMEL, and set up
  // the interrupts.
  
  ioinit();
 482:	dc df       	rcall	.-72     	; 0x43c <ioinit>
  
  // Show that we are active.
  
  set_all(~0x01);
 484:	8e ef       	ldi	r24, 0xFE	; 254
 486:	59 de       	rcall	.-846    	; 0x13a <set_all>

  // enable the interrupts.  I think this is not needed
  // since it'll immediately be done by the loop, below.
  
  sei();
 488:	78 94       	sei
  
  // Loop until we timeout, at which point the ATMEL is
  // put to sleep.  If the communications routine timed
  // out, or the user pressed the button for >500ms,
  // then sensor_timer will be 0xFFFF and we'll immediately
  // sleep.
  
  // Change to for (;;) to see if it makes any difference
  
  for (;;) {
  
    // Reset the watchdog Timer.
    //
    // QUESTION: What's with toggling the PD0 output line here?
    // it doesn't seem to be connected to anything according to
    // the circuit diagram...
    
    // *** PORTD |= 0x1;
    asm("wdr");
 48a:	a8 95       	wdr
    // *** PORTD &= ~0x1;

	// If the sensor_timer (incremented by TIMER0) maxes out
	// (in about 3 minutes), then sleep everything.
	
    if (sensor_timer.bytes.high_byte == 0xFF) {
 48c:	80 91 7e 00 	lds	r24, 0x007E
 490:	8f 3f       	cpi	r24, 0xFF	; 255
 492:	71 f4       	brne	.+28     	; 0x4b0 <main+0x3e>
      
      // Avoid pesky interruptions
      
      cli();
 494:	f8 94       	cli
      
      // Turn off all LEDs - I guess LED 0 is one of the "invisible ones"
      
      set_all(0xFF);
 496:	51 de       	rcall	.-862    	; 0x13a <set_all>
      
      // Turn off power to the Hall Effect sensor.
      
      SENSOR_PORT &= ~_BV(SENSORPOWER);
 498:	96 98       	cbi	0x12, 6	; 18
      
      // Deselect EEPROM
      
      SPIEE_CS_PORT |= _BV(SPIEE_CS);      // pull CS high to deselect
 49a:	c4 9a       	sbi	0x18, 4	; 24
      
      // Turn off Watchdog (must be restarted when we get the wakeup)
      // Wakeup will be via the button interrupt.
      
      WDTCSR |= _BV(WDCE) | _BV(WDE);
 49c:	81 b5       	in	r24, 0x21	; 33
 49e:	88 61       	ori	r24, 0x18	; 24
 4a0:	81 bd       	out	0x21, r24	; 33
      WDTCSR = 0;
 4a2:	11 bc       	out	0x21, r1	; 33
      MCUCR |= _BV(SM1) | _BV(SM0) | _BV(SE);
 4a4:	85 b7       	in	r24, 0x35	; 53
 4a6:	80 67       	ori	r24, 0x70	; 112
 4a8:	85 bf       	out	0x35, r24	; 53
      
      // Re-enable interrupts so we can get the wakeup!
      
      sei();
 4aa:	78 94       	sei
     
      // Go into sleep mode
      
      asm("sleep");
 4ac:	88 95       	sleep
 4ae:	ed cf       	rjmp	.-38     	; 0x48a <main+0x18>
      
    } else {
    
      // Do we have dynamic updating to do?
      
      #ifdef DYNAMIC
     
        uint8_t tBytes;						// Number of bytes to transfer
        
        // Use unions to overlay variables and save some space
        
        union {
          char *fPtr;						// from pointer
          var16bit divisor;					// the divisor for RPM
        } a;
        
        union {
          char *tPtr;						// to pointer
          char *divTable;					// divisor table
        } b;
        
        // Update the dynamic data display
        
        switch (dynamicType & 0xF0) {
           
          #ifdef DYNAMIC_REVCOUNT					// Rev counter compiled in?
            
            case 0x10:								// Rev counter
            
              tBytes = 4;							// number of bytes we'll move down below
              a.fPtr = (char *)dynamicREV;
              break;                                // gets put into dynamicBuffer in reverse order.
            
          #endif
            
          #ifdef DYNAMIC_RPM						// RPM counter compiled in?
            
            case 0x20:
            
              // CODE NOT YET OPTIMIZED FOR SPACE.
              
              // Initialize the RPM counter to 0
              
              dynamicRPM[0]=dynamicRPM[1]=dynamicRPM[2] = '0';
              
              // Get a copy of the TIMER1 value that we need to divide 732 by
              
              a.divisor.word = OCR1A;
              
              // Start out pointing to the SECOND element of the div732 array.
              // We need to set to the second one because the min value of the
              // OCR1A hibyte (max speed) is 01, and we'll do at most 7 shifts
              // before we see a bit.  But there are 8 bits after that that
              // might get looked at, so the div732 table must be 8 entries long.
              // We also add 2 so that we are pointing at the last byte of each
              // entry.
              
              b.divTable = (char *)(div732+5);				// 3 bytes per entry
              
              // Shift the divisor to the left and the divtable pointer to the
              // right until the high bit of the divisor is set
              
              while (a.divisor.bytes.high_byte < 0x80) {
               
                a.divisor.word = a.divisor.word << 1;
                b.divTable = b.divTable + 3;
                 
              }
              
              // Once we have found the high bit, that tells us the fastest
              // the device could possibly be rotating.  Any other set bits in
              // a.divisor mean that the RPM is lower.  So what we do is clear
              // the high bit and add in our partial sums only when the bits
              // in the remainder are ** 0 **.  Since we just cleared the
              // high bit, it'll get counted.  If all the bits are zero, all
              // the sums will be added.
                    
              // NOTE: could be made smaller by using a.divisor.bytes.high_byte
              // below, sacrificing a bit of accuracy at very high speeds.
              
              a.divisor.word = a.divisor.word & 0x7FFF;
              
              while (b.divTable > div732) {
              
                if (a.divisor.bytes.high_byte < 0x80) {
                
                  // Add in the least significant bit.  Since the table is actual
                  // byte values, we don't need to deal with an ascii conversion
                
                  dynamicRPM[0] = dynamicRPM[0] + pgm_read_byte(b.divTable--);

                  if (dynamicRPM[0] > '9') {
                    dynamicRPM[0] = dynamicRPM[0] - 10;
                    dynamicRPM[1]++;
                  }
                
                  // repeat for second byte...
                
                  dynamicRPM[1] = dynamicRPM[1] + pgm_read_byte(b.divTable--);

                  if (dynamicRPM[1] > '9') {
                    dynamicRPM[1] = dynamicRPM[1] - 10;
                    dynamicRPM[2]++;
                  }
             
                  // and for third, but no carry needed this time
                
                  dynamicRPM[2] = dynamicRPM[2] + pgm_read_byte(b.divTable--);

				  // At this point, we've already subtracted 3 from b.divTable, so we're
				  // ready to go for the next loop.
				
				} else {
				
				  // But if we didn't add anything in, we need to shift b.divTable
				  
				  b.divTable = b.divTable - 3;
				  
				}
				
				// And finally move to the next bit
				
				a.divisor.word = a.divisor.word << 1;				
								
			  }
			  
			  // And when that's all done, we just set up for the move
			  
			  tBytes = 3;
			  a.fPtr = (char *)dynamicRPM;
              
              break;
              
          #endif
            
          #ifdef DYNAMIC_TIME						// Clock compiled in?
            
            case 0x30:								// Rev counter
            
              tBytes = 8;							// number of bytes we'll move down below
              a.fPtr = (char *)dynamicTime;
              break;                                // gets put into dynamicBuffer in reverse order.
            
          #endif
            
          default:								// This will get executed if no dynamic data
            tBytes = 0x00;						// and will clear things.
               
        }
          
        // If we have bytes to transfer, and if the dynamic display
        // is still active, then transfer the bytes into the display
           
        cli();
           
        if ( (dynamicType != 0x00) && (tBytes != 0x00) ) {
           
          b.tPtr = (char *)dynamicPtr;			// we now know dynamicPtr is valid
           
          // Remember, dynamicPtr points to the last byte, so we
          // copy bass ackwards!
             
          for(;tBytes>0;tBytes--) {
            *b.tPtr-- = *a.fPtr++;
          }
             
        }
           
      #endif
          	
      sei();
 4b0:	78 94       	sei
 4b2:	eb cf       	rjmp	.-42     	; 0x48a <main+0x18>

000004b4 <spi_transfer_n>:
// code space!

// Move n bits of data over the serial link

void spi_transfer_n(uint8_t c, uint8_t n) {
 4b4:	96 2f       	mov	r25, r22

  // Stuff the byte to transfer into the serial data register
  
  USIDR = c;
 4b6:	8f b9       	out	0x0f, r24	; 15
  
  // Set up the status register.  On each state transition of
  // the serial bus (up or down), the lower 4 bits will be
  // incremented - so twice per bit.  When that overflows,
  // the transfer is done.  So if they start out as 0, 8
  // bits get moved.  But if you start it out at a different
  // value, you can move an arbitrary number of bits
  
  USISR = _BV(USIOIF) | (16 - (n<<1));
 4b8:	99 0f       	add	r25, r25
 4ba:	80 e1       	ldi	r24, 0x10	; 16
 4bc:	89 1b       	sub	r24, r25
 4be:	80 64       	ori	r24, 0x40	; 64
 4c0:	8e b9       	out	0x0e, r24	; 14

  // While the transfer has not finished
  
  while ( (USISR & _BV(USIOIF)) == 0) {

    // Send out another bit
    
    USICR = _BV(USIWM0) | _BV(USICS1) | _BV(USICLK) | _BV(USITC);
 4c2:	76 99       	sbic	0x0e, 6	; 14
 4c4:	04 c0       	rjmp	.+8      	; 0x4ce <spi_transfer_n+0x1a>
 4c6:	8b e1       	ldi	r24, 0x1B	; 27
 4c8:	8d b9       	out	0x0d, r24	; 13
 4ca:	76 9b       	sbis	0x0e, 6	; 14
 4cc:	fd cf       	rjmp	.-6      	; 0x4c8 <spi_transfer_n+0x14>
 4ce:	08 95       	ret

000004d0 <spi_transfer>:
    //NOP;  // slow down so that the eeprom isnt overwhelmed

  }

}

// Move 4 bytes over the serial link (to the 1K/4K EEPROM or the
// LED shift registers, or both!).  This code does things "blind",
// clocking 16 times, to transfer the data as fast as possible.

void spi_transfer(uint8_t c) {

  USIDR = c;
 4d0:	8f b9       	out	0x0f, r24	; 15
  USISR = _BV(USIOIF);
 4d2:	80 e4       	ldi	r24, 0x40	; 64
 4d4:	8e b9       	out	0x0e, r24	; 14

  while ( (USISR & _BV(USIOIF)) == 0) {

    USICR = _BV(USIWM0) | _BV(USICS1) | _BV(USICLK) | _BV(USITC);
 4d6:	76 99       	sbic	0x0e, 6	; 14
 4d8:	04 c0       	rjmp	.+8      	; 0x4e2 <spi_transfer+0x12>
 4da:	8b e1       	ldi	r24, 0x1B	; 27
 4dc:	8d b9       	out	0x0d, r24	; 13
 4de:	76 9b       	sbis	0x0e, 6	; 14
 4e0:	fd cf       	rjmp	.-6      	; 0x4dc <spi_transfer+0xc>
 4e2:	08 95       	ret

000004e4 <spieeprom_read>:
    //NOP;  // slow down so that the eeprom isnt overwhelmed

  }

  // The byte read, if any, will be in USIDR
  
}

void spieeprom_read(uint16_t addr, uint8_t *buff, uint8_t len) {
 4e4:	ff 92       	push	r15
 4e6:	0f 93       	push	r16
 4e8:	1f 93       	push	r17
 4ea:	cf 93       	push	r28
 4ec:	df 93       	push	r29
 4ee:	08 2f       	mov	r16, r24
 4f0:	19 2f       	mov	r17, r25
 4f2:	d7 2f       	mov	r29, r23
 4f4:	c6 2f       	mov	r28, r22
 4f6:	f4 2e       	mov	r15, r20
  uint8_t i;

  SPIEE_CS_PORT &= ~_BV(SPIEE_CS); // pull CS low
 4f8:	c4 98       	cbi	0x18, 4	; 24
	...
  NOP; NOP; NOP; NOP;

  spi_transfer(SPI_EEPROM_READ);           // send READ command
 502:	83 e0       	ldi	r24, 0x03	; 3
 504:	e5 df       	rcall	.-54     	; 0x4d0 <spi_transfer>
  spi_transfer(addr >> 8);                 // send high addr 
 506:	81 2f       	mov	r24, r17
 508:	99 27       	eor	r25, r25
 50a:	e2 df       	rcall	.-60     	; 0x4d0 <spi_transfer>
  spi_transfer(addr & 0xFF);               // send low addr
 50c:	80 2f       	mov	r24, r16
 50e:	e0 df       	rcall	.-64     	; 0x4d0 <spi_transfer>

  for (i=0; i<len; i++)	{				   // read in the right number of
 510:	00 e0       	ldi	r16, 0x00	; 0
 512:	0f 15       	cp	r16, r15
 514:	30 f4       	brcc	.+12     	; 0x522 <spieeprom_read+0x3e>
    spi_transfer(0);					   // bits, then move to buff[]
 516:	80 e0       	ldi	r24, 0x00	; 0
 518:	db df       	rcall	.-74     	; 0x4d0 <spi_transfer>
    buff[i] = USIDR;
 51a:	8f b1       	in	r24, 0x0f	; 15
 51c:	89 93       	st	Y+, r24
 51e:	0f 5f       	subi	r16, 0xFF	; 255
 520:	f8 cf       	rjmp	.-16     	; 0x512 <spieeprom_read+0x2e>
  }

  SPIEE_CS_PORT |= _BV(SPIEE_CS);      // pull CS high
 522:	c4 9a       	sbi	0x18, 4	; 24
 524:	df 91       	pop	r29
 526:	cf 91       	pop	r28
 528:	1f 91       	pop	r17
 52a:	0f 91       	pop	r16
 52c:	ff 90       	pop	r15
 52e:	08 95       	ret

00000530 <memcpy_P>:
 530:	e6 2f       	mov	r30, r22
 532:	f7 2f       	mov	r31, r23
 534:	a8 2f       	mov	r26, r24
 536:	b9 2f       	mov	r27, r25
 538:	03 c0       	rjmp	.+6      	; 0x540 <memcpy_P+0x10>
 53a:	c8 95       	lpm
 53c:	31 96       	adiw	r30, 0x01	; 1
 53e:	0d 92       	st	X+, r0
 540:	41 50       	subi	r20, 0x01	; 1
 542:	50 40       	sbci	r21, 0x00	; 0
 544:	d0 f7       	brcc	.-12     	; 0x53a <memcpy_P+0xa>
 546:	08 95       	ret

⌨️ 快捷键说明

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