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

📄 spokepov.lss

📁 旋转16个LED灯控制程序
💻 LSS
📖 第 1 页 / 共 5 页
字号:
  
  set_all(0x00);
 61a:	80 e0       	ldi	r24, 0x00	; 0
 61c:	9c dd       	rcall	.-1224   	; 0x156 <set_all>
  delay_ms(255);
 61e:	8f ef       	ldi	r24, 0xFF	; 255
 620:	83 de       	rcall	.-762    	; 0x328 <delay_ms>
 622:	08 95       	ret

00000624 <main>:
  
  // likely the 1-second reset timer will go off before
  // this ends.  But no biggy, since if it does, it'll
  // reset the LEDs..
  
}

int main(void) {
 624:	cf ed       	ldi	r28, 0xDF	; 223
 626:	d0 e0       	ldi	r29, 0x00	; 0
 628:	de bf       	out	0x3e, r29	; 62
 62a:	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;
 62c:	14 b7       	in	r17, 0x34	; 52
  
  // The first order of business is to tell the chip that
  // we've got things under control.
  
  MCUSR = 0;
 62e:	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
 630:	8e e0       	ldi	r24, 0x0E	; 14
 632:	81 bd       	out	0x21, r24	; 33
  
  // Initialize the various pins of the ATMEL, and set up
  // the interrupts.
  
  ioinit();
 634:	cf df       	rcall	.-98     	; 0x5d4 <ioinit>
  
  // test the copy from our PROGMEM string
  
  // We saved the reason for the reset of the chip.  If
  // it's a power-on, then we run a test pattern through
  // the LEDs.  Note that because we've set a 1-second
  // watchdog timer (in ioinit), if this test sequence
  // takes more than a second, the chip will reset.  But
  // since we'll know it isn't a power-on, the test
  // sequence won't run...
  
  if ((cmd & _BV(PORF)) != 0)
 636:	10 fd       	sbrc	r17, 0
    test_leds();
 638:	e8 df       	rcall	.-48     	; 0x60a <test_leds>

  // display the reason for the reset on the LEDs.
  
  set_all(~0x01);
 63a:	8e ef       	ldi	r24, 0xFE	; 254
 63c:	8c dd       	rcall	.-1256   	; 0x156 <set_all>

  // enable the interrupts.  I think this is not needed
  // since it'll immediately be done by the loop, below.
  
  sei();
 63e:	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
  
  while (1) {
  
    // 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");
 640:	a8 95       	wdr
    // *** PORTD &= ~0x1;

	// If the sensor_timer (incremented by TIMER0) maxes out
	// (in about 3 minutes), then sleep everything.
	
    if (sensor_timer == 0xFFFF) {
 642:	80 91 87 00 	lds	r24, 0x0087
 646:	90 91 88 00 	lds	r25, 0x0088
 64a:	8f 5f       	subi	r24, 0xFF	; 255
 64c:	9f 4f       	sbci	r25, 0xFF	; 255
 64e:	79 f4       	brne	.+30     	; 0x66e <main+0x4a>
      
      // Avoid pesky interruptions
      
      cli();
 650:	f8 94       	cli
      
      // Turn off all LEDs - I guess LED 0 is one of the "invisible ones"
      
      set_all(0xFF);
 652:	8f ef       	ldi	r24, 0xFF	; 255
 654:	80 dd       	rcall	.-1280   	; 0x156 <set_all>
      
      // Turn off power to the Hall Effect sensor.
      
      SENSOR_PORT &= ~_BV(SENSORPOWER);
 656:	96 98       	cbi	0x12, 6	; 18
      
      // Deselect EEPROM
      
      SPIEE_CS_PORT |= _BV(SPIEE_CS);      // pull CS high to deselect
 658:	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);
 65a:	81 b5       	in	r24, 0x21	; 33
 65c:	88 61       	ori	r24, 0x18	; 24
 65e:	81 bd       	out	0x21, r24	; 33
      WDTCSR = 0;
 660:	11 bc       	out	0x21, r1	; 33
      MCUCR |= _BV(SM1) | _BV(SM0) | _BV(SE);
 662:	85 b7       	in	r24, 0x35	; 53
 664:	80 67       	ori	r24, 0x70	; 112
 666:	85 bf       	out	0x35, r24	; 53
      
      // Re-enable interrupts so we can get the wakeup!
      
      sei();
 668:	78 94       	sei
     
      // Go into sleep mode
      
      asm("sleep");
 66a:	88 95       	sleep
 66c:	e9 cf       	rjmp	.-46     	; 0x640 <main+0x1c>
      
    } 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
          uint16_t divisor;					// the divisor for RPM
        } a;
        
        union {
          char *tPtr;						// to pointer
          char *divTable;					// divisor table
        } b;
        
        // Step 1, update the dynamicPtr
        
        if (dynamicPtr != newDynamicPtr) {
 66e:	80 91 74 00 	lds	r24, 0x0074
 672:	90 91 75 00 	lds	r25, 0x0075
 676:	20 91 72 00 	lds	r18, 0x0072
 67a:	30 91 73 00 	lds	r19, 0x0073
 67e:	82 17       	cp	r24, r18
 680:	93 07       	cpc	r25, r19
 682:	31 f0       	breq	.+12     	; 0x690 <main+0x6c>
        
          cli();								// unclear if I really need to turn off
 684:	f8 94       	cli
          dynamicPtr = (char *)newDynamicPtr;	// interrupts, but I'll play it safe for
 686:	30 93 75 00 	sts	0x0075, r19
 68a:	20 93 74 00 	sts	0x0074, r18
          sei();								// the time being
 68e:	78 94       	sei
           
        }
        
        // If we have dynamic data to display...
        
        if (dynamicPtr != NULL) {
 690:	80 91 74 00 	lds	r24, 0x0074
 694:	90 91 75 00 	lds	r25, 0x0075
 698:	89 2b       	or	r24, r25
 69a:	91 f2       	breq	.-92     	; 0x640 <main+0x1c>
        
          switch (dynamicType & 0xF0) {
 69c:	80 91 71 00 	lds	r24, 0x0071
 6a0:	99 27       	eor	r25, r25
 6a2:	80 7f       	andi	r24, 0xF0	; 240
 6a4:	90 70       	andi	r25, 0x00	; 0
 6a6:	80 97       	sbiw	r24, 0x20	; 32
 6a8:	09 f0       	breq	.+2      	; 0x6ac <main+0x88>
 6aa:	61 c0       	rjmp	.+194    	; 0x76e <main+0x14a>
           
            #ifdef DYNAMIC_REVCOUNT					// Rev counter compiled in?
            
            case 0x10:								// Rev counter
            
              tBytes = 4;							// number of bytes we'll move down below
              a.fPtr = (char *)dynamicCounter;
              break;                                // gets put into dynamicBuffer in reverse order.
            
            #endif
            
            #ifdef DYNAMIC_RPM						// RPM counter compiled in?
            
            case 0x20:
            
              // Initialize the RPM counter to 0
              
              dynamicCounter[0]=dynamicCounter[1]=dynamicCounter[2] = '0';
 6ac:	80 e3       	ldi	r24, 0x30	; 48
 6ae:	80 93 65 00 	sts	0x0065, r24
 6b2:	80 91 65 00 	lds	r24, 0x0065
 6b6:	80 93 64 00 	sts	0x0064, r24
 6ba:	80 91 64 00 	lds	r24, 0x0064
 6be:	80 93 63 00 	sts	0x0063, r24
              
              // Get a copy of the TIMER1 value that we need to divide 732 by
              
              a.divisor = OCR1A;
 6c2:	8a b5       	in	r24, 0x2a	; 42
 6c4:	9b b5       	in	r25, 0x2b	; 43
              
              // 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
 6c6:	ab e2       	ldi	r26, 0x2B	; 43
 6c8:	b0 e0       	ldi	r27, 0x00	; 0
              
              // 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 & 0x80) == 0) {
               
                a.divisor = a.divisor << 1;
                b.divTable = b.divTable + 3;
 6ca:	87 fd       	sbrc	r24, 7
 6cc:	04 c0       	rjmp	.+8      	; 0x6d6 <main+0xb2>
 6ce:	88 0f       	add	r24, r24
 6d0:	99 1f       	adc	r25, r25
 6d2:	13 96       	adiw	r26, 0x03	; 3
 6d4:	fa cf       	rjmp	.-12     	; 0x6ca <main+0xa6>
                 
              }
              
              // Now we go back through the div732 array, adding in the digits
              // whenever we have a set bit in the divisor, until we've run out
              // of significant bits
              
              while (b.divTable > div732) {
              
                // Add in the least significant bit.  Keep in mind we are adding
                // ASCII to ASCII (so must subtract 48...)
                
                dynamicCounter[0] = dynamicCounter[0] + pgm_read_byte(*b.divTable--) - 48;
                
                if (dynamicCounter[0] > '9') {
                  dynamicCounter[0] = dynamicCounter[0] - 10;
                  dynamicCounter[1]++;
                }
                
                // repeat for second byte...
                
                dynamicCounter[1] = dynamicCounter[1] + pgm_read_byte(*b.divTable--) - 48;
                
                if (dynamicCounter[1] > '9') {
                  dynamicCounter[1] = dynamicCounter[1] - 10;
                  dynamicCounter[2]++;
                }
             
                // and for third, but no carry needed this time
                
                dynamicCounter[1] = dynamicCounter[1] + pgm_read_byte(*b.divTable--) - 48;
                
				// finally, shift back in the table
				
				b.divTable = b.divTable - 3;
				
				// and get the next bit of the divisor
				
				a.divisor = a.divisor << 1;
 6d6:	80 e0       	ldi	r24, 0x00	; 0
 6d8:	a6 32       	cpi	r26, 0x26	; 38
 6da:	b8 07       	cpc	r27, r24
 6dc:	09 f0       	breq	.+2      	; 0x6e0 <main+0xbc>
 6de:	08 f4       	brcc	.+2      	; 0x6e2 <main+0xbe>
 6e0:	46 c0       	rjmp	.+140    	; 0x76e <main+0x14a>
 6e2:	8c 91       	ld	r24, X
 6e4:	e8 2f       	mov	r30, r24
 6e6:	ff 27       	eor	r31, r31
 6e8:	11 97       	sbiw	r26, 0x01	; 1
 6ea:	c8 95       	lpm
 6ec:	90 2d       	mov	r25, r0
 6ee:	80 91 63 00 	lds	r24, 0x0063
 6f2:	89 0f       	add	r24, r25
 6f4:	80 53       	subi	r24, 0x30	; 48
 6f6:	80 93 63 00 	sts	0x0063, r24
 6fa:	80 91 63 00 	lds	r24, 0x0063
 6fe:	8a 33       	cpi	r24, 0x3A	; 58
 700:	50 f0       	brcs	.+20     	; 0x716 <main+0xf2>
 702:	80 91 63 00 	lds	r24, 0x0063
 706:	8a 50       	subi	r24, 0x0A	; 10
 708:	80 93 63 00 	sts	0x0063, r24
 70c:	80 91 64 00 	lds	r24, 0x0064
 710:	8f 5f       	subi	r24, 0xFF	; 255
 712:	80 93 64 00 	sts	0x0064, r24
 716:	8c 91       	ld	r24, X
 718:	e8 2f       	mov	r30, r24
 71a:	ff 27       	eor	r31, r31
 71c:	11 97       	sbiw	r26, 0x01	; 1
 71e:	c8 95       	lpm
 720:	90 2d       	mov	r25, r0
 722:	80 91 64 00 	lds	r24, 0x0064
 726:	89 0f       	add	r24, r25
 728:	80 53       	subi	r24, 0x30	; 48
 72a:	80 93 64 00 	sts	0x0064, r24
 72e:	80 91 64 00 	lds	r24, 0x0064
 732:	8a 33       	cpi	r24, 0x3A	; 58
 734:	50 f0       	brcs	.+20     	; 0x74a <main+0x126>
 736:	80 91 64 00 	lds	r24, 0x0064
 73a:	8a 50       	subi	r24, 0x0A	; 10
 73c:	80 93 64 00 	sts	0x0064, r24
 740:	80 91 65 00 	lds	r24, 0x0065
 744:	8f 5f       	subi	r24, 0xFF	; 255
 746:	80 93 65 00 	sts	0x0065, r24
 74a:	8c 91       	ld	r24, X
 74c:	e8 2f       	mov	r30, r24
 74e:	ff 27       	eor	r31, r31
 750:	c8 95       	lpm
 752:	90 2d       	mov	r25, r0
 754:	80 91 64 00 	lds	r24, 0x0064
 758:	89 0f       	add	r24, r25
 75a:	80 53       	subi	r24, 0x30	; 48
 75c:	80 93 64 00 	sts	0x0064, r24
 760:	14 97       	sbiw	r26, 0x04	; 4
 762:	20 e0       	ldi	r18, 0x00	; 0
 764:	a6 32       	cpi	r26, 0x26	; 38
 766:	b2 07       	cpc	r27, r18
 768:	11 f0       	breq	.+4      	; 0x76e <main+0x14a>
 76a:	08 f0       	brcs	.+2      	; 0x76e <main+0x14a>
 76c:	ba cf       	rjmp	.-140    	; 0x6e2 <main+0xbe>
				
			  }
			  
			  // And when that's all done, we just set up for the move
			  
			  tBytes = 3;
			  a.fPtr = (char *)dynamicCounter;
              
            #endif
            
            default:
              tBytes = 0;
              a.fPtr = NULL;						// preset the pointers to what we
              
            }
          
           // Now move the bytes IF newDynamicPtr hasn't changed...
           // This one we do need to insulate from interrupts
           
           b.tPtr = dynamicPtr;				// move
           
           cli();
 76e:	f8 94       	cli
           
           if ( (a.fPtr != NULL) && (newDynamicPtr == dynamicPtr) ) {
           
             // Remember, dynamicPtr points to the last byte, so we
             // copy bass ackwards!
             
             for(;tBytes>0;tBytes--) {
               *b.tPtr-- =

⌨️ 快捷键说明

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