Jump to content
43oh

zeke

Members
  • Content Count

    1,782
  • Joined

  • Last visited

  • Days Won

    102

Reputation Activity

  1. Like
    zeke got a reaction from jsolarski in e2e website is like a chicken coop   
    I went over to the e2e.ti.com website today just to see what's going on.
     
    I gotta say, if you could hear it out loud, that place would be like the Grand Central Station of chicken coops!
     
    There's a zillion people asking questions and few answers coming back to them.
     
    I don't know if you could call that place "organized" chaos but you could call it chaotic.
     
    Too bad the TI guys don't hang out here. They'd find this forum like a pleasant trip to the Weekend Cottage at the Lake.
     
    Ooo! Maybe I shouldn't say anything. It might turn into an episode of The Great Outdoors!
  2. Like
    zeke got a reaction from GeekDoc in RGB LOLShield?   
    While surfing the Sure Electronics site tonight, I spotted these RGB LED's: CCand CA. 100 LEDs for $20.
     
    It got me thinking about making an RGB LED scrolling billboard.
     
    What do you think of a billboard that uses RGB LEDs instead of just one color?
    And PWM-able?
    With the obligatory MSP430 on it?
  3. Like
    zeke got a reaction from artifus in Flashing the missing DCO calibration constants   
    Hi Guys,
     
    I wanted to tack on my calibration code that I successfully used to calibrate my G2231 device.
     
    It's almost exactly like naturetm's code. The only difference is the setDCO() function has a little more fine tuning in it.
     
    Take a look and notice that the setDCO() function is slightly different. I stole the idea from a post aBUGSworstnightmare made on the ti.com website. Here's the link.
     

    //****************************************************************************** // MSP430F20xx Demo - DCO Calibration Constants Programmer // // NOTE: THIS CODE REPLACES THE TI FACTORY-PROGRAMMED DCO CALIBRATION // CONSTANTS LOCATED IN INFOA WITH NEW VALUES. USE ONLY IF THE ORIGINAL // CONSTANTS ACCIDENTALLY GOT CORRUPTED OR ERASED. // // Description: This code re-programs the F2xx DCO calibration constants. // A software FLL mechanism is used to set the DCO based on an external // 32kHz reference clock. After each calibration, the values from the // clock system are read out and stored in a temporary variable. The final // frequency the DCO is set to is 1MHz, and this frequency is also used // during Flash programming of the constants. The program end is indicated // by the blinking LED. // ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = target DCO // //* External watch crystal installed on XIN XOUT is required for ACLK *// // // MSP430F20xx // --------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | P1.0|--> LED // | P1.4|--> SMLCK = target DCO // // A. Dannenberg // Texas Instruments Inc. // May 2007 // Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.42A //****************************************************************************** //#include "msp430x20x1.h" // do not forget to change this according to the device you're using #include #define DELTA_1MHZ 244 // 244 x 4096Hz = 999.4Hz #define DELTA_8MHZ 1953 // 1953 x 4096Hz = 7.99MHz #define DELTA_12MHZ 2930 // 2930 x 4096Hz = 12.00MHz #define DELTA_16MHZ 3906 // 3906 x 4096Hz = 15.99MHz unsigned char CAL_DATA[8]; // Temp. storage for constants volatile unsigned int i; int j; char *Flash_ptrA; // Segment A pointer void Set_DCO(unsigned int Delta); void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL3 |= XCAP_3; // Launchpad watch crystals need ~12.5 pF for (i = 0; i < 0xfffe; i++); // Delay for XTAL stabilization P1OUT = 0x00; // Clear P1 output latches P1SEL = 0x10; // P1.4 SMCLK output P1DIR = 0x11; // P1.0,4 output j = 0; // Reset pointer Set_DCO(DELTA_16MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(DELTA_12MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(DELTA_8MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Set_DCO(DELTA_1MHZ); // Set DCO and obtain constants CAL_DATA[j++] = DCOCTL; CAL_DATA[j++] = BCSCTL1; Flash_ptrA = (char *)0x10C0; // Point to beginning of seg A FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits *Flash_ptrA = 0x00; // Dummy write to erase Flash seg A FCTL1 = FWKEY + WRT; // Set WRT bit for write operation Flash_ptrA = (char *)0x10F8; // Point to beginning of cal consts for (j = 0; j < 8; j++) *Flash_ptrA++ = CAL_DATA[j]; // re-flash DCO calibration data FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit while (1) { P1OUT ^= 0x01; // Toggle LED for (i = 0; i < 0x4000; i++); // SW Delay } } void Set_DCO(unsigned int Delta) // Set DCO to selected frequency { unsigned int Compare, Oldcapture = 0; BCSCTL1 |= DIVA_3; // ACLK = LFXT1CLK/8 TACCTL0 = CM_1 + CCIS_1 + CAP; // CAP, ACLK TACTL = TASSEL_2 + MC_2 + TACLR; // SMCLK, cont-mode, clear while (1) { while (!(CCIFG & TACCTL0)); // Wait until capture occured TACCTL0 &= ~CCIFG; // Capture occured, clear flag Compare = TACCR0; // Get current captured SMCLK Compare = Compare - Oldcapture; // SMCLK difference Oldcapture = TACCR0; // Save current captured SMCLK if (Delta == Compare) break; // If equal, leave "while(1)" else if (Delta < Compare) { DCOCTL--; // DCO is too fast, slow it down if (DCOCTL == 0xFF) // Did DCO roll under? if (BCSCTL1 & 0x0f) BCSCTL1--; // Select lower RSEL } else { DCOCTL++; // DCO is too slow, speed it up if (DCOCTL == 0x00) // Did DCO roll over? if ((BCSCTL1 & 0x0f) != 0x0f) BCSCTL1++; // Sel higher RSEL } } TACCTL0 = 0; // Stop TACCR0 TACTL = 0; // Stop Timer_A BCSCTL1 &= ~DIVA_3; // ACLK = LFXT1CLK }
     
    Concerning the mods that were made to the cmd file, I just threw them into the default files because I know that I'm going to forget to made the project edits that are suggested in the first post above.
     
    Just calibrate the g2231 first then use the code after.
  4. Like
    zeke reacted to RobG in Can't flash the MSP430 with Launchpad - stuck at step 0 :(   
    You should be changing target for the whole project:
    Right click on the project folder -> Build Properties... -> CCS Build -> General
    This will update all necessary files, like linker cmd file.
  5. Like
    zeke got a reaction from RobG in 4-bit LCD Code for 16x1 LCD (have the LCD's for sale too)   
    Sounds like your chainsaw needs some guards bolted onto it.
  6. Like
    zeke got a reaction from RobG in Timers, how do they work?   
    I agree, you could do this without test equipment.
     
    I have both a scope and a logic analyzer but the logic analyzer is perfect for this task.
     
    If you're in a buying mood, the Logic Sniffer is only $10 more than the Logic Shrimp.
     
    That's 32 channels versus 4 channels for $10 more. Hmm... Which to choose....
  7. Like
    zeke reacted to SugarAddict in TLC5940... no lights? - Solved (Code & video) (twice)   
    http://pastebin.com/0zeuLgTQ

    // I know that my commenting sucks ass... I'm not exactly working on a team project here :-P #define SetLow(port, pin) (port &= ~pin) #define SetHigh(port, pin) (port |= pin) #define Pulse(port, pin) do{SetHigh(port, pin);SetLow(port, pin);} while(0) #include "msp430g2231_mod.h" void Rotate(void); char dcdata[] = {0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F}; int gsdata[] = {0x0001, 0x0004, 0x0010, 0x0040, 0x0100, 0x0400, 0x0100, 0x0040, 0x0010, 0x0004, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}; int Counter = 0, CntrA = 0, CntrB = 0, data = 0; char dcsent = 0, rotator = 0; void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_16MHZ; // Set range DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation P1DIR |= (BIT1|BIT2|BIT3|BIT4|BIT5|BIT6|BIT7); // P1.1 XLAT, P1.5 SCLK, P1.3 BLANK, P1.4 DCPRG, P1.7 VPRG, P1.6 SIN, 1.2 GSCLK P1OUT &= ~(BIT1|BIT2|BIT4|BIT5|BIT6|BIT7); P1OUT |= (BIT3|BIT4|BIT7); CCTL0 = CCIE; // CCR0 interrupt enabled CCR0 = 300; TACTL = TASSEL_2 + MC_1 + ID_0; // SMCLK, Up _bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupt } // Timer A0 interrupt service routine #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A (void) { Counter++; if(Counter>1024) { Counter = 0; CntrA = 0; CntrB = 0; SetHigh(P1OUT,BIT3); Pulse(P1OUT,BIT1); if(rotator) Rotate(); rotator ^= 1; } if(!dcsent) { if((CntrA == 0) && (CntrB == 0)) data = dcdata[CntrA]; if(CntrA<16) { if(CntrB<6) { if(data & 0x0020) SetHigh(P1OUT,BIT6); else SetLow(P1OUT,BIT6); data <<= 1; CntrB++; Pulse(P1OUT,BIT5); } else { CntrA++; if(CntrA<16) { CntrB = 1; data = dcdata[CntrA]; if(data & 0x0020) SetHigh(P1OUT,BIT6); else SetLow(P1OUT,BIT6); data <<= 1; Pulse(P1OUT,BIT5); } } } if(CntrA==16) { Pulse(P1OUT,BIT1); CntrA = 0; CntrB = 0; dcsent = 1; SetLow(P1OUT,BIT7); } } else { if((CntrA == 0) && (CntrB == 0)) data = gsdata[CntrA]; if(CntrA<16) { if(CntrB<12) { if(data & 0x0800) SetHigh(P1OUT,BIT6); else SetLow(P1OUT,BIT6); data <<= 1; CntrB++; Pulse(P1OUT,BIT5); } else { CntrA++; if(CntrA<16) { CntrB = 1; data = gsdata[CntrA]; if(data & 0x0800) SetHigh(P1OUT,BIT6); else SetLow(P1OUT,BIT6); data <<= 1; Pulse(P1OUT,BIT5); } } } if(CntrA == 16) { Pulse(P1OUT,BIT1); SetLow(P1OUT,BIT3); if(dcsent == 1) { Pulse(P1OUT,BIT5); dcsent = 2; } CntrA = 17; } } if(CntrA==17) Pulse(P1OUT, BIT2); } void Rotate(void) { int data = gsdata[15]; for(CntrA = 15;CntrA > 0;CntrA--) { gsdata[CntrA] = gsdata[CntrA-1]; } gsdata[0] = data; data = 0; CntrA = 0; }


  8. Like
    zeke got a reaction from nickey in Question on these Resistors   
    Just to back up what Rob is saying...
     
    Find out how much current the relay requires to stay active. I think they call it Holding Current. That's how much current the NPN has to sink. Calculate the Collector resistor required. If Vcc = 12V and Ic = 10mA (this is the relay's holding current) then Rc = 12/0.01 or 1200 ohms.
     
    I also agree with Rob, the biasing resistors shown are not required because you want to saturate the NPN into the conduction state. The only resistor that you should have is a Collector resistor to limit the current flowing through the NPN's collector.
     
    I would also make sure to use the MSP430's internal pullup resistors on the I/O pin driving the NPN.
     
    I hope this info is helpful.
  9. Like
    zeke reacted to Mac in CC vs CA 7-Segment displays   
    Hi Zeke,
     
    It just occurred to me that you might be trying to duplicate Rob's Charlieplexed display. If that's the case, replace the NPN column driver transistors, as depicted in the CA example drawing below, with PNP transistors and wire the emitters to the CC pins and the collectors to ground instead of VCC. The display driver will use the same segment data array and will setup the DIR register(s) exactly the same way but you need to invert the pattern written to the OUT register(s).
     
    Cheerful regards, Mike

  10. Like
    zeke got a reaction from jsolarski in Can't flash the MSP430 with Launchpad - stuck at step 0 :(   
    It sounds like the TI drivers for the Launchpad are not installed yet.
     
    You should verify that your PC can see the LP in the Device Manager as a TI Comm Port.
     
    Assuming you're using Windows:
    - Press "WindowsKey R",
    - Enter "devmgmt.msc"
    - Expand "Ports (Com & LPT)"
     
    Do you now see "MSP430 Application UART (COM)" where is some number like "3"?
     
    If you don't see that then you have to plug in the Launchpad via a USB cable and press the F5 key in the Device Manager. That will cause the DM to refresh its list of devices.
     
    If the DM can't see the LP then your LP is most likely dead in the USB sense. :x
     
    If this is the case then this is the first time I have heard of an LP dieing and we're sorry for your loss.
     
    If you can see the LP then you're in action!
     
    If you want to use a different method to check out your LP then go get this program from Elpotronics. Install it. Fire it up. See if it can see your LP. If so then you're in business. If not then we weep for the loss of your LP :cry:
     
    Let's hope for the best.
  11. Like
    zeke got a reaction from RobG in Connector for 2013 target board with staples   
    That connector is a simple 0.050" spaced header which means that it's nothing exotic - just tiny.
     
    MDFLY has them suuuuuuuuper cheep.
     
    Male connectors.
     
    Female connectors.
     
    Cue the MC Hammer song "Can't Touch This".
     

    ..................
     
    Can't Touch This!

     
    Don't boo me. I just need more sleep.
  12. Like
    zeke reacted to RobG in TLC5940... no lights? - Solved (Code & video) (twice)   
    Have you seen Demystifying TLC5940 book?
    I started going through it after I got my samples, but due to lack of time I was never able to put it into use.
  13. Like
    zeke got a reaction from bluehash in Windows Programming?   
    I also discovered the Boost C++ libraries.
     
    They have a serial port library called ASIO which provides the resources for serial ports amongst other things.
     
    Google found example programs to show us how to use the libraries.
     
    This article shows how to use Boost::ASIO with Qt.
  14. Like
    zeke reacted to GeekDoc in Reading the ADC from any pin   
    nexusone1984:
     
    Don't forget that little "thumbs-up" symbol at the top right of a post. Use it to give "thanks" to the author.
     
    The number of "thanks" an author has received (and given) is shown in their info on the right of their posts. This helps others gauge the author's overall helpfulness and credibility.
  15. Like
    zeke reacted to RobG in CC vs CA 7-Segment displays   
    Are you sure? Most of what I did is CC. I think you are fine.
    To recap:
    CC - for common side, we usually use TPIC6C595, ULN2003, ULN2803, NPN transistors.
    CA - for common side, PNP transistors or n-channel MOSFETs like 2N7000.
  16. Like
    zeke reacted to nexusone1984 in CC vs CA 7-Segment displays   
    What are you using to drive the LED's?
     
    My LED temperature project using the CD4511 which is made to drive a Common cathode LED display.
     
    If you using something like a 74hc595, Just invert the data your sending.
     
    Where one becomes zero and zero becomes one.
     
    My 74hc595 output code:
     
    j = ~data; //add the '~' which will apply a Not logic and reverses the data bits.
     
    P1OUT &= ~BIT2; //ST_clock low
    for(i=0; i < 8; i++)
    {
    P1OUT &= ~BIT1; //SH_clock low
    if (j & 0x01)
    {
    P1OUT |= BIT0; set data high
    }else{
    P1OUT &= ~BIT0; set data low
    }
    P1OUT |= BIT1; //SH_clock high
    j = j>>1;
    }
    P1OUT |= BIT2; //ST_clock low
  17. Like
    zeke got a reaction from nickey in OK, in deeper water now...   
    Take a look at this google image search for relay driver circuit.
     
    There's some pretty good schematics that come up. You will see a theme amongst them all. An NPN driving a relay.
     
    Hopefully, one of them will click with you.
  18. Like
    zeke got a reaction from nickey in Loading final (non-debug) code to chip   
    Yes, there are debugging symbols inside the code. They don't take up much space.
     
    You remove them by changing the build type to release instead of debug.
     
    If you're using CCS then look in the top left window - "C/C++ Projects". See your Active Project? Hove your mouse over it and right click to bring up a menu.
     
    See the sixth option down from the top "Active Build Configuration". Make it change to "2- Release".
     
    Hit "Control B" to recompile and then you have your release build.
     
    The release file will be located in a new directory called Release in your active project. The filename will end with the extension ".out".
     
    If you convert this file to a ".hex" then you can use an external program to load it into the MSP.
  19. Like
    zeke got a reaction from bluehash in Loading final (non-debug) code to chip   
    Yes, there are debugging symbols inside the code. They don't take up much space.
     
    You remove them by changing the build type to release instead of debug.
     
    If you're using CCS then look in the top left window - "C/C++ Projects". See your Active Project? Hove your mouse over it and right click to bring up a menu.
     
    See the sixth option down from the top "Active Build Configuration". Make it change to "2- Release".
     
    Hit "Control B" to recompile and then you have your release build.
     
    The release file will be located in a new directory called Release in your active project. The filename will end with the extension ".out".
     
    If you convert this file to a ".hex" then you can use an external program to load it into the MSP.
  20. Like
    zeke reacted to RobG in LaunchPad, DC Motor, PWM   
    Here's my little demo of how to use SN754410 with LaunchPad.
    Timer's CCR1 is used to control duty cycle via P1.2
    P1.0 and P1.1 to control direction (setting both to the same level, 0 or 1, will cause dynamic breaking.)
    Vcc1 of SN754410 is connected to LP's Vcc, Vcc2 is connected to a separate power supply (6V in my case.)
    Between outputs and Vcc/Vss I put some Schottky's just in case.
     
    EDIT: SN754410 logic side (Vcc1) requires 5V, it may not work correctly when powered from LP's Vcc.
     
    Next week I will add more examples with bigger motor and some MOSFETs.
     


     

     

    #include // DEMO counter unsigned int demoCounter = 0; void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1OUT |= BIT1; // Direction control - left P1OUT &= ~BIT0; // Direction control - right // Both 0 or 1 - dynamic break P1DIR |= BIT0 + BIT1 + BIT2; // Bit 2 is connected to enable and will be used for PWM P1SEL |= BIT2; // P1.2 TA1 option select CCTL0 = CCIE; // CCR0 interrupt enabled CCR0 = 1000; // ~8ms CCTL1 = OUTMOD_3; // CCR1 set/reset CCR1 = 950; // CCR1 duty cycle, slow in the beginning TACTL = TASSEL_2 + MC_1 + ID_3; // SMCLK/8, upmode _bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupt } // Timer A0 interrupt service routine #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A (void) { // DEMO movement demoCounter++; if(demoCounter == 800) CCR1 = 900; if(demoCounter == 1600) CCR1 = 500; if(demoCounter == 2000) CCR1 = 250; if(demoCounter == 2400) CCR1 = 0; if(demoCounter == 2800) CCR1 = 900; if(demoCounter == 3200) { P1OUT |= BIT0; // switch direction P1OUT &= ~BIT1; } if(demoCounter == 3600) CCR1 = 0; if(demoCounter == 4000) CCR1 = 900; if(demoCounter == 4400) { P1OUT |= BIT1; // switch direction P1OUT &= ~BIT0; } if(demoCounter == 4800) { P1OUT |= BIT0; // switch direction P1OUT &= ~BIT1; } if(demoCounter == 5200) { CCR1 = 500; P1OUT |= BIT1; // switch direction P1OUT &= ~BIT0; demoCounter = 0; } // END DEMO movement }
  21. Like
    zeke got a reaction from NatureTM in TI buying National Semiconductor   
    Uhm... National Semiconductor != NXP Semiconductors
     
    If it did then this announcement would be even bigger than it is.
  22. Like
    zeke got a reaction from PentiumPC in PCB Layout Tutorial   
    Some of you guys may already be aware of Dave Jones from Australia.
     
    He's the guy who does the Elelctronics Enigneering Video Blog
     
    Well, a while ago, he put together a tutorial on PCB Design and Layout.
     
    Here's a direct link to his tutorial pdf.
     
    If you want to make some PCB's and you're a newbie then do yourself a favor and check it out. I'm reading it right now.
  23. Like
    zeke got a reaction from cdch10 in PCB Layout Tutorial   
    Some of you guys may already be aware of Dave Jones from Australia.
     
    He's the guy who does the Elelctronics Enigneering Video Blog
     
    Well, a while ago, he put together a tutorial on PCB Design and Layout.
     
    Here's a direct link to his tutorial pdf.
     
    If you want to make some PCB's and you're a newbie then do yourself a favor and check it out. I'm reading it right now.
  24. Like
    zeke got a reaction from bluehash in Stand alone programming software   
    Hi Guys,
     
    Recently, I had to find a stand alone program that would give me the ability to program an MSP. This is for the factory floor. They don't want to use CCS on the factory floor, for obvious reasons.
     
    In my search, I found others asking the same question.
     
    There is the Gang Programmer.
     
    Or, you can use the Launchpad in combination with Elpotronic's FET-Pro430-Lite.
     
    I think Elpotronic's program is perfect. Give it the hex file and it will program your MSP430 using any TI USB programmer. It's cool that you can use Spy Bi-Wire to program your devices.
     
    Hope you like it.
  25. Like
    zeke reacted to RobG in [ ENDED ] April 2011 - 43oh Project of the Month Contest   
    Serial to 7 segment LED display driver v1
     
    This is a milestone for my project so I figured I will include it in this month's PotM.
    The idea behind it was to create a simple display driver which could communicate with my LaunchPad over 2 wires so I don't have to deal with shift registers, wiring, wasted ports, and display routines each time I work on a new project.
    There are 2 parts, driver board and display board. Schematic for the driver board is below, schematic for the display board is here.
    Input: 2 wire 16bit SPI
    Output: up to 8 seven segment LED displays, no decimal point (I decided not to include it with this version because 20pin chips are now available and things will get a lot easier.)
    Functions: Clear display, set single digit, set pair of digits (decimal or hex), set 4 digits (12 bit signed, but cannot show the sign, all you get is ABS,) scroll left, scroll right.
    Connector SV2 connects to display board.
    Connector SV1 allows easy pin reassignment for future I2C protocol support.
    Connector SV3: 1 - Vcc, 2 - clock, 3 - unused for SPI, 4 - data in, 5 - GND.
     




     
    Controller code

    #include "msp430g2231.h" // 0-9,A,b,c,d,E,F,blank,-,r,C,o,h,H,L,u,t,i,n,P,U,deg,= const unsigned char to7digit[32] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F, 0x77,0x7C,0x58,0x5E,0x79,0x71, 0x00,0x40,0x50,0x39,0x5C,0x74,0x76,0x38, 0x1C,0x78,0x18,0x54,0x73,0x3E,0x63,0x48}; const unsigned char digitSelector[8] = {BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7}; const unsigned char mask2 = 0xC0; const unsigned char mask1 = 0x3F; const unsigned char mask1spi = 0x5F; unsigned char tmpDIR = 0; unsigned char tmpOUT = 0; unsigned char digit = 0; unsigned char digitData[8] = {16,16,16,16,16,16,16,16}; unsigned int rxData = 0; unsigned char rxDataL = 0; unsigned char rxDataH = 0; unsigned char switchVar = 0; unsigned char negative = 0; unsigned char blankChar = 16; void main() { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; CCTL0 = CCIE; CCR0 = 125; TACTL = TASSEL_2 + MC_1 + ID_3; P2SEL &= ~(BIT6|BIT7); USICTL0 |= USIPE7 + USIPE5; USICTL1 |= USICKPH + USICKPL + USIIE; USICTL0 &= ~USISWRST; USICNT = 16 | USI16B; __enable_interrupt(); while(1) { } } // USI interrupt service routine #pragma vector = USI_VECTOR __interrupt void USI_RX (void) { //SPI rxData = USISR; rxDataL = USISRL; rxDataH = USISRH; USICNT |= 16; switchVar = rxDataH & 0xE0; switch(switchVar) { case 0xA0: //10100AAADDDDDDDD (A0xxh-A7xxh) Set A digit to D (0-255, anything above 32 will be useless) //10101000AAADDDDD (A8xxh) Set A digit to D, pretty much as above, but limited to 32 characters //(how many meaningful can you do with 7 segment anyway?) switchVar = rxDataH & 0xF8; switch(switchVar) { case 0xA8: switchVar = rxDataL & 0xE0; switchVar >>= 5; digitData[switchVar] = rxDataL & 0x1F; break; case 0xA0: switchVar = rxDataH & 0x07; digitData[switchVar] = rxDataL; // TODO 32+ are not available at this time, will produce unexpected results break; } break; case 0x80: //100000AADDDDDDDD (80xxh-83xxh) Set 2 digits to 8 bit unsigned value (convert to BCD) A=0 digits 0-1, etc. //Value can be 0-99 (score boards with 4 sets of 2 digits?) //100001AADDDDDDDD (84xxh-87xxh) As above, but no BCD conversion, just HEX switchVar = rxDataH & 0xFC; switch(switchVar) { case 0x80: switchVar = rxDataH & 0x03; switchVar <<= 1; digitData[switchVar + 1] = blankChar; digitData[switchVar] = 0; //TODO values bigger than 99 will overflow, check and display overflow while(rxDataL > 0) { digitData[switchVar] = rxDataL % 10; rxDataL /= 10; switchVar++; } break; case 0x84: switchVar = rxDataH & 0x03; switchVar <<= 1; digitData[switchVar] = rxDataL & 0x0F; digitData[switchVar + 1] = rxDataL >> 4; break; } break; case 0xC0: //110ADDDDDDDDDDDD (Cxxxh, Dxxxh) Set 4 digits to 12 bit signed integer (convert to BCD) //A=0 digits 0-3, A=1 digits 4-7, D= signed 12 bit integer, //DP of digits 0 and 4 should be connected to "-" LEDs, //value can be 0-1999 with floating decimal point and "-" sign switchVar = 0; if(rxData & BITC) switchVar = 4; // first digit is 4 digitData[switchVar] = 0; digitData[switchVar + 1] = blankChar; digitData[switchVar + 2] = blankChar; digitData[switchVar + 3] = blankChar; rxData &= 0x0FFF; negative = 0; if(rxData & BITB) { negative = 1; rxData = -(rxData); } while(rxData > 0) { digitData[switchVar] = rxData % 10; rxData /= 10; switchVar++; } //TODO handle negative sign //decimal point has to be set with another cmd //also, when DP will determine blank digits, 0.0 0.00 break; case 0xE0: //111XXXXXXXXXXXXX (Exxxh, Fxxxh) Set configuration values like leading 0 blank, etc. switchVar = rxDataH; switch(switchVar) { case 0xE0: // set blank char to 0 blankChar = 0; break; case 0xE1: // set blank char to, well, blank blankChar = 16; break; case 0xEF: // clear display by setting all digits to blank char switchVar = 0; while(switchVar < 8) { digitData[switchVar] = blankChar; switchVar++; } break; case 0xE2: // scroll left switchVar = 7; while(switchVar > 0) { digitData[switchVar] = digitData[switchVar - 1]; switchVar--; } digitData[0] = rxDataL & 0x1F; break; case 0xE3: // scroll right switchVar = 0; while(switchVar < 7) { digitData[switchVar] = digitData[switchVar + 1]; switchVar++; } digitData[7] = rxDataL & 0x1F; break; } break; } } // Timer A0 interrupt service routine #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A (void) { P1OUT &= ~mask1spi; //spi P2OUT &= ~mask2; P1DIR &= ~mask1spi; //spi P2DIR &= ~mask2; tmpDIR = to7digit[digitData[digit]]; tmpOUT = digitSelector[digit]; if(tmpDIR & tmpOUT) tmpDIR |= BIT7; tmpDIR |= digitSelector[digit]; P1DIR |= tmpDIR & mask1spi; P1OUT |= tmpOUT & mask1spi; P2DIR |= tmpDIR & BIT7; //spi P2OUT |= tmpOUT & BIT7; //spi tmpDIR <<= 1; //spi tmpOUT <<= 1; //spi P2DIR |= tmpDIR & BIT6; //spi P2OUT |= tmpOUT & BIT6; //spi digit++; if (digit == 8) digit = 0; }
     
    Master code for testing purposes

    #include unsigned int number = 0; unsigned int digit = 0; unsigned int data = 0; void main(void) { WDTCTL = WDTPW + WDTHOLD; // ---- this is whats needed to send USICTL0 |= USIPE6 + USIPE5 + USIMST + USIOE; USICTL1 |= USICKPH + USICKPL + USIIE; USICKCTL = USIDIV_7 + USISSEL_2; USICTL0 &= ~USISWRST; USICNT = USI16B; // --------------------------------- _delay_cycles(2000); _bis_SR_register(GIE); int n = 0; int d = 0; // ------------------------- // example of how to clear display and set blank char while(n < 2) { USISRH = 0xE0; //set blank char to 0 USICNT |= 16; _delay_cycles(2500); //wait for USI to finish sending USISRH = 0xEF; //clear display USICNT |= 16; _delay_cycles(1000000); //delay 1s USISRH = 0xE1; //set blank char to "blank" USICNT |= 16; _delay_cycles(2500); USISRH = 0xEF; //clear display USICNT |= 16; _delay_cycles(1000000); n++; } // ------------------------- // ------------------------- // example of how to set single digits, scrolls through all available chars for(n = 0; n<32; n++) { //n is character number to be displayed for(d = 0; d<8; d++) { //d is digit number data = d; data <<=5; //digit number is in bits 5-7 data |= n; //char number is in bits 0-4 USISRL = data; USISRH = 0xA8; //command to set single digit USICNT |= 16; _delay_cycles(20000); } } // ------------------------- _delay_cycles(1000000); // ------------------------- // clear display USISRH = 0xE1; USICNT |= 16; _delay_cycles(2500); USISRH = 0xEF; USICNT |= 16; _delay_cycles(2500); // ------------------------- // ------------------------- // example of how to set a pair of digits // this one sets digits 2-3 to decimal representation of n // n must be in the range of 0-99 // if n is <10, left digit will be blanked with blank char. for(n = 0; n<100; n++) { USISRL = n; USISRH = 0x81; //cmd to set pair 2-3 to BCD USICNT |= 16; _delay_cycles(100000); } // ------------------------- // ------------------------- // example of how to set a pair of digits // this one sets digits 4-5 to decimal representation of n // n must be in the range of 0-99 // if n is <10, left digit will be blanked with blank char. for(n = 0; n<100; n++) { USISRL = n; USISRH = 0x82; //cmd to set pair 4-5 to BCD USICNT |= 16; _delay_cycles(50000); } // ------------------------- // ------------------------- // example of how to set a pair of digits // this one sets digits 0-1 to hex value of n // n must be in the range of 00-FF for(n = 0; n<256; n++) { USISRL = n; USISRH = 0x84; //cmd to set pair 0-1 to hex USICNT |= 16; _delay_cycles(50000); } // ------------------------- _delay_cycles(1000000); // ------------------------- // clear display USISRH = 0xEF; USICNT |= 16; _delay_cycles(2500); // ------------------------- // ------------------------- // example of how to use 12 bit value, digits 0-3 // i must in the range of -1999 to 1999 int i = 0; for(i = 0; i<2000; i+=5) { USISR = i; USISRH |= 0xC0; USICNT |= 16; _delay_cycles(20000); } // ------------------------- _delay_cycles(1000000); // ------------------------- // another example USISRH = 0xEF; USICNT |= 16; _delay_cycles(2500); const char toSend[12] = {0,15,1,30,2,3,3,2,4,31,5,25}; //digit,char,digit,char... t=23oF for(i = 0; i<12; i+=2) { USISRL = (toSend[i] << 5) | toSend[i + 1]; USISRH = 0xA8; //command to set single digit USICNT |= 16; _delay_cycles(2500); } for(i = 4; i<10; i++) { USISRL = (2 << 5) | i; USISRH = 0xA8; //command to set single digit USICNT |= 16; _delay_cycles(1000000); } // ------------------------- _delay_cycles(2000000); // ------------------------- // another example // send an array USICTL1 &= ~USIIE; USISRH = 0xEF; USICNT |= 16; _delay_cycles(2500); const char array[4] = {21,20,3,4}; //char,char,... in reversed order d = 3; // start position for(i = 0; i<4; i++) { USISRL = (d << 5) | array[i]; USISRH = 0xA8; //command to set single digit USICNT |= 16; _delay_cycles(2500); d++; } // ------------------------- _delay_cycles(1000000); // ------------------------- // scroll example for(i = 0; i<8; i++) { USISRH = 0xE3; // scroll right USISRL = 16; // new char, blank USICNT |= 16; _delay_cycles(150000); } // ------------------------- const char msg[12] = {22,14,23,23,0,16,4,3,20,21,16,16}; for(i = 0; i<12; i++) { USISRH = 0xE2; // scroll left USISRL = msg[i]; // new char from an array USICNT |= 16; _delay_cycles(150000); } _delay_cycles(1000000); const char msg2[27] = {5,14,18,26,10,23,16,25,20,16,23,14,13,16,23,10,24,27,12,21,16,28,10,13,16,16,16}; for(i = 0; i<27; i++) { USISRH = 0xE2; // scroll left USISRL = msg2[i]; // new char from an array USICNT |= 16; _delay_cycles(150000); if(i==6 || i==12 || i==20) _delay_cycles(1000000); } while(1) { } } // --- this may be used, but ISR is not required if dealing directly with IF. // USI interrupt service routine #pragma vector = USI_VECTOR __interrupt void USI_TX (void) { USICTL1 &= ~USIIFG; // logic to send could be here }
×
×
  • Create New...