Jump to content

mpigsley

Members
  • Content Count

    9
  • Joined

  • Last visited

About mpigsley

  • Rank
    Noob Class
  • Birthday 02/10/1992

Profile Information

  • Gender
    Not Telling
  • Location
    United States
  1. mpigsley

    While(1) not Executing with Timer Interrupt

    I ended up using SMCLK and increasing the capture compare register. Why this suddenly works while the ACLK didn't... I don't know. The updated code is below for reference. #include <msp430g2553.h> #define MS_TIME 1000 volatile unsigned int s_cnt = 0; unsigned int last_cnt = 0; int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR |= BIT0 + BIT6; // P1.0 and P1.6 are the red+green LEDs P1OUT &= ~(BIT0 + BIT6); // Both LEDs off TA0CCTL0 = CCIE; // Enable Timer A0 interrupts TA0CCR0 = 1000; // Count limit TA0CTL = TASSEL_2 + MC_1; // Timer A0 with SMCLK, count UP _BIS_SR(GIE); // Enable interrupts while(1) { if (last_cnt != s_cnt) { last_cnt = s_cnt; if (s_cnt >= MS_TIME) { P1OUT ^= BIT6; // Toggle green LED s_cnt = 0; } } } } #pragma vector=TIMER0_A0_VECTOR // Timer0 A0 interrupt service routine __interrupt void Timer0_A0 (void) { s_cnt++; }
  2. mpigsley

    While(1) not Executing with Timer Interrupt

    @@pabigot The capture compare flag needs to be manually reset after each ISR execution? From the user guide page 11-20: @@greeeg Even after removing Low Power Mode I'm still getting that starvation.
  3. mpigsley

    While(1) not Executing with Timer Interrupt

    @@greeeg This is brilliant. I'll take a look at it later today. I appreciate both of you guys' help!
  4. mpigsley

    While(1) not Executing with Timer Interrupt

    _enable_interrupts(); It's not declared in the scope. What header is that defined in? I can't seem to find any documentation on it either. I've also played around with the low power modes to no avail. Removing it doesn't help.
  5. Hey all, I've run into a peculiar problem where my main loop doesn't execute. I know my interrupt routine is executing because I can uncomment the led toggle and I can see it blink. From what I've researched thus far, I believe the issue might be that the ISR is starving the main loop from ever executing. If that is the case, I'm not sure what the solution would be. The reason I have my main loop set up this way is because I am going to need different functions executing at different intervals. I'm still fairly new to MSP430 development, so any help will be appreciated! #include <msp430g2553.h> #define MS_TIME 1000 volatile unsigned int s_cnt = 0; unsigned int last_cnt = 0; int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR |= BIT0 + BIT6; // P1.0 and P1.6 are the red+green LEDs P1OUT &= ~(BIT0 + BIT6); // Both LEDs off TA0CCTL0 = CCIE; // Enable Timer A0 interrupts TA0CCR0 = 22; // Count limit TA0CTL = TASSEL_1 + MC_1; // Timer A0 with ACLK, count UP _BIS_SR(LPM0_bits + GIE); // Enable interrupts while(1) { if (last_cnt != s_cnt) { last_cnt = s_cnt; if (last_cnt == MS_TIME) { P1OUT ^= BIT6; // Toggle green LED s_cnt = 0; } } } } #pragma vector=TIMER0_A0_VECTOR // Timer0 A0 interrupt service routine __interrupt void Timer0_A0 (void) { s_cnt++; //P1OUT ^= BIT6; }
  6. mpigsley

    Hardware UART & Two Servos

    I'll do just that. Thank you for your prompt help!
  7. mpigsley

    Hardware UART & Two Servos

    You're right, there's that TimerA_UART_tx() function I missed. It is editied in to the original post. Since there is dedicated UART hardware, does this mean I can remove that dependency on TimerA for bi-directional serial comm? It looks like you did just that in the code snippet. Great! I'll look into this and see where I get. Thank you!
  8. mpigsley

    Hardware UART & Two Servos

    Oh sorry, it's G2553
  9. mpigsley

    Hardware UART & Two Servos

    I'm fairly new to specifically MSP430 development, so any help here is appreciated! I'm trying to send data to and from a Raspberry Pi connected over hardware UART. This I've tested and works. I'm also trying to run two servos on the MSP430 and the basic code I have for them has been tested and also works. The problem occurs when I try to put them together as my timer setup must clash somewhere. It seems to me that the serial communication is all set on TA0 while the other timer is set to TA1. I don't understand why this would prevent the UART from sending and receiving. Edit: I'm using the MSP430G2553 int main(void){ WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer init_servos(); init_UART(); _BIS_SR(GIE); // Enable CPU interrupts while(1){ // Wait for incoming character _BIS_SR(LPM0_bits); // Enter low poser mode if (rxBuffer == 'a') { P1OUT |= BIT0; } } } void init_UART() { 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 = UART_TXD + BIT0; // TX and LED1 to Output // Configures Timer_A for full-duplex UART operation TA0CCTL0 = OUT; // Set TXD Idle as Mark = '1' TA0CCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int TA0CTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode } void init_servos() { P2SEL |= BIT0 | BIT1; P2DIR |= BIT0 | BIT1; // Duty Cycle (585 - 675 - 765) TA1CCTL0 = OUTMOD_7; // reset/set (0) TA1CCTL1 = OUTMOD_7; // reset/set (1) TA1CTL = TASSEL_2 + MC_1; // SMCLK, up mode BCSCTL1 = 0x84; // CLK Info TA1CCR0 = 675; // Duty Cycle (2.0) TA1CCR1 = 675; // Duty Cycle (2.1) } void TimerA_UART_print(char *string) { // Prints a string using the Timer_A UART while (*string) TimerA_UART_tx(*string++); } 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 } #pragma vector = TIMER0_A0_VECTOR // Timer_A UART - Transmit Interrupt Handler __interrupt void Timer_A0_ISR(void) { static unsigned char txBitCnt = 10; TA0CCR0 += UART_TBIT; // Add Offset to CCRx if (txBitCnt == 0) { // All bits TXed? TA0CCTL0 &= ~CCIE; // All bits TXed, disable interrupt txBitCnt = 10; // Re-load bit counter } else { if (txData & 0x01) TA0CCTL0 &= ~OUTMOD2; // TX Mark '1' else TA0CCTL0 |= OUTMOD2; // TX Space '0' } txData >>= 1; // Shift right 1 bit txBitCnt--; } #pragma vector = TIMER0_A1_VECTOR // Timer_A UART - Receive Interrupt Handler __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch (TA0IV) { // Use calculated branching case TA0IV_TACCR1: // TACCR1 CCIFG - UART RX TA0CCR1 += UART_TBIT; // Add Offset to CCRx if (TA0CCTL1 & CAP) { // Capture mode = start bit edge TA0CCTL1 &= ~CAP; // Switch capture to compare mode TA0CCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0 } else { rxData >>= 1; if (TA0CCTL1 & 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 TA0CCTL1 |= CAP; // Switch compare to capture mode _BIC_SR_IRQ(LPM0_bits); // wake up from low power mode. } } break; } }
×