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

📄 main copy.c

📁 旋转16个LED灯控制程序
💻 C
📖 第 1 页 / 共 4 页
字号:
volatile var16bit sensor_timer;				// count (via TIMER0) since last actual Hall Effect detectionvolatile uint8_t line_timer = SCROLLSPEED;	// counter for scrolling/line stepping; realized it only needs to be 8 bitsvolatile uint8_t cur_line = NUM_LINES-1;	// the current 'top line'volatile uint8_t line_shift = 0x0f;			// # of pixels extra shift we do to scroll smoothly// Sends the 4-byte LED pixel data block out// over the serial link.  Front LEDs only// Sends 4 bytes + sCount extra bits over the serial link// to implement smooth scrolling.  Can be used with a 0// parameter to just send out the regular 4 bytes.void clock_scroll(uint8_t sCount) {  // First, send the basic 4 bytes, they go no matter what    spi_transfer(fleds[0]);  spi_transfer(fleds[1]);  spi_transfer(fleds[2]);  spi_transfer(fleds[3]);   // If there is anything to do..    if (sCount != 0) {      // If we have < 8 bits to transfer        if (sCount < 8) {           // Then that is all that we need to do              spi_transfer_n(fleds[4],sCount);           } else {          // First latch out the full first 8 bits         	  spi_transfer(fleds[4]);  	     	  // How many bits left to do?  	     	  sCount = sCount - 8;  	     	  if (sCount != 0) {  	           spi_transfer_n(fleds[5],sCount);           	  }  	     	}  	  }     // finally, latch the bits into the LEDS    LATCH_SELECT_PORT |= _BV(FRONT);  NOP; NOP; NOP; NOP;  LATCH_SELECT_PORT &= ~_BV(FRONT);}// TIMER0 interrupt handler.  This runs about every 8ms// AFAICT.  It increments the hall_debounce and sensor_timer// values until they pin.// QUESTION: what's with the setting and clearing of PORTB0?// According to the wiring diagram, it isn't connected to// anything.  Is this vestigial code from when you were using// Pin Change Interrupts?  Or is it debugger code so you// can monitor the pins and tell when something happens.SIGNAL (SIG_TIMER0_OVF) {  // *** PORTB |= 0x1;  // Let hall_debounce just wrap around.  At worst it'll just  // mess things up for one of the initial speedup rotations  // of the blade...    // if (hall_debounce != 0xFF)    hall_debounce++;    if (sensor_timer.bytes.high_byte != 0xFF)    sensor_timer.word++;  #if NUM_LINES > 0    // Increment the line timer - we only need to do this    // if we are scrolling      if (line_timer != 0xFF) {      line_timer++;    }    #endif  #ifdef DYNAMIC_TIME      // Increment the dynamic time fractional seconds byte        dynamicTimeCounter.word += DYNAMIC_TIME_CALIBRATION;        if (dynamicTimeCounter.bytes.high_byte > 0x7F) {          // wrap the counter             dynamicTimeCounter.bytes.high_byte &= 0x7F;             // Add 1 second to the time HH:MM:SS      //                          76-43-10      // Bytes in reverse order            // Increment seconds             dynamicTime[0]++;             // Check for units seconds overflow - has the digit become 10?             if ( dynamicTime[0] == ':' ) {               // If so, reset it and increment 10's digit                  dynamicTime[0] = '0';        dynamicTime[1]++;                // Repeat the process for the 10s seconds digit, has it become        // 6?                  if ( dynamicTime[1] == '6' ) {                     // reset it and increment minutes digit                        dynamicTime[1] = '0';           dynamicTime[3]++;                        // Repeat process for minutes                        if ( dynamicTime[3] == ':' ) {                 	 // You should get the idea now...          	           	 dynamicTime[3] = '0';          	 dynamicTime[4]++;                              	 if ( dynamicTime[4] == '6' ) {                         dynamicTime[4] = '0';               dynamicTime[6]++;                            // and 10s of hours                              if ( dynamicTime[6] == ':' ) {                                dynamicTime[6] = '0';                 dynamicTime[7]++;                                }                              // handle special wrap               			   #ifdef DYNAMIC_TIME_12H			   			     if ( (dynamicTime[7] == '1') && (dynamicTime[6] == '3') ) {			     			        dynamicTime[7] = '0';			        dynamicTime[6] = '1';			        			     }			     			   #else			   			     if ( (dynamicTime[7] == '2') && (dynamicTime[6] == '4') ) {			     			        dynamicTime[7] = dynamicTime[6] = '0';			        			     }			     			   #endif			                }           }         }       }     }       #endif                         // *** PORTB &= ~0x1;}// Hack - I used to copy the topChar, etc. variables into local// variables in the TIMER1 routine, but I am running out of stack space.  So instead// I'm going to keep interrupts off during this routine and// use the global versions.// As we sweep around the circle, we display 256 radial pixel// lines, once per TIMER1 interrupt.  This is broken down into// 16 16-pixel wide characters, and we have two characters// stacked vertically.  To save time, we keep track of the// character number, pixel number (in the character), and// pointers into the eeprom for each of the two chars being// displayed.// This code has to be fast enough to complete execution before// it gets interrupted again - and it must not make any subroutine// calls, since that'll mess up the stack and cause the entire// system to reset.volatile uint16_t topChar = 0;		// top character being displayed (address in EEPROM of data)volatile uint16_t botChar = 0;		// bottom character being displayedvolatile uint8_t charNum = 31;		// character numbervolatile uint8_t pixelNum = 15;		// pixel number#ifdef HALFSHIFT  volatile uint8_t charNum2 = 31;		// character number  volatile uint8_t pixelNum2 = 15;	// pixel number	#endif#ifdef SMOOTHSCROLL  volatile uint16_t scrollChar = 0;	// extra scroll character  #ifdef HALFSHIFT	volatile uint8_t charNum3 = 31;		// character number	volatile uint8_t pixelNum3 = 15;	// pixel number	  #endif#endif// This routine gets called every time the pixel timer runs down;// in other words, once per "scan line", 256 times per revolution// of the SpokePOV.  Its purpose is to update the LEDs.SIGNAL (SIG_TIMER1_COMPA) {  // Because of the way the code's evolved, I have the vars just  // defined above renamed via defines right here.  Just haven't  // gotten around to grepping them...    #define	tChar	topChar  #define	bChar	botChar  #define	cNum	charNum  #define	pNum	pixelNum  #define	sChar	scrollChar  #define	cNum2	charNum2  #define	cNum3	charNum3  #define	pNum2	pixelNum2  #define	pNum3	pixelNum3  // If it has been less than STANDBY_TIMEOUT seconds since the last time we  // got a Hall Effect sensor update, then proceed as normal and  // update the LEDs.    // QUESTION: what is F_CPU?  ANSWER: FREQUENCY OF CPU (clocks/second)    if (sensor_timer.bytes.high_byte < ( (F_CPU/NUM_PIXELS)/256 * STANDBY_TIMEOUT) / 256) {            // *** PORTA |= 0x1;        // If we are in normal mode, we use one shift for everyone        #ifndef HALFSHIFT          // The first thing we do is increment our character position; this      // is done here to avoid code duplication.  This means that the      // Hall Effect interrupt routine must set them up so they "wrap"      // into the first valid values.          // Move to the next pixel in the character            pNum++;          // If we have moved off the edge of the character, then      // we need to move to the next character          if (pNum == 16) {            // If we will wrap around to the first character, turn off the pixel        // timer, clear the display, and exit.  Might speed things up a bit              if (cNum == 15) {          TCCR1B &= ~0x7;          set_all(~0x00);          return;        }        pNum = 0;					// reset to first pixel        cNum = (cNum+1) & 0x0F;	// move, with wrap, to next character position                    // Now we need to reset the pointers to the correct addresses        // in the EEPROM for the characters they display.  With the new        // interleaved character sets, this becomes much easier              tChar = (topLine[cNum]-32) << 1;		// character offset for the top char, 0-95        // Ditto for bChar...              bChar = (botLine[cNum]-32) << 1;      	    #ifdef SMOOTHSCROLL			  // and if smooth scrolling, sChar		  		  sChar = (scrollLine[cNum]-32) << 1;		  	    #endif      } else {            // If we haven't wrapped around a character boundary, we just move        // to the next 2-byte line in the character set, which will be 192 bytes        // away              tChar += 192;        bChar += 192;      	    #ifdef SMOOTHSCROLL				  sChar += 192;			    #endif      }         #else          // Okay, we are doing half-shifts.  So we effectively have to do the      // above code once for each line            // Do for the first line.  Also use this to turn off the display if      // we get to the end.  If first line is shifted, this'll turn us off      // a half-char early, so other lines can't have anything in the last      // character space...            pNum++;          if (pNum == 16) {            if (cNum == 15) {          TCCR1B &= ~0x7;          set_all(~0x00);          return;        }        pNum = 0;        cNum = (cNum+1) & 0x0F;                    tChar = (topLine[cNum]-32) << 1;		// character offset for the top char, 0-95      } else {            tChar += 192;      }            // do for second line            pNum2++;          if (pNum2 == 16) {            pNum2 = 0;        cNum2 = (cNum2+1) & 0x0F;                    bChar = (botLine[cNum2]-32) << 1;      } else {            bChar += 192;      }            // and scroll line            #ifdef SMOOTHSCROLL              pNum3++;            if (pNum3 == 16) {              pNum3 = 0;          cNum3 = (cNum3+1) & 0x0F;                      sChar = (scrollLine[cNum]-32) << 1;        } else {              sChar += 192;        }            #endif    #endif        // Unfortunately, we can't do the cute "read from the EEPROM right    // into the LEDs trick" that limor can do in SpokePOV.  We have to    // read the data into the ATMEL and then write it out.

⌨️ 快捷键说明

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