Jump to content

Search the Community

Showing results for tags 'pwm'.

More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


  • News
    • Announcements
    • Suggestions
    • New users say Hi!
  • Spotlight!
    • Sponsor Spotlight
    • Sponsor Giveaways
  • Energia
    • Energia - MSP
    • Energia - TivaC/CC3XXX
    • Energia - C2000
    • Energia Libraries
  • MSP Technical Forums
    • General
    • Compilers and IDEs
    • Development Kits
    • Programmers and Debuggers
    • Code vault
    • Projects
    • Booster Packs
    • Energia
  • Tiva-C, Hercules, CCXXXX ARM Technical Forums
    • General
    • SensorTag
    • Tiva-C, Hercules, CC3XXX Launchpad Booster Packs
    • Code Vault
    • Projects
    • Compilers and IDEs
    • Development Kits and Custom Boards
  • Beagle ARM Cortex A8 Technical Forums
    • General
    • Code Snippets and Scripts
    • Cases, Capes and Plugin Boards
    • Projects
  • General Electronics Forum
    • General Electronics
    • Other Microcontrollers
  • Connect
    • Embedded Systems/Test Equipment Deals
    • Buy, Trade and Sell
    • The 43oh Store
    • Community Projects
    • Fireside Chat
  • C2000 Technical Forums
    • General
    • Development Kits
    • Code Vault
    • Projects
    • BoosterPacks


There are no results to display.

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start



Website URL





Found 44 results

  1. What is the preferred way to stop doing analogWrite (PWM) on a pin in Energia? For instance how should I change a pin to digitalWrite, or change it to input, or to just prepare to stop using the pin? In particular, how do you stop the timer (which is used to generate the PWM)? Studying the code for analogWrite, digitalWrite and pinMode I do not see where PWM timers are ever stopped once they are started. (I looked at the code on MSP430, Stellaris, and CC3200). To confirm my impression, I ran a little test on an MSP430. While I can change mode to output and/or do a digitalWrite to change the pin after doing an analogWrite, it appears that the timer just keeps ticking away, even though it is no longer controlling the pin. (I haven't tested this on the other platforms or tested whether changing the pin to input stops the timer.) Is there some glitch where the timers have to be left running once started? Why would one care if the timer keeps running? It uses power (or is this an insignificant amount of power, even on an MSP430 or CC3200 running on a battery). It might make bookkeeping a little easier if unused timers were stopped. (e.g. easier to tell which ones could safely be used for other purposes). Thanks.
  2. I found out from this post that there are 14 PWM outputs possible on the MSP430F5529 microcontroller, and 10 PWM outputs possible on the MSP430F5529 Launchpad. How many are possible when using Energia? I think it is less, but I can't tell from the .h file. I will be using a custom BoosterPack so it doesn't have to stick to that standard. Thanks, Ben
  3. hi , i'm trying to create a PWM signal with period of 15 msec and pulse width the can vary between 1.1 msec and 1.9 msec. (I'm using the Msp430F5529 ) how can i do it? thx in advance.
  4. Hello, I'm planning for a project the use of 12 Channels PWM (Frequency must be above 60khZ, because of driving some VCA´s and not getting into the audio range). As I know, Energia uses "software" PWM with the use of timers (the hardware PWM´s of the new TIVA's is not implimented). So my question is, may I can get some overall performance boost using the driverlib hardware PWM rather than the energia software version? Thanks regards Matthias
  5. The usual way to generate PWM with the MSP430 is to set the timer to up mode, CCR0 to the PWM period, and then use CCR1 and up in reset/set mode to set the PWM pulse width. This provides a precise hardware driven PWM with minimal CPU overhead. The only ISR required is the CCR0 interrupt so new PWM values can be updated without creating glitches. It is possible to use CCR0 to do PWM in addition to CCR1 and up by using continuous mode and output compare toggle mode. This requires an ISR for each CCR used. It is glitch free and allows different PWM periods for each output if desired. The basic ISR is simple: __interrupt void isr_ccr0(void) // - ISR for CCR0 { // static unsigned s = 0; // State static unsigned d; // On duration // TA1CCR0 += (s++ & 1) ? (pwm_period[0] - d) : (d = pwm_on[0]); } // Each time the ISR occurs, the output time is advanced in to the future. The lsb of a state variable toggles between adding the on duration or off duration to the previous time. When the lsb is 0, then the on duration is used, and also saved for later. When the lsb is 1, then the off duration is calculated from the saved on duration and the PWM period. Toggling of the output pin is automatic because the CCR output mode is set to toggle. Complete code for 3 PWM outputs using CCR0, CCR1, and CCR2 of Timer 1 #include <msp430.h> static unsigned pwm_on[3]; // PWM on duration static unsigned pwm_period[3]; // Total PWM period - on duration + off duration // #pragma vector = TIMER1_A0_VECTOR // - ISR for CCR0 __interrupt void isr_ccr0(void) // { // static unsigned s = 0; // State static unsigned d; // On duration // TA1CCR0 += (s++ & 1) ? (pwm_period[0] - d) : (d = pwm_on[0]); } // // #pragma vector = TIMER1_A1_VECTOR // - ISR for CCR1, CCR2 __interrupt void isr_ccr12(void) // { // static unsigned s1 = 0; // State static unsigned d1; // On duration static unsigned s2 = 0; // static unsigned d2; // // switch(TA1IV) { // case 0x02: // - CCR1 TA1CCR1 += (s1++ & 1) ? (pwm_period[1] - d1) : (d1 = pwm_on[1]); break; // case 0x04: // - CCR2 TA1CCR2 += (s2++ & 1) ? (pwm_period[2] - d2) : (d2 = pwm_on[2]); break; // } // } // // static void pwm_init(void) // { // P2DIR |= (BIT0 | BIT2 | BIT4); // PWM outputs on P2.0, P2.2, P2.4 P2SEL |= (BIT0 | BIT2 | BIT4); // Enable timer compare outputs P2SEL2 &= ~(BIT0 | BIT2 | BIT4); // // TA1CTL = TASSEL_2 | ID_3 | MC_2; // Setup timer 1 for SMCLK / 8, continuous mode // TA1CCTL0 = TA1CCTL1 = TA1CCTL2 = OUTMOD_4 | CCIE; // Set timer output to toggle mode, enable interrupt TA1CCR0 = TA1CCR1 = TA1CCR2 = TA1R + 1000; // Set initial interrupt time } // // int main(void) // { // WDTCTL = WDTPW | WDTHOLD; // // DCOCTL = 0; // Run DCO at 8 MHz BCSCTL1 = CALBC1_8MHZ; // DCOCTL = CALDCO_8MHZ; // // pwm_init(); // Initialize PWM // // Setup PWM period pwm_period[0] = pwm_period[1] = pwm_period[2] = 20000; pwm_on[0] = 1000; // Setup servo times pwm_on[1] = 1500; // pwm_on[2] = 2000; // // _enable_interrupts(); // Enable all interrupts // for(; { // } // // return 0; // } //
  6. Hi, Playing around with AnalogWrite and my scope: This little script toggles between two duty cycles: const int analogOutPin = 9; void setup() { pinMode (analogOutPin,OUTPUT); } void loop() { analogWrite(analogOutPin, 100); delay(15); analogWrite(analogOutPin, 150); delay(15); } below is how this looks on the scope, blue direct, yellow with a simple R-C lowpass. every now and then, when changing duty cycle, I get an extra-long pulse. I am using the G2553 on the launchpad, with xtal. I have seen on this forum that calling AnalogWrite when NOT changing the duty cycle should be avoided. But I DO sometimes want to change the duty cycle ;-) Tried the same on an Arduino Uno, no problem there, smooth transitions. any suggestions? maelli01
  7. Hi, I am trying to use the analog write function on energia and am having trouble. When I use the function on the inbuilt LEDs everything is working fine but when I use it on external circuits, if I use analogWrite(255)(the maximum) the led is staying on with the maximum brightness as it supposed to but for any other values, its off. In the example codes there is one which increases and decreases the brightness of the led periodically. For the in-built LED its working fine but for others, when the brightness is supposed to be maximum, the LED is staying on and all other time its off. Any help would be great. Thanks.
  8. How to change the output frequency of the analogWrite() function in Energia??
  9. L293D

    Auduino code

    I am sure everybody has seen the Auduino code (Grain synth for arduino). I don't really understand the way that the PWM is setup, so I have no idea how to make this work on the MSP430 (or if it even can). Could someone explain how the timers are setup in this code? and the interrupt vector as well? I am just curious how one would setup the timer on one of the MSP430's? // Auduino, the Lo-Fi granular synthesiser // // by Peter Knight, Tinker.it http://tinker.it // // Help: http://code.google.com/p/tinkerit/wiki/Auduino // More help: http://groups.google.com/group/auduino // // Analog in 0: Grain 1 pitch // Analog in 1: Grain 2 decay // Analog in 2: Grain 1 decay // Analog in 3: Grain 2 pitch // Analog in 4: Grain repetition frequency // // Digital 3: Audio out (Digital 11 on ATmega8) // // Changelog: // 19 Nov 2008: Added support for ATmega8 boards // 21 Mar 2009: Added support for ATmega328 boards // 7 Apr 2009: Fixed interrupt vector for ATmega328 boards // 8 Apr 2009: Added support for ATmega1280 boards (Arduino Mega) #include <avr/io.h> #include <avr/interrupt.h> uint16_t syncPhaseAcc; uint16_t syncPhaseInc; uint16_t grainPhaseAcc; uint16_t grainPhaseInc; uint16_t grainAmp; uint8_t grainDecay; uint16_t grain2PhaseAcc; uint16_t grain2PhaseInc; uint16_t grain2Amp; uint8_t grain2Decay; // Map Analogue channels #define SYNC_CONTROL (4) #define GRAIN_FREQ_CONTROL (0) #define GRAIN_DECAY_CONTROL (2) #define GRAIN2_FREQ_CONTROL (3) #define GRAIN2_DECAY_CONTROL (1) // Changing these will also requires rewriting audioOn() #if defined(__AVR_ATmega8__) // // On old ATmega8 boards. // Output is on pin 11 // #define LED_PIN 13 #define LED_PORT PORTB #define LED_BIT 5 #define PWM_PIN 11 #define PWM_VALUE OCR2 #define PWM_INTERRUPT TIMER2_OVF_vect #elif defined(__AVR_ATmega1280__) // // On the Arduino Mega // Output is on pin 3 // #define LED_PIN 13 #define LED_PORT PORTB #define LED_BIT 7 #define PWM_PIN 3 #define PWM_VALUE OCR3C #define PWM_INTERRUPT TIMER3_OVF_vect #else // // For modern ATmega168 and ATmega328 boards // Output is on pin 3 // #define PWM_PIN 3 #define PWM_VALUE OCR2B #define LED_PIN 13 #define LED_PORT PORTB #define LED_BIT 5 #define PWM_INTERRUPT TIMER2_OVF_vect #endif // Smooth logarithmic mapping // uint16_t antilogTable[] = { 64830,64132,63441,62757,62081,61413,60751,60097,59449,58809,58176,57549,56929,56316,55709,55109, 54515,53928,53347,52773,52204,51642,51085,50535,49991,49452,48920,48393,47871,47356,46846,46341, 45842,45348,44859,44376,43898,43425,42958,42495,42037,41584,41136,40693,40255,39821,39392,38968, 38548,38133,37722,37316,36914,36516,36123,35734,35349,34968,34591,34219,33850,33486,33125,32768 }; uint16_t mapPhaseInc(uint16_t input) { return (antilogTable[input & 0x3f]) >> (input >> 6); } // Stepped chromatic mapping // uint16_t midiTable[] = { 17,18,19,20,22,23,24,26,27,29,31,32,34,36,38,41,43,46,48,51,54,58,61,65,69,73, 77,82,86,92,97,103,109,115,122,129,137,145,154,163,173,183,194,206,218,231, 244,259,274,291,308,326,346,366,388,411,435,461,489,518,549,581,616,652,691, 732,776,822,871,923,978,1036,1097,1163,1232,1305,1383,1465,1552,1644,1742, 1845,1955,2071,2195,2325,2463,2610,2765,2930,3104,3288,3484,3691,3910,4143, 4389,4650,4927,5220,5530,5859,6207,6577,6968,7382,7821,8286,8779,9301,9854, 10440,11060,11718,12415,13153,13935,14764,15642,16572,17557,18601,19708,20879, 22121,23436,24830,26306 }; uint16_t mapMidi(uint16_t input) { return (midiTable[(1023-input) >> 3]); } // Stepped Pentatonic mapping // uint16_t pentatonicTable[54] = { 0,19,22,26,29,32,38,43,51,58,65,77,86,103,115,129,154,173,206,231,259,308,346, 411,461,518,616,691,822,923,1036,1232,1383,1644,1845,2071,2463,2765,3288, 3691,4143,4927,5530,6577,7382,8286,9854,11060,13153,14764,16572,19708,22121,26306 }; uint16_t mapPentatonic(uint16_t input) { uint8_t value = (1023-input) / (1024/53); return (pentatonicTable[value]); } void audioOn() { #if defined(__AVR_ATmega8__) // ATmega8 has different registers TCCR2 = _BV(WGM20) | _BV(COM21) | _BV(CS20); TIMSK = _BV(TOIE2); #elif defined(__AVR_ATmega1280__) TCCR3A = _BV(COM3C1) | _BV(WGM30); TCCR3B = _BV(CS30); TIMSK3 = _BV(TOIE3); #else // Set up PWM to 31.25kHz, phase accurate TCCR2A = _BV(COM2B1) | _BV(WGM20); TCCR2B = _BV(CS20); TIMSK2 = _BV(TOIE2); #endif } void setup() { pinMode(PWM_PIN,OUTPUT); audioOn(); pinMode(LED_PIN,OUTPUT); } void loop() { // The loop is pretty simple - it just updates the parameters for the oscillators. // // Avoid using any functions that make extensive use of interrupts, or turn interrupts off. // They will cause clicks and poops in the audio. // Smooth frequency mapping //syncPhaseInc = mapPhaseInc(analogRead(SYNC_CONTROL)) / 4; // Stepped mapping to MIDI notes: C, Db, D, Eb, E, F... //syncPhaseInc = mapMidi(analogRead(SYNC_CONTROL)); // Stepped pentatonic mapping: D, E, G, A, B syncPhaseInc = mapPentatonic(analogRead(SYNC_CONTROL)); grainPhaseInc = mapPhaseInc(analogRead(GRAIN_FREQ_CONTROL)) / 2; grainDecay = analogRead(GRAIN_DECAY_CONTROL) / 8; grain2PhaseInc = mapPhaseInc(analogRead(GRAIN2_FREQ_CONTROL)) / 2; grain2Decay = analogRead(GRAIN2_DECAY_CONTROL) / 4; } SIGNAL(PWM_INTERRUPT) { uint8_t value; uint16_t output; syncPhaseAcc += syncPhaseInc; if (syncPhaseAcc < syncPhaseInc) { // Time to start the next grain grainPhaseAcc = 0; grainAmp = 0x7fff; grain2PhaseAcc = 0; grain2Amp = 0x7fff; LED_PORT ^= 1 << LED_BIT; // Faster than using digitalWrite } // Increment the phase of the grain oscillators grainPhaseAcc += grainPhaseInc; grain2PhaseAcc += grain2PhaseInc; // Convert phase into a triangle wave value = (grainPhaseAcc >> 7) & 0xff; if (grainPhaseAcc & 0x8000) value = ~value; // Multiply by current grain amplitude to get sample output = value * (grainAmp >> 8); // Repeat for second grain value = (grain2PhaseAcc >> 7) & 0xff; if (grain2PhaseAcc & 0x8000) value = ~value; output += value * (grain2Amp >> 8); // Make the grain amplitudes decay by a factor every sample (exponential decay) grainAmp -= (grainAmp >> 8) * grainDecay; grain2Amp -= (grain2Amp >> 8) * grain2Decay; // Scale output to the available range, clipping if necessary output >>= 9; if (output > 255) output = 255; // Output to PWM (this is faster than using analogWrite) PWM_VALUE = output; } So really I would just like someone to explain: // Set up PWM to 31.25kHz, phase accurate TCCR2A = _BV(COM2B1) | _BV(WGM20); TCCR2B = _BV(CS20); TIMSK2 = _BV(TOIE2); and these defines: #define PWM_PIN 3 #define PWM_VALUE OCR2B #define PWM_INTERRUPT TIMER2_OVF_vect and if there is a way to setup one of the timers on the 2452 or 2553 to accomplish the same thing. As always, thanks very much. L293D
  10. Earlier this year I happened to be in Singapore in transit, and took the opportunity to visit Sim Lim Tower - a high-rise mall full of electronic components shops! Amazing place, and amongst other things (including super-cheap kits for the kids to build!) I picked up three 5x7 LED matrix panels for a dollar each (!!). They didn't have any part numbers that I could see, but after experimentation they turned out to be row-anode devices and once I figured out the pinout I decided to build a project out of them. As any of us who have children know, it's a daily battle to get kids to brush their teeth for long enough, and as any of us who have children also know, time spent on projects goes down better if there's a kid angle to it. So I decided to make a tooth brush timer, that will display a countdown from two minutes - interspersed with inspirational text and probably amusing patterns and other things to keep the kids entertained during their twice-daily two-minute ordeal. Poor things. Being given to doing things the hard way, I decided to design two boards - one for the LED panels, and one for the controller. I'll get to the controller board in a later post because it's quite complicated (since the board fab place makes 10 identical boards I decided to try to make it as multi-purpose as possible). The LED boards though are simpler, they just use a 4094 shift register to handle the columns (or rows, I decided to use my three matrices abutted end to end rather than side to side, giving me a display that's five LEDs high and twenty-one across. I found a nice 5x5 bitmap font on dafont.com, and decided that I had enough space for what I needed to display. Because if all the LEDs are on the 4094 will be over it's specified current limit, it drives the columns through seven PNP transistors. This meant quite a bit of routing, which is what led me to use a board fab house rather than attempt it all on veroboard. So, onto the code (I have attached the eagle files if anyone is interested). I wanted to use the USI module to drive the 4094's. Looking at the datasheet for a 4094, it clocks in it's data on a rising edge of the clock. So the USI module will need to be configured thusly (I'm running the CPU at 12Mhz). // Reset USI logic to allow configuration USICTL0 |= USISWRST; // Setup serial output for a 4094 shift register USICTL0 = USIPE6 // SDO enabled + USIPE5 // CLK enabled + USIMST // master mode + USIOE // output enable + USISWRST // leave in reset ; // clock phase = 1, interrupts enabled SICTL1 = USICKPH // phase = 1 + USIIE // interrupt enabled ; USICKCTL = USIDIV_4 // divide by 16, giving 500khz clock + USISSEL_2 // SMCLCK as clock source ; // release SPI for operation USICTL0 &= ~USISWRST; Now, the tricky part of this project is that I want to have greyscale (redscale!) on my LEDs. To do this I will have to not only row-scan the matrix, but also PWM each LED individually. And I want to do all this in the USI interrupt handler, and have a framebuffer in RAM that I can just write to at any time without having to worry about getting the LEDs to update. So first thing is the framebuffer, I'm just using one LED matrix at the moment so it's only a 5x7 array: unsigned char framebuffer[5][8]; // greyscale framebuffer So, for those unfamiliar with how to drive these types of LED matrices, here's a bullet-pointed flow-chart. Start at the first row. Clock bits into the 4094 shift register, corresponding to which LEDs in the current row are on. Because I'm using PNP transistors as high-side switches, a zero in the 4094 outputs will correspond to an LED being on. Once the bits are clocked in, set the 'strobe' input into the 4094 to high. This will latch the outputs of the 4094, causing them all to change at once to whatever you just clocked in. Now that the high-side transistors are all either on or off, according to which LED in the current row you want to be on, it's time to turn that row on using the low-side switch for that row. Of course there could be quite a bit of current flowing out through the row pin if all the LEDs in that row are on, so it's not safe to just hook it up to a GPIO pin. A FET is instead used as a low-side switch. Now the row is lit up. Move to the next row and goto 2. If we're at the last row, then instead goto 1 (which means start over). The above method, if run fast enough, will cause all the LEDs to appear illuminated in whatever pattern you desire. But it won't allow brightness control of individual LEDs. To get that we need another variable, that I'll call PWM. PWM will start at zero, and will be incremented at step 1 of the above bullet-pointed flowchart. When it reaches 16, it will be reset back to zero. So it's a rolling counter that will count up each time a frame is output to the matrix, and will roll over at 16. Using this, and the greyscale framebuffer above, we can modify the flowchart so that instead of just clocking in whichever LEDs are on into the 4094, we clock in whichever LEDs have a brightness value that is greater than the current PWM counter. Thus, when the framebuffer entry is zero for a particular LED, that LED is never illuminated because it's brightness value (zero) is never greater than the PWM value (zero to fifteen). And when the framebuffer entry is sixteen, it's always greater than the PWM counter, and thus that LED is illuminated every frame. In between values illumiate the LED for varying numbers of frames, which - if you run the whole process fast enough - will cause them to appear dimmer. The heart of this code is the following loop, which I would love some advice on how to optimise: output = 0; for(bit = 8; bit ; bit--) { output <<= 1; output |= (framebuffer[row][bit] > pwm) ? 0 : 1; // on if over pwm } This loop calculates what to output to the 4094 shift register for each row. It's quite alot of work for an interrupt handler, and it needs to be three times more work once I add the additional two LED panels. I'm sure the compiler in CCS does a good job of figuring out the loop and optimising it for me, but I should take a look at the assembly output and determine if I can do any better. Anyway, to kickstart the process, the main program calls NextRow(), and then sets up a timer and fiddles with the framebuffer at intervals. So, here's NextRow and the USI interrupt handler: unsigned char pwm = 0; unsigned char row = 0; void NextRow() { unsigned char bit; unsigned char output; // strobe low ready for next thingy P1OUT &= ~BIT3; // next row's data - work out if each pixel should be on output = 0; for(bit = 8; bit ; bit--) { output <<= 1; output |= (framebuffer[row][bit] > pwm) ? 0 : 1; // on if over pwm } USISRL = output; // 8 bits out, we'll come back to _usi once these bits have been clocked out. USICNT = 8; } #pragma vector = USI_VECTOR interrupt void _usi() { USICTL1 &= ~USIIFG; // reset interrupt flag // turn off rows P2OUT = 0; // latch data P1OUT |= BIT3; // Strobe high // turn on rows P2OUT = (1 << row); // next row row++; if (row == 5) { pwm++; pwm &= 0x0F; // loop pwm back to zero when it hits sixteen row= 0; // start at row zero again. } NextRow(); } I've left alot of stuff out here, setting up the clock module and the GPIO pins etc etc. Also there's code in the project that makes a pretty (ish) pattern, and the displays some numbers. The code and eagles files are attached, and assuming I can use the video feature of BBcode correctly, here's a video! http://www.youtube.com/watch?v=gvPZ8LyGYGY --Edit--- Well that youtube embed didn't work. Here's a link. How do you embed videos anyway? LED control.zip
  11. When programming recently, I found that I had some trouble controlling a motor at the same time as several servo. The servos would go all crazy, and the motor wouldn't work. I guessed that this was because the timers were interfering, or not enough timers, or similar. Digging into the servo library, and the analogWrite function, I found that they're both trying to use Timer A. Thus, I modified the analogWrite function. In file energia/hardware/msp430/cores/msp430/wiring_analog.c , I commented out lines 110 to 123 (inclusive). Below is the code commented out. case T0A1: // TimerA0 / CCR1 TA0CCR0 = PWM_PERIOD; // PWM Period TA0CCTL1 = OUTMOD_7; // reset/set TA0CCR1 = PWM_DUTY(val); // PWM duty cycle TA0CTL = TASSEL_2 + MC_1 + analog_div; // SMCLK, up mode break; #if defined(__MSP430_HAS_TA3__) || defined(__MSP430_HAS_T0A3__) case T0A2: // TimerA0 / CCR2 TA0CCR0 = PWM_PERIOD; // PWM Period TA0CCTL2 = OUTMOD_7; // reset/set TA0CCR2 = PWM_DUTY(val); // PWM duty cycle TA0CTL = TASSEL_2 + MC_1+ analog_div; // SMCLK, up mode break; #endif This may only work using the G2553, but if you're stuck with a G2231 from a rev 1.4 board, just sample a new chip
  12. cromiumlake

    PWM led

    HI there, I'm playing around PWM, for now just with leds. I checked the teory, but I need to get a simple example. I'm working with msp430-gcc, this code was the easier that I found. They seem to use a shorter syntax (P1OUT_bit.P1OUT_0) that I don't get. I also have few errors, mentioned below. ------------------------------- #include <msp430g2553.h> #include <intrinsics.h> // Intrinsic functions int main( void ) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer BCSCTL3 = LFXT1S_2; // Select ACLK from VLO (no crystal) // Initialize ports P1OUT = 0; // Preset LED off (and everything else) P1DIR = BIT0; // Configure P1.0 for LED output P1REN = 0xFE; // Activate pullups on P1[7:1] // Set up timer channel 1 TACCR1 = 0x2000; // Test compare action TACCTL1 = CCIE; // Interrupts on TACCR1 compare // Start timer: SMCLK, prescale/8, continuous mode, interrupts, clear TACTL = TASSEL_2 | ID_3 | MC_2 | TACLR | TAIE; for (; { LPM0; // LPM0 with interrupts (need SMCLK) } return 0; // Infinite loop } //---------------------------------------------------------------------- // Interrupt service routine for TACCR1.CCIFG, called when TAR -> TACCR1 // and for TAIFG, called when TAR -> 0; share vector // Interrupt flag cleared automatically with access to TAIV //---------------------------------------------------------------------- #pragma vector = TIMER_A1_VECTOR __interrupt void TIMER_A1_ISR (void) // ISR for TACCR1 CCIFG and TAIFG { // switch (TAIV) { // Standard switch switch (__even_in_range(TAIV, 10)) { // Faster intrinsic fn case 0: // No interrupt pending break; // No action case TAIV_CCIFG1: // Vector 2: CCIFG1 P1OUT_bit.P1OUT_0 = 0; // End of duty cycle: Turn off LED break; case TAIV_TAIFG: // Vector A: TAIFG, last value possible P1OUT_bit.P1OUT_0 = 1; // Start of PWM cycle: Turn on LED break; default: // Should not be possible for (; { // Disaster! Loop here for ever } } } ------------------------- errors: blink3.c:30:9: warning: malformed
  13. MSP430g2553 ALL DOCUMENTATION BELOW Playing with IR receiver (IR Library from Energia) and RGB led. I cant write analog values to my RGB led without breaking the program. I connected the three outputs to analogWrite capable pins. All works great when writing 0 or 255 but the library stop working well when i try to write other value to make the color less bright. Then i read about timers and PWM. I notice my library use Timer1_A so i need to connect leds to pins capable of analog writing but using Timer0_A. These pins were three, but one is RXD of Serial and messed things up. So I changed the library to use Timer0_A and connect leds to pins capable of analog writing but using Timer1_A. The program at the moment works nice, but again only with 0 or 255 values. BUT i noticed i can write other values to ONE of these pins, it dont breaks things. I wonder what could be the difference, with datasheet. The pins were: #define RED P2_1 #define GREEN P2_2 #define BLUE P2_4 ---> this works with values between 0 and 255 With datasheet i noticed pin P2_4 has "Out2 output", thats all difference i have found. BUT i put RED to P2_5 wich is "Out2 output" too and again it breaks things, while BLUE doesnt. All of these without knowing what can be out2 output. I miss something. Can you help me? I can give you more details if needed. EDITED: Individually, it works. Pins that are analogWrite capable and use T0_A are {2_1 - 2_2 - 2_4 - 2_5} DOCUMENTATION ABOUT: Problems with timers and IR library http://forum.43oh.com/topic/3550-ir-library-and-pwm/ Datasheet(page 6) http://www.ti.com/lit/ds/symlink/msp430g2553.pdf PinOUT https://www.dropbox.com/s/mcvbnkdpzsn1wna/LaunchPad%20MSP430G2553-V1.4.jpg
  14. Ok, I am out of ideas on this. I am going to start by saying, this works on an arduino uno, no problems. Then follow that up by saying this works perfectly on a launchpad with a 2553 in it IF I DO NOT USE THE IR LIBRARY. So this is what happens: Simple motor control for a two motor robot. Using the IR Library to receive commands from a remote control. I upload the code, and I can make both motors go full throttle, forward, or backward. The moment that I try to spin right or left, I get a quick "jerk" from both motors, in opposite directions (as I would expect) and then nothing...I can not even make it go forward and backward anymore until I reset the launchpad. Again, if I hook the launchpad up, and give it a routine for the robot (forward, spin, backward, spin, left, right, etc) it works just perfectly fine. It is the addition of the IR Library and whatever it is either doing with timers, or interrupts...but I just can't seem to figure it out. I have tried every combination of PWM capable pins that I can think of, and can not get it to work. Here is the code. I would sincerely appreciate any help you can give me. //======================================================================= // IR Remote Control Robot // Remixed by Jerod W. //======================================================================= #include <IRremote.h> #include <IRremoteInt.h> //motor control pin const int E1=4; //motor 1 (right) enable pin const int M1A=2; //motor 1 (right) Output pin 1 const int M1B=3; //motor 1 (right) Output pin 2 const int E2=13; //motor 2 (left) enable pin const int M2A=5; //motor 2 (left) Output pin 1 const int M2B=7; //motor 2 (left) Output pin 2 //IR Receiver Module Pin and variable int RECV_PIN = 10; IRrecv irrecv(RECV_PIN); decode_results results; // setup function //======================================================================= void setup() { //configure all motor control pin as output pinMode(E1,OUTPUT); pinMode(M1A,OUTPUT); pinMode(M1B,OUTPUT); pinMode(E2,OUTPUT); pinMode(M2A,OUTPUT); pinMode(M2B,OUTPUT); //disable both motor by default analogWrite(E1,0); analogWrite(E2,0); //start IR receiver irrecv.enableIRIn(); } // loop function //======================================================================= void loop() { //IR signal received if(irrecv.decode(&results)) { //forward (Up arrow) if(results.value==0x820 || results.value == 0x20) { motor(255,255); } //reverse (VOL-) else if(results.value==0x821 || results.value == 0x21) { motor(-255,-255); } //rotate left (PREVIOUS) else if(results.value==0x811 || results.value==0x11) { motor(240,-240); } //rotate right (NEXT) else if(results.value==0x810 || results.value==0x10) { motor(-240,240); } //forward left (POWER) else if(results.value==0x80F || results.value==0xF) { motor(230,160); } //forward right (FUNC/STOP) else if(results.value==0x80C || results.value==0xC) { motor(180,220); } //reverse left (DOWN) else if(results.value==0x80D || results.value==0xD) { motor(-230,-160); } //reverse right (UP) else if(results.value==0x822 || results.value==0x22) { motor(-180,-220); } //receive the next value irrecv.resume(); //short delay waiting for repeating IR signal // (prevent it to stop if no signal received) delay(50); } //no IR signal received else { //right wheel stop analogWrite(E1,0); //left wheel stop analogWrite(E2,0); } } // extra function //======================================================================= //function to control the motor void motor(int left, int right) { //limit the max speed //if(left>255)left=255; //else if(left<-255)left=-255; //if(right>255)right=255; //else if(right<-255)right=-255; //left wheel forward if(left>0) { //left wheel direction forward digitalWrite(M2A,LOW); digitalWrite(M2B,HIGH); //left wheel speed analogWrite(E2,left); } //left wheel reverse else if(left<0) { //left wheel direction reverse digitalWrite(M2A,HIGH); digitalWrite(M2B,LOW); //left wheel speed analogWrite(E2,-(left)); } //left wheel stop else { //left wheel stop analogWrite(E2,0); } //right wheel forward if(right>0) { //right wheel direction forward digitalWrite(M1A,LOW); digitalWrite(M1B,HIGH); analogWrite(E1,right); } //right wheel reverse else if(right<0) { //right wheel direction reverse digitalWrite(M1A,HIGH); digitalWrite(M1B,LOW); analogWrite(E1,-(right)); } //right wheel stop else { //right wheel stop analogWrite(E1,0); } }
  15. Thanks for taking the time to read this. would love to collaborate with some MSP430 beginners as myself in controlling stepper motors for our home projects. :thumbup:
  16. Hi all, After a little help with some PWM code, the code is below and the areas I believe to be the main issue are in bold. I basically have 2 LDR's linked up to P1.1 and P1.2, then I would like to have 2 PWM outputs on a further 2 pins say P1.4 and P1.5. The code below is working as far as the ADC and changes the brightness of an LED on P1.6, but I am struggling to have any output on another pin (currently trying P1.5). I have been looking at the TI PDF's slau144i and the MSP430G2231 datasheet, but still unsure how to approach this. There is another small question regarding the ADC line ADC10SA = (unsigned int)adc; as I currently need to include this twice, or the code fails to work? Thanks in-advance, Ant #include "msp430g2231.h" unsigned int adc[2] = {0}; void SetHW() { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_1MHZ; // Set range DCOCTL = CALDCO_1MHZ; BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO = 1MHz } // ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { __bic_SR_register_on_exit(CPUOFF); // Return to active mode } void ConfigureAdc(void) { ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE + REFON + REF2_5V; ADC10CTL1 = INCH_2 + CONSEQ_1; // Sets which ADC ports to monitor + defines a sequence of reads __delay_cycles(1000); // Wait for ADC ref voltage to settle ADC10DTC1 = 0x02; // enable data transfer controller so ADC10MEM is copied to RAM ADC10AE0 |= 0x03; // disable digital operation on the ports being used for the ADC ADC10SA = (unsigned int)adc; // copies data in ADC10SA to unsigned int adc } void main(void) { SetHW(); ConfigureAdc(); __enable_interrupt(); // enable interrupts. while(1) { ADC10CTL0 |= ENC + ADC10SC; // Enable Conversion + Start Conversion __bis_SR_register(CPUOFF + GIE); // LPM0 Low Power Mode 0 with interrupts enabled ADC10SA = (unsigned int)adc; // copies data in ADC10SA to unsigned int adc P1DIR |= BIT6; // P1.6 output P1SEL |= BIT6; // P1.6 TA1/2 options CCR0 = 512-1; // PWM Period - this is the up mode see page 387 slau144i.pdf CCTL1 = OUTMOD_7; // CCR1 reset/set - output mode CCR1 = (adc[0]/2); // CCR1 PWM duty cycle - use a variable to dynamically control the duty cycle TACTL = TASSEL_2 + MC_1; // SMCLK, up mode - TACTL = Timer_A Vontrol Register, TASSEL-Timer_A clock source select + MC_1-Mode Control used to conserve power //_BIS_SR(CPUOFF); // Enter LPM0 P1DIR |= BIT5; // P1.5 output P1SEL |= BIT5; // P1.5 TA1/2 options CCR0 = 512-1; // PWM Period CCTL1 = OUTMOD_7; // CCR1 reset/set CCR1 = adc[1]; // CCR1 PWM duty cycle TACTL = TASSEL_2 + MC_1; // SMCLK, up mode //_BIS_SR(CPUOFF); // Enter LPM0 } }
  17. I don't have one of these yet, I am still waiting for mine to arrive. My question is this: How many "individual" pins on this board are capable of doing analogWrite? I say individual as on the MSP430G2553 while there are 6 pins available, certain pins share the same timer, so you can only use 1 pin out of a "pair" which share a timer. So, that said, does anyone have an answer to this? Thank you! Also, I read somewhere that the pins on this board are 5 volt tolerant, however while reading the datasheet, it looks like that isn't the case. Would be great if I could use this board with 5v logic (even if it is being powered by 3.3v). Can anybody weigh in on that?
  18. Hello everyone, I am using the launchpad with MSP430G2452 motherboard "sam board", unfortunately I cannot have the datasheet Chassis Pololu RRC04a with two wheels and two DC motors IAR Workbench The thing I need to do for my school project is to be able to run the "robot" in a straight line. But I can't figure how. I use CCRO as the period of the PWM signal, CCR1 for the duty cycle of the first PWM and CCR2 for the duty cycle of the second one. But the second PWM is acting weird therefore I think I didn't understand how to make it work. With this code, the second PWM is not running at the same frequency as the first one although I used the same duty cycle (the B motor is running a little bit slower therefore the robot isnt running into a straight line). I have to use the motherboard like this : P1.2(TA0.1) for the first PWM (250kHz max) P1.4 (TA0.2) for the second one (250kHz max) P2.1 and P2.2 for the motors' direction #include "io430.h" void init_clock() { if(CALBC1_1MHZ==0xFF||CALDCO_1MHZ==0xFF) { while(1); } BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; } void init_PWM() { P2DIR &= ~(BIT1); //motor's A direction P2DIR |= BIT2; //motor's B direction P1DIR |= BIT2 + BIT4; P1SEL |= BIT2 + BIT4; //TA0.1 with bit2 P1SEL2 |= BIT4; //TA0.2(p37 MSP430G2452) TACTL |= TASSEL_2 + MC_1 + ID_3 + TACLR; /* SMCLK * Mode UP * Diviseur /8 * Timer A clear */ TACCR0 = 1000; TACCR1 = 500; //50% duty cycle TACCR2 = 500; //50% duty cycle TACCTL1 = OUTMOD_3; TACCTL2|= OUTMOD_3; } int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer to prevent time out reset init_clock(); init_PWM(); while(1) { } } I am sorry if my english isn't very good, I hope you understand what I'm trying to say. A little help would be appreciate, thank !
  19. Hi there! I'm totally new in MCU programming) I have the g2553 microcontroller and I need some program to make two PWMs and to control shift of impulse fronts one from other by clicking buttons. Try to explain: ___---___---___---___ ___---___---___---___ <click!> ____---___---___---__ ___---___---___---___ I think shift by adding __delay_cycles() to one of pwms is not too bad idea, but i totally have no thoughts how to get two PWMs. Sorry about my english:)
  • Create New...