Jump to content

octavian_rot

Members
  • Content Count

    8
  • Joined

  • Last visited

  1. octavian_rot

    GPS + MSP430G2452 UART Problem

    No, I'm just storing the $GPRMC string and parsing the coordinates, and UTC time and date from there.
  2. octavian_rot

    GPS + MSP430G2452 UART Problem

    The TI example UART ( which he is using) doesn't use the crystal. True, but I used the crystal to calibrate my DCO.
  3. octavian_rot

    GPS + MSP430G2452 UART Problem

    I calibrated the DCO but it still has the same problem. So, as rockets4kids said, the best solution(simplest) for my problem was to change the controllers. Works beautifully with the G2553 . Thank you all for your help!
  4. octavian_rot

    GPS + MSP430G2452 UART Problem

    Thanks for the reply! I still can't figure it out. Here's what I did so far: I had already tried changing the DCO, and I get better messages, but still not correct ones. If they're not exactly right, the GPS software doesn't know how to interpret them. I think I'm losing a character at almost periodical intervals(In bold what I'm losing): $GPRMC,10212.00,V,,,,,,31051,,,N*70 $GPVTG,,,,,,,,N*30 $GPGGA,12912.00,,,,0,00,9.99,,,,,,*6F $GPGS,A,1,,,,,,,,,,,,9.99,99.9999.99*30new line$GPGSV,2,,08,05,,31,12,,,2,14,,,22,6,,,23*72 $GPGSV,,2,08,17,,21,24,,,7,27,,,2632,,,24*7something in the check-sum; it should be 2 characters long $GPGLL,,,,10291.00,V,N*4something in the check-sum; it should be 2 characters long I can only store about 200 characters into a string, and that's not enough for all of the messages. (I want to mention that I'm a beginner with MSP430) I don't understand why I can't declare a bigger string in the main function? I don't get any error when doing that, nor warnings, but the program won't print anything. Already did that, but I don't think it has any effect. Do you have any other suggestions? Thank you very much, Octav
  5. octavian_rot

    GPS + MSP430G2452 UART Problem

    Hello, I am using the example code from TI for UART at 9600baud. I have connected a GPS receiver and I'm trying to get the NMEA data from the receiver on a serial monitor. However the received NMEA messages are degraded (and I can't use any GPS Software), for example: Degraded: $GPRMC,V,,,,,,,,,N*3 $GPTG,,,,,,,,N*0 $GPGS,A,1,,,,,,,,,,,99.9,99.9,99.9930 $GGSV,1,,02,17,,26,3,,,33*A $GPLL,,,,,V,N*6 Correct: $GPRMC,,V,,,,,,,,,,N*53 $GPVTG,,,,,,,,,N*30 $GPGGA,,,,,,0,00,99.99,,,,,,*48 $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30 $GPGSV,1,1,00*79 $GPGLL,,,,,,V,N*64 The only correct message i'm receiving is the $GPRMC one (witch is pretty neat; I can read the coordinates ). Do you know why am I having this problem? Could you please, please help me? Thank you very much, Octav Here's the code: //****************************************************************************** // 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) //------------------------------------------------------------------------------ // 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() //------------------------------------------------------------------------------ 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("G2xx2 TimerA UART\r\n"); TimerA_UART_print("READY.\r\n"); for (; { // Wait for incoming character __bis_SR_register(LPM0_bits); // Update board outputs according to received byte /* if (rxBuffer & 0x01) P1OUT |= 0x01; else P1OUT &= ~0x01; // P1.0 if (rxBuffer & 0x02) P1OUT |= 0x08; else P1OUT &= ~0x08; // P1.3 if (rxBuffer & 0x04) P1OUT |= 0x10; else P1OUT &= ~0x10; // P1.4 if (rxBuffer & 0x08) P1OUT |= 0x20; else P1OUT &= ~0x20; // P1.5 if (rxBuffer & 0x10) P1OUT |= 0x40; else P1OUT &= ~0x40; // P1.6 if (rxBuffer & 0x20) P1OUT |= 0x80; else P1OUT &= ~0x80; // P1.7 if (rxBuffer & 0x40) P2OUT |= 0x40; else P2OUT &= ~0x40; // P2.6 if (rxBuffer & 0x80) P2OUT |= 0x80; else P2OUT &= ~0x80; // P2.7 */ // 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; } } //------------------------------------------------------------------------------
  6. octavian_rot

    LCD noob help

    Thanks for the reply! I've just realized that, but it was simpler to wire the data pins as 3,4,2,5. I tried to build a void function that simply shifts the bits, but without too much luck. I think I'll start the code from scratch and write it in this curious way. Thanks again!
  7. octavian_rot

    LCD noob help

    Hi! First of all I want to say that I'm a beginner with ucontrollers. I recently got hold of a launchpad and I had a LCD at home and I managed to write on it, using the code and the pin definitions from TI. However I want to build a shield and it would be easier to use other definitions. I've attached the code and wrote in the comments where i changed the code. Could somebody please help me and explain why I'm only getting strange characters on my LCM? Thanks! #include #define LCM_DIR P1DIR #define LCM_OUT P1OUT #define LCM_PIN_RS BIT0 #define LCM_PIN_EN BIT1 #define LCM_PIN_D7 BIT3 //instead of BIT7 #define LCM_PIN_D6 BIT4 //instead of BIT6 #define LCM_PIN_D5 BIT2 //instead of BIT5 #define LCM_PIN_D4 BIT5 //instead of BIT4 #define LCM_PIN_MASK ((LCM_PIN_RS | LCM_PIN_EN | LCM_PIN_D7 | LCM_PIN_D6 | LCM_PIN_D5 | LCM_PIN_D4)) #define FALSE 0 #define TRUE 1 // // Routine Desc: // // This is the function that must be called // whenever the LCM needs to be told to // scan it's data bus. // // Parameters: // // void. // // Return // // void. // void PulseLcm() { // // pull EN bit low // LCM_OUT &= ~LCM_PIN_EN; __delay_cycles(200); // // pull EN bit high // LCM_OUT |= LCM_PIN_EN; __delay_cycles(200); // // pull EN bit low again // LCM_OUT &= (~LCM_PIN_EN); __delay_cycles(200); } // // Routine Desc: // // Send a byte on the data bus in the 4 bit mode // This requires sending the data in two chunks. // The high nibble first and then the low nible // // Parameters: // // ByteToSend - the single byte to send // // IsData - set to TRUE if the byte is character data // FALSE if its a command // // Return // // void. // void SendByte(char ByteToSend, int IsData) { // // clear out all pins // LCM_OUT &= (~LCM_PIN_MASK); // // set High Nibble (HN) - LCM_OUT |= (2 >> (ByteToSend & 0xF0)); //instead of LCM_OUT |= (ByteToSend & 0xF0); if (IsData == TRUE) { LCM_OUT |= LCM_PIN_RS; } else { LCM_OUT &= ~LCM_PIN_RS; } // // we've set up the input voltages to the LCM. // Now tell it to read them. // PulseLcm(); // // set Low Nibble (LN) - LCM_OUT &= (~LCM_PIN_MASK); LCM_OUT |= ((ByteToSend & 0x0F) << 2);//instead of LCM_OUT |= ((ByteToSend & 0xF0)<<4); if (IsData == TRUE) { LCM_OUT |= LCM_PIN_RS; } else { LCM_OUT &= ~LCM_PIN_RS; } // // we've set up the input voltages to the LCM. // Now tell it to read them. // PulseLcm(); } // // Routine Desc: // // Set the position of the cursor on the screen // // Parameters: // // Row - zero based row number // // Col - zero based col number // // Return // // void. // void LcmSetCursorPosition(char Row, char Col) { char address; // // construct address from (Row, Col) pair // if (Row == 0) { address = 0; } else { address = 0x40; } address |= Col; SendByte(0x80 | address, FALSE); } // // Routine Desc: // // Clear the screen data and return the // cursor to home position // // Parameters: // // void. // // Return // // void. // void ClearLcmScreen() { // // Clear display, return home // SendByte(0x01, FALSE); SendByte(0x02, FALSE); } // // Routine Desc: // // Initialize the LCM after power-up. // // Note: This routine must not be called twice on the // LCM. This is not so uncommon when the power // for the MCU and LCM are separate. // // Parameters: // // void. // // Return // // void. // void InitializeLcm(void) { // // set the MSP pin configurations // and bring them to low // LCM_DIR |= LCM_PIN_MASK; LCM_OUT &= ~(LCM_PIN_MASK); // // wait for the LCM to warm up and reach // active regions. Remember MSPs can power // up much faster than the LCM. // __delay_cycles(100000); // // initialize the LCM module // // 1. Set 4-bit input // LCM_OUT &= ~LCM_PIN_RS; LCM_OUT &= ~LCM_PIN_EN; LCM_OUT = BIT2; //instead of LCM_OUT = 0x20; that means D5 is 1. PulseLcm(); // // set 4-bit input - second time. // (as reqd by the spec.) // SendByte(0x28, FALSE); // // 2. Display on, cursor on, blink cursor // SendByte(0x0E, FALSE); // // 3. Cursor move auto-increment // SendByte(0x06, FALSE); } // // Routine Desc // // Print a string of characters to the screen // // Parameters: // // Text - null terminated string of chars // // Returns // // void. // void PrintStr(char *Text) { char *c; c = Text; while ((c != 0) && (*c != 0)) { SendByte(*c, TRUE); c++; } } // // Routine Desc // // main entry point to the sketch // // Parameters // // void. // // Returns // // void. // void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer InitializeLcm(); ClearLcmScreen(); PrintStr("Hello World!"); while (1) { __delay_cycles(1000); } }
  8. octavian_rot

    Hello, hello!

    Hello, and greetings from Bucharest Romania. I'm quite new to micro controllers and recently purchased a launchpad. I intend to connect it to a relay and control my outdoor lighting. I will also be using an LCM to program the time when to start and stop the installation. Where should I post questions? Thanks!
×