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

📄 spokepov.lss

📁 旋转16个LED灯控制程序
💻 LSS
📖 第 1 页 / 共 5 页
字号:
  set_led(2, BACK);

  // If the 4K EEPROM is installed, then up to 4 images
  // can be displayed.  The SpokePOV cycles between them
  // at regular intervals.  This interval is stored in
  // the ATMEL internal EEPROM, which is seperate from
  // the external EEPROM.
  
  animation_time = internal_eeprom_read(EEPROM_ANIMATION);

  // enable the interrupts.  I think this is not needed
  // since it'll immediately be done by the loop, below.
  
  sei();
  
  // Now loop processing commands that come in over the
  // dongle.  This is how the EEPROMs are programmed.
  
  while (1) {
  
  	// Enable interrupts again
  	
  	sei();
    cmd = tx_computer_byte(0);

	// This break is the only way out of
	// this loop.  If it executes (probably because of
	// a timeout in tx_computer_byte()), then there is
	// no way back other than resetting the chip by
	// a long button-push.
	
    if (cmd == 0)
      break;
    else
    
      // Disable interrupts during command processing.
      
      cli();

	// Sensor_timer does double-duty here, as a timeout counter for
	// the communications link.  But this is OK since we never do
	// comm and display at the same time...
	
	// POSSIBLE BUG: it isn't cleared before the original cmd
	// byte read, and since interrupts are off, it won't be
	// incremented by the interrupt routine!
	
    sensor_timer = 0;      // overloaded to reset communications timeout

    switch (cmd) {

		// Read either a single byte, or 16 bytes, from either
		// the external or internal EEPROM.  If the high bit of
		// the address is 1, then it's an internal read.
		
		case COMP_CMD_RDEEPROM:
		case COMP_CMD_RDEEPROM16:

		  if  (cmd == COMP_CMD_RDEEPROM16)
			n = 16;
		  else
			n = 1;
	
		  // read 2 bytes to get the address
		  
		  addr = tx_computer_byte(0);
		  addr <<= 8;
		  addr |= tx_computer_byte(0);
		  
		  // internal or external?
		  
		  if ((addr & 0x8000) != 0) {
		  
		  	// there are only 256 bytes of internal eeprom
		  	
			tx_computer_byte(internal_eeprom_read(addr & 0xFF));
			
		  } else {
		
			// read and transfer 1 or 16 bytes
			
			spieeprom_read(addr, buff, n);
			for (i=0; i<n; i++) {
			  tx_computer_byte(buff[i]);
			}
			
		  }
	
		  // Tell the PC we're copacetic
		  
		  tx_computer_byte(COMP_SUCCESS);
		  break;
	
		// Write either a single byte or a block of 16.  Same
		// idea as above...
		
		case COMP_CMD_WREEPROM:
		case COMP_CMD_WREEPROM16:
		  
		  if (cmd == COMP_CMD_WREEPROM16)
			n = 16;
		  else
			n = 1;
	
		  addr = tx_computer_byte(0);
		  addr <<= 8;
		  addr |= tx_computer_byte(0);
		  
		  // Give a visual indication that we're loading data
		  
		  set_led((addr/16)%32,FRONT); 
		  
		  // Receive the bytes
		  
		  for (i=0; i<n; i++) {
			buff[i] = tx_computer_byte(0);
		  }
	
		  // Tell the PC we got the data...
		  
		  tx_computer_byte(COMP_SUCCESS);
	
		  // ...and actually do the write
		  
		  if ((addr & 0x8000) != 0) {
			internal_eeprom_write(addr & 0xFF, buff[0]);
		  } else {
			spieeprom_write(addr, buff, n);
		  }
		  break;
    }
  
  }

  // 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");
    PORTD &= ~0x1;

	// If the sensor_timer (incremented by TIMER0) maxes out
	// (in about 3 minutes), then sleep everything.
	
    if (sensor_timer == 0xFFFF) {
      
      // Avoid pesky interruptions
      
      cli();
      
      // Turn off all LEDs - I guess LED 0 is one of the "invisible ones"
      
      set_led(0, FRONT);
      set_led(0, BACK);
      
      // Turn off power to the Hall Effect sensor.
      
      SENSOR_PORT &= ~_BV(SENSORPOWER);
      
      // Deselect EEPROM
      
      SPIEE_CS_PORT |= _BV(SPIEE_CS);      // pull CS high to deselect
      
      // Turn off Watchdog (must be restarted when we get the wakeup)
      // Wakeup will be via the button interrupt.
      
      WDTCSR |= _BV(WDCE) | _BV(WDE);
      WDTCSR = 0;
      MCUCR |= _BV(SM1) | _BV(SM0) | _BV(SE);
      
      // Re-enable interrupts so we can get the wakeup!
      
      sei();
     
      // Go into sleep mode
      
      asm("sleep");
    }
  }
  PORTD |= 0x2;
}

// Talk to the PC.  First a byte is sent, then a byte
// is received.  This is a simple form of handshaking.
//
// The assembly wdr instruction resets the watchdog
// timer so it won't cause everything to abort.
//
// POSSIBLE BUG: this function quits when sensor_timer
// maxes out.  But sensor_timer is incremented in an
// interrupt routine, and AFAICT interrupts are turned
// off in the communications loop (except for the
// cmd read, which is possibly the only time it's
// needed).  But in addition, it isn't cleared before
// that read, so the timeout may occur a lot faster
// that expected.
//
// POSSIBLE BUG: if it does time out, then the returned
// value v is undefined.
//
// I won't worry at this point about figuring out how
// this works!

uint8_t tx_computer_byte(uint8_t b) {
  uint8_t v;

  DDRA = 0x0;           				// outputs
  DDRB = 0x5F;          				// input on MOSI/DI (for SPI), all others output
  USICR = _BV(USIWM0) | _BV(USICS1);
  USIDR = b;                 			// transfer 0x0
  USISR = _BV(USIOIF);       			// ready
  while (! (USISR & _BV(USIOIF)) ) {
    asm("wdr");

    if (sensor_timer == 0xFFFF) { 
      stopcomputertx = 1;
    }
    
    if (stopcomputertx) {
      break;
    }
    
  }

  v = USIDR;

  DDRB = 0xDF; 
  USICR = 0;

  return v;
}

// Move data over the serial link (to the 1K/4K EEPROM or the
// LED shift registers, or both!)  This is black magic to me!

uint8_t spi_transfer(uint8_t c) {

  USIDR = c;
  USISR = _BV(USIOIF);

  while (! (USISR & _BV(USIOIF))) {

    USICR = _BV(USIWM0) | _BV(USICS1) | _BV(USICLK) | _BV(USITC);
    //NOP;  // slow down so that the eeprom isnt overwhelmed

  }

  return USIDR;

}

// Read the internal EEPROM

uint8_t internal_eeprom_read(uint8_t addr) {

  loop_until_bit_is_clear(EECR, EEWE);	// Wait for last write to finish
 144:	e1 99       	sbic	0x1c, 1	; 28
 146:	fe cf       	rjmp	.-4      	; 0x144 <internal_eeprom_read>

  EEAR = addr;							// Store address to read
 148:	8e bb       	out	0x1e, r24	; 30
  EECR |= _BV(EERE);					// Trigger the EEPROM read - this takes only one
 14a:	e0 9a       	sbi	0x1c, 0	; 28
										// cycle, so the result can immediately be returned!
  return EEDR;							
 14c:	8d b3       	in	r24, 0x1d	; 29

}
 14e:	99 27       	eor	r25, r25
 150:	08 95       	ret

00000152 <ioinit>:
 152:	83 e7       	ldi	r24, 0x73	; 115
 154:	81 bb       	out	0x11, r24	; 17
 156:	8f ed       	ldi	r24, 0xDF	; 223
 158:	87 bb       	out	0x17, r24	; 23
 15a:	80 e1       	ldi	r24, 0x10	; 16
 15c:	88 bb       	out	0x18, r24	; 24
 15e:	8c e4       	ldi	r24, 0x4C	; 76
 160:	82 bb       	out	0x12, r24	; 18
 162:	98 e0       	ldi	r25, 0x08	; 8
 164:	95 bf       	out	0x35, r25	; 53
 166:	80 ec       	ldi	r24, 0xC0	; 192
 168:	8b bf       	out	0x3b, r24	; 59
 16a:	10 be       	out	0x30, r1	; 48
 16c:	84 e0       	ldi	r24, 0x04	; 4
 16e:	83 bf       	out	0x33, r24	; 51
 170:	89 b7       	in	r24, 0x39	; 57
 172:	82 60       	ori	r24, 0x02	; 2
 174:	89 bf       	out	0x39, r24	; 57
 176:	1f bc       	out	0x2f, r1	; 47
 178:	9e bd       	out	0x2e, r25	; 46
 17a:	10 92 69 00 	sts	0x0069, r1
 17e:	10 92 6b 00 	sts	0x006B, r1
 182:	10 92 6a 00 	sts	0x006A, r1
 186:	08 95       	ret

00000188 <spi_transfer>:
 188:	8f b9       	out	0x0f, r24	; 15
 18a:	80 e4       	ldi	r24, 0x40	; 64
 18c:	8e b9       	out	0x0e, r24	; 14
 18e:	76 99       	sbic	0x0e, 6	; 14
 190:	04 c0       	rjmp	.+8      	; 0x19a <spi_transfer+0x12>
 192:	8b e1       	ldi	r24, 0x1B	; 27
 194:	8d b9       	out	0x0d, r24	; 13
 196:	76 9b       	sbis	0x0e, 6	; 14
 198:	fd cf       	rjmp	.-6      	; 0x194 <spi_transfer+0xc>
 19a:	8f b1       	in	r24, 0x0f	; 15
 19c:	99 27       	eor	r25, r25
 19e:	08 95       	ret

000001a0 <clock_leds>:
 1a0:	1f 93       	push	r17
 1a2:	cf 93       	push	r28
 1a4:	df 93       	push	r29
 1a6:	18 2f       	mov	r17, r24
 1a8:	84 30       	cpi	r24, 0x04	; 4
 1aa:	19 f4       	brne	.+6      	; 0x1b2 <clock_leds+0x12>
 1ac:	c0 e7       	ldi	r28, 0x70	; 112
 1ae:	d0 e0       	ldi	r29, 0x00	; 0
 1b0:	02 c0       	rjmp	.+4      	; 0x1b6 <clock_leds+0x16>
 1b2:	cc e6       	ldi	r28, 0x6C	; 108
 1b4:	d0 e0       	ldi	r29, 0x00	; 0
 1b6:	8b 81       	ldd	r24, Y+3	; 0x03
 1b8:	e7 df       	rcall	.-50     	; 0x188 <spi_transfer>
 1ba:	8a 81       	ldd	r24, Y+2	; 0x02
 1bc:	e5 df       	rcall	.-54     	; 0x188 <spi_transfer>
 1be:	89 81       	ldd	r24, Y+1	; 0x01
 1c0:	e3 df       	rcall	.-58     	; 0x188 <spi_transfer>
 1c2:	88 81       	ld	r24, Y
 1c4:	e1 df       	rcall	.-62     	; 0x188 <spi_transfer>
 1c6:	21 e0       	ldi	r18, 0x01	; 1
 1c8:	30 e0       	ldi	r19, 0x00	; 0
 1ca:	02 c0       	rjmp	.+4      	; 0x1d0 <clock_leds+0x30>
 1cc:	22 0f       	add	r18, r18
 1ce:	33 1f       	adc	r19, r19
 1d0:	1a 95       	dec	r17
 1d2:	e2 f7       	brpl	.-8      	; 0x1cc <clock_leds+0x2c>
 1d4:	82 b3       	in	r24, 0x12	; 18
 1d6:	82 2b       	or	r24, r18
 1d8:	82 bb       	out	0x12, r24	; 18
	...
 1e2:	92 2f       	mov	r25, r18
 1e4:	90 95       	com	r25
 1e6:	82 b3       	in	r24, 0x12	; 18
 1e8:	89 23       	and	r24, r25
 1ea:	82 bb       	out	0x12, r24	; 18
 1ec:	df 91       	pop	r29
 1ee:	cf 91       	pop	r28
 1f0:	1f 91       	pop	r17
 1f2:	08 95       	ret

000001f4 <set_led>:
 1f4:	28 2f       	mov	r18, r24
 1f6:	64 30       	cpi	r22, 0x04	; 4
 1f8:	19 f4       	brne	.+6      	; 0x200 <set_led+0xc>
 1fa:	e0 e7       	ldi	r30, 0x70	; 112
 1fc:	f0 e0       	ldi	r31, 0x00	; 0
 1fe:	02 c0       	rjmp	.+4      	; 0x204 <set_led+0x10>
 200:	ec e6       	ldi	r30, 0x6C	; 108
 202:	f0 e0       	ldi	r31, 0x00	; 0
 204:	8f ef       	ldi	r24, 0xFF	; 255
 206:	83 83       	std	Z+3, r24	; 0x03
 208:	82 83       	std	Z+2, r24	; 0x02
 20a:	81 83       	std	Z+1, r24	; 0x01
 20c:	80 83       	st	Z, r24
 20e:	82 2f       	mov	r24, r18
 210:	86 95       	lsr	r24
 212:	86 95       	lsr	r24
 214:	86 95       	lsr	r24
 216:	e8 0f       	add	r30, r24
 218:	f1 1d       	adc	r31, r1
 21a:	27 70       	andi	r18, 0x07	; 7
 21c:	81 e0       	ldi	r24, 0x01	; 1
 21e:	90 e0       	ldi	r25, 0x00	; 0
 220:	02 c0       	rjmp	.+4      	; 0x226 <set_led+0x32>
 222:	88 0f       	add	r24, r24
 224:	99 1f       	adc	r25, r25
 226:	2a 95       	dec	r18
 228:	e2 f7       	brpl	.-8      	; 0x222 <set_led+0x2e>
 22a:	80 95       	com	r24
 22c:	80 83       	st	Z, r24
 22e:	86 2f       	mov	r24, r22

⌨️ 快捷键说明

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