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

📄 spokepov.lss

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

int main(void) {
 5d4:	cf ed       	ldi	r28, 0xDF	; 223
 5d6:	d0 e0       	ldi	r29, 0x00	; 0
 5d8:	de bf       	out	0x3e, r29	; 62
 5da:	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;
 5dc:	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;
 5de:	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
 5e0:	8e e0       	ldi	r24, 0x0E	; 14
 5e2:	81 bd       	out	0x21, r24	; 33
  
  // Initialize the various pins of the ATMEL, and set up
  // the interrupts.
  
  ioinit();
 5e4:	dc df       	rcall	.-72     	; 0x59e <ioinit>
  
  // Show that we are active.
  
  set_all(~0x01);
 5e6:	8e ef       	ldi	r24, 0xFE	; 254
 5e8:	0f de       	rcall	.-994    	; 0x208 <set_all>

  // enable the interrupts.  I think this is not needed
  // since it'll immediately be done by the loop, below.
  
  sei();
 5ea:	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");
 5ec:	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) {
 5ee:	80 91 82 00 	lds	r24, 0x0082
 5f2:	8f 3f       	cpi	r24, 0xFF	; 255
 5f4:	71 f4       	brne	.+28     	; 0x612 <main+0x3e>
      
      // Avoid pesky interruptions
      
      cli();
 5f6:	f8 94       	cli
      
      // Turn off all LEDs - I guess LED 0 is one of the "invisible ones"
      
      set_all(0xFF);
 5f8:	07 de       	rcall	.-1010   	; 0x208 <set_all>
      
      // Turn off power to the Hall Effect sensor.
      
      SENSOR_PORT &= ~_BV(SENSORPOWER);
 5fa:	96 98       	cbi	0x12, 6	; 18
      
      // Deselect EEPROM
      
      SPIEE_CS_PORT |= _BV(SPIEE_CS);      // pull CS high to deselect
 5fc:	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);
 5fe:	81 b5       	in	r24, 0x21	; 33
 600:	88 61       	ori	r24, 0x18	; 24
 602:	81 bd       	out	0x21, r24	; 33
      WDTCSR = 0;
 604:	11 bc       	out	0x21, r1	; 33
      MCUCR |= _BV(SM1) | _BV(SM0) | _BV(SE);
 606:	85 b7       	in	r24, 0x35	; 53
 608:	80 67       	ori	r24, 0x70	; 112
 60a:	85 bf       	out	0x35, r24	; 53
      
      // Re-enable interrupts so we can get the wakeup!
      
      sei();
 60c:	78 94       	sei
     
      // Go into sleep mode
      
      asm("sleep");
 60e:	88 95       	sleep
 610:	ed cf       	rjmp	.-38     	; 0x5ec <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();
 612:	78 94       	sei
 614:	eb cf       	rjmp	.-42     	; 0x5ec <main+0x18>

00000616 <spi_transfer_n>:
// code space!

// Move n bits of data over the serial link

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

  // Stuff the byte to transfer into the serial data register
  
  USIDR = c;
 618:	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));
 61a:	99 0f       	add	r25, r25
 61c:	80 e1       	ldi	r24, 0x10	; 16
 61e:	89 1b       	sub	r24, r25
 620:	80 64       	ori	r24, 0x40	; 64
 622:	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);
 624:	76 99       	sbic	0x0e, 6	; 14
 626:	04 c0       	rjmp	.+8      	; 0x630 <spi_transfer_n+0x1a>
 628:	8b e1       	ldi	r24, 0x1B	; 27
 62a:	8d b9       	out	0x0d, r24	; 13
 62c:	76 9b       	sbis	0x0e, 6	; 14
 62e:	fd cf       	rjmp	.-6      	; 0x62a <spi_transfer_n+0x14>
 630:	08 95       	ret

00000632 <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;
 632:	8f b9       	out	0x0f, r24	; 15
  USISR = _BV(USIOIF);
 634:	80 e4       	ldi	r24, 0x40	; 64
 636:	8e b9       	out	0x0e, r24	; 14

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

    USICR = _BV(USIWM0) | _BV(USICS1) | _BV(USICLK) | _BV(USITC);
 638:	76 99       	sbic	0x0e, 6	; 14
 63a:	04 c0       	rjmp	.+8      	; 0x644 <spi_transfer+0x12>
 63c:	8b e1       	ldi	r24, 0x1B	; 27
 63e:	8d b9       	out	0x0d, r24	; 13
 640:	76 9b       	sbis	0x0e, 6	; 14
 642:	fd cf       	rjmp	.-6      	; 0x63e <spi_transfer+0xc>
 644:	08 95       	ret

00000646 <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) {
 646:	ff 92       	push	r15
 648:	0f 93       	push	r16
 64a:	1f 93       	push	r17
 64c:	cf 93       	push	r28
 64e:	df 93       	push	r29
 650:	08 2f       	mov	r16, r24
 652:	19 2f       	mov	r17, r25
 654:	d7 2f       	mov	r29, r23
 656:	c6 2f       	mov	r28, r22
 658:	f4 2e       	mov	r15, r20
  uint8_t i;

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

  spi_transfer(SPI_EEPROM_READ);           // send READ command
 664:	83 e0       	ldi	r24, 0x03	; 3
 666:	e5 df       	rcall	.-54     	; 0x632 <spi_transfer>
  spi_transfer(addr >> 8);                 // send high addr 
 668:	81 2f       	mov	r24, r17
 66a:	99 27       	eor	r25, r25
 66c:	e2 df       	rcall	.-60     	; 0x632 <spi_transfer>
  spi_transfer(addr & 0xFF);               // send low a

⌨️ 快捷键说明

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