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

📄 spokepov.lss

📁 旋转16个LED灯控制程序
💻 LSS
📖 第 1 页 / 共 5 页
字号:
  // 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) {
 632:	cf ed       	ldi	r28, 0xDF	; 223
 634:	d0 e0       	ldi	r29, 0x00	; 0
 636:	de bf       	out	0x3e, r29	; 62
 638:	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;
 63a:	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;
 63c:	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
 63e:	8e e0       	ldi	r24, 0x0E	; 14
 640:	81 bd       	out	0x21, r24	; 33
  
  // Initialize the various pins of the ATMEL, and set up
  // the interrupts.
  
  ioinit();
 642:	cf df       	rcall	.-98     	; 0x5e2 <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)
 644:	10 fd       	sbrc	r17, 0
    test_leds();
 646:	e8 df       	rcall	.-48     	; 0x618 <test_leds>

  // display the reason for the reset on the LEDs.
  
  set_all(~0x01);
 648:	8e ef       	ldi	r24, 0xFE	; 254
 64a:	77 dd       	rcall	.-1298   	; 0x13a <set_all>

  // enable the interrupts.  I think this is not needed
  // since it'll immediately be done by the loop, below.
  
  sei();
 64c:	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.
  
  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");
 64e:	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) {
 650:	80 91 87 00 	lds	r24, 0x0087
 654:	90 91 88 00 	lds	r25, 0x0088
 658:	8f 5f       	subi	r24, 0xFF	; 255
 65a:	9f 4f       	sbci	r25, 0xFF	; 255
 65c:	79 f4       	brne	.+30     	; 0x67c <main+0x4a>
      
      // Avoid pesky interruptions
      
      cli();
 65e:	f8 94       	cli
      
      // Turn off all LEDs - I guess LED 0 is one of the "invisible ones"
      
      set_all(0xFF);
 660:	8f ef       	ldi	r24, 0xFF	; 255
 662:	6b dd       	rcall	.-1322   	; 0x13a <set_all>
      
      // Turn off power to the Hall Effect sensor.
      
      SENSOR_PORT &= ~_BV(SENSORPOWER);
 664:	96 98       	cbi	0x12, 6	; 18
      
      // Deselect EEPROM
      
      SPIEE_CS_PORT |= _BV(SPIEE_CS);      // pull CS high to deselect
 666:	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);
 668:	81 b5       	in	r24, 0x21	; 33
 66a:	88 61       	ori	r24, 0x18	; 24
 66c:	81 bd       	out	0x21, r24	; 33
      WDTCSR = 0;
 66e:	11 bc       	out	0x21, r1	; 33
      MCUCR |= _BV(SM1) | _BV(SM0) | _BV(SE);
 670:	85 b7       	in	r24, 0x35	; 53
 672:	80 67       	ori	r24, 0x70	; 112
 674:	85 bf       	out	0x35, r24	; 53
      
      // Re-enable interrupts so we can get the wakeup!
      
      sei();
 676:	78 94       	sei
     
      // Go into sleep mode
      
      asm("sleep");
 678:	88 95       	sleep
 67a:	e9 cf       	rjmp	.-46     	; 0x64e <main+0x1c>
      
    } else {
    
      // Do we have dynamic updating to do?
      
      #ifdef DYNAMIC
     
        uint8_t tBytes;						// Number of bytes to transfer
        char *fPtr,*tPtr;					// transfer pointers
        
        // Step 1, update the dynamicPtr
        
        if (dynamicPtr != newDynamicPtr) {
 67c:	80 91 74 00 	lds	r24, 0x0074
 680:	90 91 75 00 	lds	r25, 0x0075
 684:	20 91 72 00 	lds	r18, 0x0072
 688:	30 91 73 00 	lds	r19, 0x0073
 68c:	82 17       	cp	r24, r18
 68e:	93 07       	cpc	r25, r19
 690:	31 f0       	breq	.+12     	; 0x69e <main+0x6c>
        
          cli();								// unclear if I really need to turn off
 692:	f8 94       	cli
          dynamicPtr = (char *)newDynamicPtr;	// interrupts, but I'll play it safe for
 694:	30 93 75 00 	sts	0x0075, r19
 698:	20 93 74 00 	sts	0x0074, r18
          sei();								// the time being
 69c:	78 94       	sei
           
        }
        
        // If we have dynamic data to display...
        
        if (dynamicPtr != NULL) {
 69e:	20 91 74 00 	lds	r18, 0x0074
 6a2:	30 91 75 00 	lds	r19, 0x0075
 6a6:	21 15       	cp	r18, r1
 6a8:	31 05       	cpc	r19, r1
 6aa:	89 f2       	breq	.-94     	; 0x64e <main+0x1c>
        
          switch (dynamicType & 0xF0) {
 6ac:	80 91 71 00 	lds	r24, 0x0071
 6b0:	99 27       	eor	r25, r25
 6b2:	80 7f       	andi	r24, 0xF0	; 240
 6b4:	90 70       	andi	r25, 0x00	; 0
 6b6:	40 97       	sbiw	r24, 0x10	; 16
 6b8:	21 f4       	brne	.+8      	; 0x6c2 <main+0x90>
           
            case 0x10:								// Rev counter
            
              tBytes = 4;							// number of bytes we'll move down below
 6ba:	44 e0       	ldi	r20, 0x04	; 4
              fPtr = (char *)dynamicCounter;
 6bc:	a3 e6       	ldi	r26, 0x63	; 99
 6be:	b0 e0       	ldi	r27, 0x00	; 0
              break;                                // gets put into dynamicBuffer in reverse order.
 6c0:	03 c0       	rjmp	.+6      	; 0x6c8 <main+0x96>
              
            default:
              tBytes = 0;
 6c2:	40 e0       	ldi	r20, 0x00	; 0
              fPtr = NULL;							// preset the pointers to what we
 6c4:	a0 e0       	ldi	r26, 0x00	; 0
 6c6:	b0 e0       	ldi	r27, 0x00	; 0
              
            }
          
           // Now move the bytes IF newDynamicPtr hasn't changed...
           // This one we do need to insulate from interrupts
           
           tPtr = dynamicPtr;				// move
 6c8:	f3 2f       	mov	r31, r19
 6ca:	e2 2f       	mov	r30, r18
           
           cli();
 6cc:	f8 94       	cli
           
           if ( (fPtr != NULL) && (newDynamicPtr == dynamicPtr) ) {
 6ce:	10 97       	sbiw	r26, 0x00	; 0
 6d0:	71 f0       	breq	.+28     	; 0x6ee <main+0xbc>
 6d2:	80 91 72 00 	lds	r24, 0x0072
 6d6:	90 91 73 00 	lds	r25, 0x0073
 6da:	82 17       	cp	r24, r18
 6dc:	93 07       	cpc	r25, r19
 6de:	39 f4       	brne	.+14     	; 0x6ee <main+0xbc>
           
             // Remember, dynamicPtr points to the last byte, so we
             // copy bass ackwards!
             
             for(;tBytes>0;tBytes--) {
 6e0:	44 23       	and	r20, r20
 6e2:	29 f0       	breq	.+10     	; 0x6ee <main+0xbc>
               *tPtr-- = *fPtr++;
 6e4:	8d 91       	ld	r24, X+
 6e6:	80 83       	st	Z, r24
 6e8:	31 97       	sbiw	r30, 0x01	; 1
 6ea:	41 50       	subi	r20, 0x01	; 1
 6ec:	f9 cf       	rjmp	.-14     	; 0x6e0 <main+0xae>
             }
             
           }
           
           sei();
 6ee:	78 94       	sei
 6f0:	ae cf       	rjmp	.-164    	; 0x64e <main+0x1c>

000006f2 <spi_transfer_n>:
// code space!

// Move n bits of data over the serial link

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

  // Stuff the byte to transfer into the serial data register
  
  USIDR = c;
 6f4:	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));
 6f6:	99 0f       	add	r25, r25
 6f8:	80 e1       	ldi	r24, 0x10	; 16
 6fa:	89 1b       	sub	r24, r25
 6fc:	80 64       	ori	r24, 0x40	; 64
 6fe:	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);
 700:	76 99       	sbic	0x0e, 6	; 14
 702:	04 c0       	rjmp	.+8      	; 0x70c <spi_transfer_n+0x1a>
 704:	8b e1       	ldi	r24, 0x1B	; 27
 706:	8d b9       	out	0x0d, r24	; 13
 708:	76 9b       	sbis	0x0e, 6	; 14
 70a:	fd cf       	rjmp	.-6      	; 0x706 <spi_transfer_n+0x14>
 70c:	08 95       	ret

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

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

    USICR = _BV(USIWM0) | _BV(USICS1) | _BV(USICLK) | _BV(USITC);
 714:	76 99       	sbic	0x0e, 6	; 14
 716:	04 c0       	rjmp	.+8      	; 0x720 <spi_transfer+0x12>
 718:	8b e1       	ldi	r24, 0x1B	; 27
 71a:	8d b9       	out	0x0d, r24	; 13
 71c:	76 9b       	sbis	0x0e, 6	; 14
 71e:	fd cf       	rjmp	.-6      	; 0x71a <spi_transfer+0xc>
 720:	08 95       	ret

00000722 <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) {
 722:	ff 92       	push	r15
 724:	0f 93       	push	r16
 726:	1f 93       	push	r17
 728:	cf 93       	push	r28
 72a:	df 93       	push	r29
 72c:	08 2f       	mov	r16, r24
 72e:	19 2f       	mov	r17, r25
 730:	d7 2f       	mov	r29, r23
 732:	c6 2f       	mov	r28, r22
 734:	f4 2e       	mov	r15, r20
  uint8_t i;

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

  spi_transfer(SPI_EEPROM_READ);           // send READ command
 740:	83 e0       	ldi	r24, 0x03	; 3
 742:	e5 df       	rcall	.-54     	; 0x70e <spi_transfer>
  spi_transfer(addr >> 8);                 // send high addr 
 744:	81 2f       	mov	r24, r17
 746:	99 27       	eor	r25, r25
 748:	e2 df       	rcall	.-60     	; 0x70e <spi_transfer>
  spi_transfer(addr & 0xFF);               // send low addr
 74a:	80 2f       	mov	r24, r16
 74c:	e0 df       	rcall	.-64     	; 0x70e <spi_transfer>

  for (i=0; i<len; i++)	{				   // read in the right number of
 74e:	00 e0       	ldi	r16, 0x00	; 0
 750:	0f 15       	cp	r16, r15
 752:	30 f4       	brcc	.+12     	; 0x760 <spieeprom_read+0x3e>
    spi_transfer(0);					   // bits, then move to buff[]
 754:	80 e0       	ldi	r24, 0x00	; 0
 756:	db df       	rcall	.-74     	; 0x70e <spi_transfer>
    buff[i] = USIDR;
 758:	8f b1       	in	r24, 0x0f	; 15
 75a:	89 93       	st	Y+, r24
 75c:	0f 5f       	subi	r16, 0xFF	; 255
 75e:	f8 cf       	rjmp	.-16     	; 0x750 <spieeprom_read+0x2e>
  }

  SPIEE_CS_PORT |= _BV(SPIEE_CS);      // pull CS high
 760:	c4 9a       	sbi	0x18, 4	; 24
 762:	df 91       	pop	r29
 764:	cf 91       	pop	r28
 766:	1f 91       	pop	r17
 768:	0f 91       	pop	r16
 76a:	ff 90       	pop	r15
 76c:	08 95       	ret

0000076e <memcpy_P>:
 76e:	e6 2f       	mov	r30, r22
 770:	f7 2f       	mov	r31, r23
 772:	a8 2f       	mov	r26, r24
 774:	b9 2f       	mov	r27, r25
 776:	03 c0       	rjmp	.+6      	; 0x77e <memcpy_P+0x10>
 778:	c8 95       	lpm
 77a:	31 96       	adiw	r30, 0x01	; 1
 77c:	0d 92       	st	X+, r0
 77e:	41 50       	subi	r20, 0x01	; 1
 780:	50 40       	sbci	r21, 0x00	; 0
 782:	d0 f7       	brcc	.-12     	; 0x778 <memcpy_P+0xa>
 784:	08 95       	ret

⌨️ 快捷键说明

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