Jump to content
43oh

mnpumar

Members
  • Content Count

    41
  • Joined

  • Last visited

Reputation Activity

  1. Like
    mnpumar reacted to MishoOo in MSP430 UART   
    Here is the modified code that i used to controll 2 H-Bridges with the launchpad:
     

    //****************************************************************************** // MSP430G2xx2 Demo - Timer_A, Ultra-Low Pwr UART 9600 Echo, 32kHz ACLK // // Description: Use Timer_A CCR0 hardware output modes and SCCI data latch // to implement UART function @ 9600 baud. Software does not directly read and // write to RX and TX pins, instead proper use of output modes and SCCI data // latch are demonstrated. Use of these hardware features eliminates ISR // latency effects as hardware insures that output and input bit latching and // timing are perfectly synchronised with Timer_A regardless of other // software activity. In the Mainloop the UART function readies the UART to // receive one character and waits in LPM3 with all activity interrupt driven. // After a character has been received, the UART receive function forces exit // from LPM3 in the Mainloop which configures the port pins (P1 & P2) based // on the value of the received byte (i.e., if BIT0 is set, turn on P1.0). // ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO // //* An external watch crystal is required on XIN XOUT for ACLK *// // // MSP430G2xx2 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | CCI0B/TXD/P1.1|--------> // | | 9600 8N1 // | CCI0A/RXD/P1.2|<-------- // // D. Dang // Texas Instruments Inc. // December 2010 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include "msp430g2452.h" //------------------------------------------------------------------------------ // Hardware-related definitions //------------------------------------------------------------------------------ #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0) #define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A) //------------------------------------------------------------------------------ // H-Bridge Transistors Definitions //------------------------------------------------------------------------------ #define LEFT BIT3 //P2.3 #define RIGHT BIT4 //P2.4 #define BCK BIT5 //P2.5 #define FWD BIT6 //P1.6 //------------------------------------------------------------------------------ // Conditions for 9600 Baud SW UART, SMCLK = 1MHz //------------------------------------------------------------------------------ #define UART_TBIT_DIV_2 (1000000 / (9600 * 2)) #define UART_TBIT (1000000 / 9600) //------------------------------------------------------------------------------ // Global variables used for full-duplex UART communication //------------------------------------------------------------------------------ unsigned int txData; // UART internal variable for TX unsigned char rxBuffer; // Received UART character //------------------------------------------------------------------------------ // Function prototypes //------------------------------------------------------------------------------ void TimerA_UART_init(void); void TimerA_UART_tx(unsigned char byte); void TimerA_UART_print(char *string); //------------------------------------------------------------------------------ // main() //------------------------------------------------------------------------------ volatile unsigned int flagFWD=0, flagBACK=0; void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer DCOCTL = 0x00; // Set DCOCLK to 1MHz BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1OUT = 0x00; // Initialize all GPIO P1SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins P1DIR = 0xFF & ~UART_RXD; // Set all pins but RXD to output P2OUT = 0x00; P2SEL = 0x00; P2DIR = 0xFF; __enable_interrupt(); TimerA_UART_init(); // Start Timer_A UART TimerA_UART_print("Mihai Tautu FILS - 2012\r\n"); TimerA_UART_print("Verbindung erstellt\r\n"); for (; { // Wait for incoming character __bis_SR_register(LPM0_bits); if(rxBuffer == 0x77) //w sent from keyboard { TimerA_UART_print("goForward\r\n"); P2OUT &= ~(BCK | LEFT | RIGHT); P1OUT |= FWD; flagFWD = 1; flagBACK = 0; } if(rxBuffer == 0x73) //s sent from keyboard { TimerA_UART_print("goBack\r\n"); P1OUT &= ~FWD; P2OUT &= ~(LEFT | RIGHT); P2OUT |= BCK; flagFWD = 0; flagBACK = 1; } if(rxBuffer == 0x61) //a sent from Keyboard { P2OUT &= ~RIGHT; P2OUT |= LEFT; if(flagFWD == 1) TimerA_UART_print("goForward+Left\r\n"); else if(flagBACK == 1) TimerA_UART_print("goBack+Left\r\n"); else TimerA_UART_print("goLeft\r\n"); } if(rxBuffer == 0x64) //d sent from Keyboard { P2OUT &= ~LEFT; P2OUT |= RIGHT; if(flagFWD == 1) TimerA_UART_print("goForward+Right\r\n"); else if(flagBACK == 1) TimerA_UART_print("goBack+Right\r\n"); else TimerA_UART_print("goRight\r\n"); } if(rxBuffer == 0x78) //x { TimerA_UART_print("STOP\r\n"); P1OUT &= ~FWD; P2OUT &= ~(RIGHT | BCK | LEFT); flagFWD = 0; flagBACK = 0; } // Echo received character //TimerA_UART_tx(rxBuffer); } } //------------------------------------------------------------------------------ // Function configures Timer_A for full-duplex UART operation //------------------------------------------------------------------------------ void TimerA_UART_init(void) { TACCTL0 = OUT; // Set TXD Idle as Mark = '1' TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode } //------------------------------------------------------------------------------ // Outputs one byte using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_tx(unsigned char byte) { while (TACCTL0 & CCIE); // Ensure last char got TX'd TACCR0 = TAR; // Current state of TA counter TACCR0 += UART_TBIT; // One bit time till first bit TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int txData = byte; // Load global variable txData |= 0x100; // Add mark stop bit to TXData txData <<= 1; // Add space start bit } //------------------------------------------------------------------------------ // Prints a string over using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_print(char *string) { while (*string) { TimerA_UART_tx(*string++); } } //------------------------------------------------------------------------------ // Timer_A UART - Transmit Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A0_ISR(void) { static unsigned char txBitCnt = 10; TACCR0 += UART_TBIT; // Add Offset to CCRx if (txBitCnt == 0) { // All bits TXed? TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt txBitCnt = 10; // Re-load bit counter } else { if (txData & 0x01) { TACCTL0 &= ~OUTMOD2; // TX Mark '1' } else { TACCTL0 |= OUTMOD2; // TX Space '0' } txData >>= 1; txBitCnt--; } } //------------------------------------------------------------------------------ // Timer_A UART - Receive Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMER0_A1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch (__even_in_range(TA0IV, TA0IV_TAIFG)) { // Use calculated branching case TA0IV_TACCR1: // TACCR1 CCIFG - UART RX TACCR1 += UART_TBIT; // Add Offset to CCRx if (TACCTL1 & CAP) { // Capture mode = start bit edge TACCTL1 &= ~CAP; // Switch capture to compare mode TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0 } else { rxData >>= 1; if (TACCTL1 & SCCI) { // Get bit waiting in receive latch rxData |= 0x80; } rxBitCnt--; if (rxBitCnt == 0) { // All bits RXed? rxBuffer = rxData; // Store in global variable rxBitCnt = 8; // Re-load bit counter TACCTL1 |= CAP; // Switch compare to capture mode __bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR) } } break; } } //------------------------------------------------------------------------------
     
    You can compare my code with the standard TI Demo code and see what i have done to open PINs when specific characters are sent thru a Terminal Program
     
    I have attached u a Terminal programm. U will use that to communicate with your launchpad. You will have to select the COMM port on witch your launchpad is (check windows device manager for MSP430 UART COMM port). In the termianl program you have to select the proper baudrate.
     
    P.S I am using the msp430g2452 on my Launchpad. So you will have to change the "#include "msp430g2452.h" with something proper to your device.
    Terminal.rar

  2. Like
    mnpumar got a reaction from rivalslayer in Digital LED Clock   
    So here it is: (EDIT: the forum seems to be cutting off some of the pictures to the right, if you'd like to see the full version of them, go here: http://img718.imageshack.us/gal.php?g=25703750f.png)
     

     

     
    4 MSP430's working together
     

     

     

     

     

     
    The whole thing runs off a single 9V battery. The two digits for the hours are connected to one MSP430, and the two digits that make up the minutes are each connected to separate MSP430s. The whole thing is controlled by another MSP430 which keeps the time.
     
    The itself clock has two modes, one mode where it counts time 60x faster and counts 1 minute as one second. The other mode is where it runs like a normal clock. If you guys would like more information, please let me know. It took me a couple all-nighters to get it all wired together on a breadboard, but I managed to get it all done Can't wait to see what my professor thinks about it, haha.
     
    Special thanks to Simplevar, GeekDoc, cde, and everyone else on this forum for answering all my questions, I couldn't have done it without you guys!
    MSP430_Digital_LED_Clock_Schematic.pdf
    MSP430_Digital_LED_Clock_Code.zip
  3. Like
    mnpumar got a reaction from bluehash in Digital LED Clock   
    So here it is: (EDIT: the forum seems to be cutting off some of the pictures to the right, if you'd like to see the full version of them, go here: http://img718.imageshack.us/gal.php?g=25703750f.png)
     

     

     
    4 MSP430's working together
     

     

     

     

     

     
    The whole thing runs off a single 9V battery. The two digits for the hours are connected to one MSP430, and the two digits that make up the minutes are each connected to separate MSP430s. The whole thing is controlled by another MSP430 which keeps the time.
     
    The itself clock has two modes, one mode where it counts time 60x faster and counts 1 minute as one second. The other mode is where it runs like a normal clock. If you guys would like more information, please let me know. It took me a couple all-nighters to get it all wired together on a breadboard, but I managed to get it all done Can't wait to see what my professor thinks about it, haha.
     
    Special thanks to Simplevar, GeekDoc, cde, and everyone else on this forum for answering all my questions, I couldn't have done it without you guys!
    MSP430_Digital_LED_Clock_Schematic.pdf
    MSP430_Digital_LED_Clock_Code.zip
  4. Like
    mnpumar reacted to simpleavr in P2.7 As Input?   
    see the second diagram in the following link
     
    http://www.rentron.com/Myke6.htm
     
    also, u should set P2DIR = 0 instead of P2DIR = BIT7, your P2IN can still get reading but it may not be reliable, if your P2OUT has also set BIT7 on (which u did not), u may even blow up a pin when u use a wire to poke around.
     
    from slau144e.pdf
     
     
    to do non-interrupt button de-bounce, i would
     
    . setup P2.7 as input, w/ pull-up enable
    P2DIR = 0;
    P2REN = BIT7;
    P2OUT = BIT7;
    . tie the button between P2.7 and Gnd (i.e. low activate)
    . use a counter for de-bouncing.
     
    this setup will be input normally high and button press does a low trigger. u will want to capture the transition of low to high (button release) for your activities.

    while (1) { // u thing here, may be display display(i); unsigned wait=0; while (!(P2IN & BIT7) wait++; // P2.7 is low, we have a key-press, wait it out // we will only consider it as a trigger if it takes wait to reach at least 20 counts // this will avoid / skip those button jitters, if no good, try a higher value if (wait > 20) { // or try some other value i++; if (i>=12) i=0; } }
     
    i haven't tried the code, just look right to me. if u tried it and still have problems, i will try something for u.
  5. Like
    mnpumar reacted to simpleavr in HELP! What am I doing wrong????   
    for breadboarding (w/o debugger connection and eventually w/o launchpad), u need to tie the RESET pin to Vcc (3.3v) otherwise your firmware won't start.
     
    see this is my hookup, i am running the wires via the jumper block headers but it's the same.
     
    http://www.simpleavr.com/msp430-projects/3p4w-clock/3p4w04.jpg
  6. Like
    mnpumar reacted to simpleavr in Powering LEDs With MSP430 Output   
    be practical, if u are driving individual leds (or a few leds per segment), you need 4 x 9 segment = 36 transistors, it is a lot to do on a breadboard. each transistor has 3 pin, each led 2 pins, each resistor 2 pins will need hundreds of tie-points and the fact that breadboard are connected column-wise (5 points per column), it will be difficult if impossible to lay them out properly.
     
    switching from blue to red led is a wise move, u can drive them leds directly if eventually u want to do that. for blues, its not possible because of voltage being too low. get a few red leds and try laying out just one digit. if u are using 7-segment reds, i am sure u don't need transistors, or even eliminate resistors if u do some pwm like switch on / off rapidly.
     
    i like breadboarding and always breadboard if possible, and it is more difficult (and challenging) to do breadboard layout than to just grab a soldering iron and use a perfboard, if u are going to breadboard this, i would recommend fritzing, it allows u to work between breadboard layout and schematic at the same time and can generate decent documents. it still alpha but i am using it all along.
     
    http://www.fritzing.org
  7. Like
    mnpumar reacted to bluehash in Powering LEDs With MSP430 Output   
    Yes, if you look at the doc cde quoted before. Your LED would go in between R1 and Q1. Except in this case, 12V supply would be 5V and 5V would be ~3V at the MSP430 pin.
    Turn the pin High to turn the LED on, and Low to turn it off.

  8. Like
    mnpumar reacted to cde in Powering LEDs With MSP430 Output   
    Just another source:
    http://www.physics.unlv.edu/~bill/PHYS483/transbas.pdf
  9. Like
    mnpumar reacted to GeekDoc in Powering LEDs With MSP430 Output   
    A picture is worth a thousand words... maybe.
     

  10. Like
    mnpumar reacted to cde in Powering LEDs With MSP430 Output   
    No, not with a diode.
     
    The TI wiki has a nice page on driving an led from a msp430 with a transistor
    http://processors.wiki.ti.com/index.php ... _Drive_LED
     
    Its the basic NPN transistor usage. Output of the msp430 gpio tied to the Base pin of the transistor, with the Emitter pin tied to ground, and the Collector pin connected to the negative side of the led.
     
    For multiple leds, you can tie them in series, which means you need a higher voltage (3 blue leds at 3.6 typical voltage would require 10.8 volts atleast, with 12v being the standard voltage) and one resistor, or you can tie them in parallel, with just means more current at a lower voltage, and ideally 3 resistors (one per led).
    http://led.linear1.org/led.wiz
    Is an online led calc that can do both series and parallel wiring schematics, based on the information you put in. You just add the transistor to the end of it. And at this current rating (20ma in series, or 60ma in parallel) any general purpose npn transistor will work fine.
     
    Edit:
    As far as switching from the blue to the red leds, you would face the same issue. The voltage drop from the msp430's current output capacity might not affect them as bad (red leds tend to be 2.2v instead of blue's ~3.5v) but the more you power at a time, and depending on the brightness, the less the msp430 will be able to power.
     
    Think of the msp430 as a pool. Its big enough for 3 or 4 people to enjoy with plenty of room. The more people you add though, the less you can move around and enjoy. Eventually, it won't work for what you need.
  11. Like
    mnpumar reacted to bluehash in You can Thank users now!   
    Hi All,
    43oh has a new feature, where you can "Thank" users if their posts have been helpful to you. You will see a tiny "Thumbs Up" sign on the top right of every post, except yours..as you can't thank yourself :mrgreen: .
     
    This also adds two fields to your profile. Hope you guys like it and make use of it.. Thank away!
  12. Like
    mnpumar reacted to simpleavr in Keeping Track of Time?   
    yes, this is basic digital io. just don't mix it up with adc input.
    you check whether a pin is HI or LOW (meaning zero volts) by looking at the P1IN or P2IN registers (port 1 and port 2). and since it's digital there is only 0 or 1 (low / hi)
     
    so to detect a trigger from the master (assuming a low-hi-low pulse) you would.
    assuming your input pin is P1.1
     

    while (1) { if (PIIN &= BIT1) { // detect a rising edge (hi) while (P1IN &= BIT1); // wait for falling edge (low) // do your led display pin toggling here }//if }//while
     
    have not tried the above, i think it's the simplest, u may want to setup an interrupt to capture triggering pulse instead.
     
    i don't know about your micro-controller experience, but u should try to implement basic things, see them working and migrate to more advance features.
  13. Like
    mnpumar reacted to GeekDoc in Keeping Track of Time?   
    To answer the part that I do know: No, you cannot set a voltage other than Vcc on an output pin.
     
    What you are looking for is a Digital to Analog Converter (DAC) function, which the MSP430G2231/2211 do not have. The LaunchPad does have a nice ADC (Analog to Digital Converter), but that is obviously the opposite direction.
     
    I believe there are other MSP430 models with DAC functions, but I'm not sure if they are compatible with the LaunchPad. Others here are more familiar with the rest of the MSP430 line and may be able to help.
  14. Like
    mnpumar reacted to simpleavr in Keeping Track of Time?   
    if it can be made perfect, there will be no need to calibrate. from the datasheet the MSP430G2231 has a typical accuracy of plus/minus 3%, at idea case it's plus/minus 0.5%. if u can keep constant voltage and constant temperature, it will be more accurate. even crystals have some drifts and for accuracy u can match capacitors or even oven control them (for temperature).
     
    no, but u can make it happen by entering various LPM modes, for more power saving (LPM3) you will need to use VLO (or 32Khz crystal) as the DCO is also shut down.
    if u really want to showcase this, u can
    . inside the while loop, go to sleep LPM?, etc.
    . inside your timer interrupt do _BIC_SR_IRQ(LPM?_bits) to exit LPM when u got a second tick (actually u could remove the "second_passed" flag in this case as system would be asleep unless it passes a second.
    . you should use clock divider (divide by 8 at most) so that the system gets fewer interrupts and thus further power save.
    . i had made the quick example simple so that it's easy to understand. and if u can gain by showcasing more features in your project you should implement them (clock dividing, power saving, etc) once the basics is going OK.
     
    if an interrupt occurs, your processing will be suspended after the interrupts have been served. for multiple interrupts at the same time, there is also a defined priority list based on interrupt types (u can find them in datasheet).
    typically inside your interrupt routine u should disable further interrupts to avoid race conditions / re-entrance problems.
    and u should disable them during your critical processing (trigger slaves, etc).
    in this case we need the interrupts on all times to keep the time right and the logic processing is not that critical (triggering the slave is still safe if interrupted). but u surely can experiment w/ them, or showcase such consideration in your code.
    it won't happen, or u have to make it not happen, if your core logic requires that much cycles (like 1million cycles), u should revise them. (or setup to run faster).
     
    another note, if u implement LPM u may want to check the datasheet as there may be delays here and there when some MCU features are brought back from sleep, these may affects accuracy.
  15. Like
    mnpumar reacted to simpleavr in Keeping Track of Time?   
    the time keeping is the least thing u should worry about, i would worry about how to put the circuit together on a breadboard.
     
    here is the code needed to keep a no-so-accurate time (may be off a few minutes a day)
     
    it's taken and modified from the ti 2xx examples (slac080h.zip i think) msp430x20x3_ta_02.c
     
    i tried it on a EZ430 dongle and it's working as expected. i build w/ msg430-gcc but it should built under windows w/ CCS also.
     
    . use SMCLK at 1Mhz as based
    . use calibrated value for clock to maximize accuracy.
    . count to 50,000 to get a timer interrupt (20 times/sec)
    . another counter counts the clicks to 20 and resets it (we got one second here)
    . update a system 'clock' (ticks), this contains the seconds since midnight
    . also update a flag so that your main loop got signal to do something (advance slave digit counters?)
    . u need to add your own logic to get seconds, hours, etc by deriving them from the 'clock' ticks.
     
     

    // use timer_a to generate one second ticks // built with msg430-gcc, flash w/ mspdebug // #ifdef MSP430 #include "signal.h" #endif #include volatile unsigned char second_passed=0; // advance indicator volatile unsigned long ticks=0; // 'clock' in seconds void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz factory calibration value DCOCTL = CALDCO_1MHZ; P1DIR |= 0x01; // P1.0 output CCTL0 = CCIE; // CCR0 interrupt enabled CCR0 = 50000; TACTL = TASSEL_2 + MC_1; // SMCLK, upmode _BIS_SR(GIE); // enable interrupt while (1) { if (second_passed) { //____ do something w/ ticks // ? trigger via io slave MCUs etc second_passed = 0; }//if }//while //_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt } // Timer A0 interrupt service routine #ifdef MSP430 interrupt(TIMERA0_VECTOR) Timer_A(void) #else #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A (void) #endif { static unsigned int clicks=0; // we will get called at 1Mhz/50k = 20 times a seconds clicks++; if (clicks >= 20) { clicks = 0; ticks++; // advance clock for each second second_passed = 1; // have a flag to tell back main loop }//if // the followng can be a HHMM colon seperator led // take them out if not needed if (clicks >= 10) P1OUT |= 0x01; // half second on else P1OUT &= ~0x01; // half second off //P1OUT ^= 0x01; // Toggle P1.0 }
     
    if you are not to solder, i think u will need a very big breadboard or several smaller ones. either way, it will be bad hair day w/ all the jumpers (and almost impossible to debug).
     
    the design of using single leds will make it almost impossible to do a proper layout, also w/ some segment have 2/3 leds in series will requires u to have different resistor values (or different refresh rates if u do not use resistors).
     
    if u can replace them w/ 7-segment LEDs you will save yourself a lot of trouble.
     
    [EDIT] just noticed i forgot to enable interrupt (but it did worked anyway)
×
×
  • Create New...