|  | 
3#
 
 
 樓主|
發表於 2016-11-5 17:30:00
|
只看該作者 
| 本帖最後由 zasdfeer13 於 2016-11-6 16:54 編輯 
 我之前有使用過他的library,但是我是打算使用48顆TLC5940串接去控制256顆RGB LED ,
 
 他的library串接到第4顆之後就會有clock不足的問題,
 
 不知道是不是我使用的問題,我是希望可以透過SPI去提高傳送的速度
 
 但是這顆TLC5940最重要的GSCLK的控制,我還是一直搞不懂,下面是我的Code,
 
 參考外國的一個http://www.kevindarrah.com/downl ... imersCountersV6.ino的Code去改的
 
 但是它是透過UNO去控制,主要的Timer還有中斷的部分我沒有辦法理解,我只能照我理解的部分改成DUE能使用的,目前串到第5顆TLC的時候就會產生不對的閃爍,希望可以能找到完整的GSCLK的寫法。
 
 我們是透過串接48顆TLC5940跟2顆74595去控制16*16*16的LED立方體。
 下面是我目前的Code
 複製代碼#include <SPI.h>//Serial Peripheral Interface Library
 //****************************************************************************************************
 //****************************************************************************************************
  byte ch=0, chbit=0, spibit=0, spibyte=0;// variables used by tlc sub routine
  int SINData;//variable used to shift data to the TLC
  byte transferbyte[1152];// bytes that are sent out to the tlc5940 via SPI
  // 48 because 16 channels @ 12bits gives 384bits, 384/8 = 48 bytes, 12 bit to 8 bit conversion
  int i, j, k, l=10,m,n,x=0; //misc variables
  int green, oldgreen= 2048;//for random animation
  int red, oldred = 2048;//for random animation
  int blue, oldblue = 2048;//for random animation
  int comeback=0, pick_color=0;//for random animation
  bool ledOn = false;
//************************************************************************************************** 開空間
  byte low_numberToDisplay[9]  = {0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 };
  byte  high_numberToDisplay[9] = {0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 };
 //*************************************************************************************************
//************************************************************************************************* 74595
  byte channelR,channelG,channelB;
  char LEDZ=0;
//*************************************************************************************************
 
  //****************************************************************************************************
  #define XLAT (1<<25) //TLC 24  due2
  #define GSCLK (1<<28) //TLC 18 due 3
  #define SIN (1<<26)  //TLC 26  due75
  #define SCLK (1<<27) //TLC 25 due76
  #define BLANK (1<<25) //TLC 23  due5
  //****************************************************************************************************
 
  //****************************************************************************************************
void setup(){//   MAIN SETUP   MAIN SETUP   MAIN SETUP   MAIN SETUP   MAIN SETUP
  REG_PIOB_OWER = XLAT; REG_PIOB_OER = XLAT;     
  REG_PIOA_OWER = SIN; REG_PIOA_OER = SIN;    
  REG_PIOA_OWER = SCLK; REG_PIOA_OER = SCLK;
  REG_PIOC_OWER = GSCLK; REG_PIOC_OER = GSCLK;
  REG_PIOC_OWER = (1<<22); REG_PIOC_OER = (1<<22);//74595 latch
  REG_PIOD_OWER = (1<<8); REG_PIOD_OER = (1<<8);//74595clk
  REG_PIOD_OWER = (1<<7); REG_PIOD_OER = (1<<7);//74595data
  
  //Set up the SPI
  SPI.setBitOrder(MSBFIRST);//Most Significant Bit First
  SPI.setDataMode(SPI_MODE0);// Mode 0 Rising edge of data, keep clock low
  SPI.setClockDivider(3);//Run the data in at 84MHZ
 
  
  for(i=0; i<1152; i++)//clear out Gray Scale Data
  transferbyte[i]=0;   
  for(i=0; i<768; i++)//wipe out the data in tlc
  tlc(i, 0);// This is how you update the LEDs, tlc is a subroutine with two inputs
  // tlc(Channel, Value)  Channel in this case is 0-32 and value is 0-4095 duty cycle
  //4095 is 100% ON
  REG_PIOC_OWER = BLANK; REG_PIOC_OER = BLANK;//BLANK  We set this pin up here, so it remains in a high impedance
  // state throughout the setup, otherwise the LEDs go crazy!  even if you write this HIGH
    
}// END OF SETUP END OF SETUP END OF SETUP END OF SETUP END OF SETUP END OF SETUP END OF SETUP
  //****************************************************************************************************
  //****************************************************************************************************
void loop(){//   MAIN LOOP   MAIN LOOP   MAIN LOOP   MAIN LOOP   MAIN LOOP   MAIN LOOP
    VccControl();
   
    for(i=0;i<96;i++)
    {
     tlc(i,k); 
    }
    ID();
    
    
    /*k=k+l;
   if (k <= 0 || k >= 4090) {
    l = -l ;
  }*/
  
 
  
}//      loop close      loop close      loop close      loop close
  //****************************************************************************************************
  //****************************************************************************************************
// INTERRUPTS   INTERRUPTS   INTERRUPTS   INTERRUPTS   INTERRUPTS   INTERRUPTS   INTERRUPTS  
// INTERRUPTS   INTERRUPTS   INTERRUPTS   INTERRUPTS   INTERRUPTS   INTERRUPTS   INTERRUPTS  
  //****************************************************************************************************
  //****************************************************************************************************
void ID(){
  
  SPI.begin();// start the SPI back up
  for(SINData=1151; SINData>=0; SINData--)// send the data out!
  SPI.transfer(transferbyte[SINData]);// The SPI port only understands bytes-8 bits wide
  SPI.end();//end the SPI so we can write to the clock pin
 REG_PIOB_SODR = 0x1 << 25;// write XLAT HIGH to latch in data from the last data stream
 REG_PIOC_CODR = 0x1 << 25;// write blank LOW  to start the next cycle
 
 for(i=0;i<4096;i++){ 
    REG_PIOC_SODR = 0x1 << 28;
    REG_PIOC_CODR = 0x1 << 28;
    } 
 REG_PIOC_SODR = 0x1 << 25;//Blank goes HIGH to reset the 4096 counter in the TLC
 REG_PIOB_CODR = 0x1 << 25;//XLAT can go low now
  
  
}
  //****************************************************************************************************
 
void tlc(int channel, int value){// TLC to UPDATE TLC to UPDATE TLC to UPDATE TLC to UPDATE
// This routine needs to happen as fast as possible!!!
//delayMicroseconds(10);//to control speed if necessary
//Limit check
  if(value>4095)
  value=4095;
  if(value<0)
  value=0;
  
   // We need to convert the 12 bit value into an 8 bit BYTE, the SPI can't write 12bits
   
   //We figure out where in all of the bytes to write to, so we don't have to waste time
   // updating everything
   
   //12 bits into bytes, a start of 12 bits will either at 0 or 4 in a byte
    spibit=0;
    if(bitRead(channel, 0))//if the read of the value is ODD, the start is at a 4
    spibit=4;
    
    //This is a simplification of channel * 12 bits / 8 bits
    spibyte = int(channel*3/2);//this assignes which byte the 12 bit value starts in
  
    for(chbit=0; chbit<12; chbit++, spibit++) // start right at where the update will go
    {         
        if(spibit==8)//during the 12 bit cycle, the limit of byte will be reached
        {
        spibyte++;//roll into the next byte
        spibit=0;//reset the bit count in the byte
        }
  
        
        if(bitRead(value, chbit))         //check the value for 1's and 0's
        {
           bitSet(transferbyte[spibyte], spibit);//transferbyte is what is written to the TLC
        }
        else
        {
           bitClear(transferbyte[spibyte], spibit);
        }
    }//0-12 bit loop
  
  }//  END OF TLC WRITE  END OF TLC WRITE  END OF TLC WRITE  END OF TLC WRITE  END OF TLC WRITE
  //*******************************************************************************************
 
void VccControl(){
  
 REG_PIOC_CODR = 0x1 << 22;//74595 LATCH LOW
  switch(LEDZ)
  { 
    case   0: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[0]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[1]);break;  
    case   1: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[0]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[2]);break;                 
    case   2: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[0]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[3]);break;  
    case   3: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[0]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[4]);break;
    case   4: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[0]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[5]);break;  
    case   5: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[0]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[6]);break;
    case   6: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[0]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[7]);break;  
    case   7: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[0]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[8]);break;
    case   8: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[1]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[0]);break;  
    case   9: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[2]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[0]);break;
    case  10: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[3]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[0]);break;  
    case  11: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[4]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[0]);break;
    case  12: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[5]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[0]);break;  
    case  13: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[6]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[0]);break;
    case  14: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[7]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[0]);break;  
    case  15: shiftOut(11, 12, MSBFIRST, high_numberToDisplay[8]); shiftOut(11, 12, MSBFIRST, low_numberToDisplay[0]);break; 
  }
  
  REG_PIOC_SODR = 0x1 << 22;//74595 LATCH HIGH
  LEDZ++;
  if(LEDZ==16)
  {
    LEDZ=0;
  }
}
 | 
 |