Jump to content

nemi

Members
  • Content Count

    9
  • Joined

  • Last visited

  1. I haven't tried this (yet) but I was wondering if the MSP430G2211 chip that accompanies the MSP430G2231 chip pre-installed on the launchpad could share the same PC USB UART interface, at the same time? I was thinking that if each had different serial command sets and only transmitted data after receiving a command then they could share the same (9600 baud) comms to a host PC, doubling the I/O lines available, assuming there is no USB UART speciic issue that I am unaware of. I realize both chips would have to be programed separably, one would then be installed in the launchpad demo PCB and the other would share the GND, VCC, TX, RX links. Has anyone tried this or have a reason it would not work? :oops:
  2. Good idea. though as I said in the post, I routed VCC and an output line to the mini board for future expansion - such as rear illumination of the monitors (nice on the eyes at night). So I need a 5+ pin connector. I may just look into cheap rj46 jacks and use a network cable.
  3. surplus electronics for the tilt switches. I got the cheapest single pin type. Need to solder or contact the case for the other terminal. http://www.surplus-electronics-sales.com/Zencart/index.php?main_page=product_info&cPath=28&products_id=316 autoit is a very handy language for automating widnows programs that don't have command line options or an API. http://www.autoitscript.com/autoit3/index.shtml
  4. Hi Everyone, my first project with the launch pad is to automatically rotate my windows desktop orientation when I rotate my monitors. I have been working with dual monitors for a while but recently got a monoprice dual monitor stand that allows rotation. http://www.monoprice.com/products/product.asp?c_id=109&cp_id=10828&cs_id=1082808&p_id=5560&seq=1&format=2 I then had the idea to implement my own hardware sensor to detect when they had been rotated to portrait (or even up-side-down). The circuit is simple and the pictures should explain everything. The hardware is the standard TI launchpad development board, together with Qty.4 tilt switches. I made a shield with two of the tilt switches on the launch pad (for mouing on the rear of monitor 1) and a mini pcb with the other two tilt switches (for the rear of monitor 2). Some wires a routed between the two. I'm using 4 pins as digital input pulled high. the tilt switches short to ground when closing the circuit. 2 tilt switches for each monitor encode the 4 possible positions (for each monitor). By placing the tilt switchers at 45 degrees to up-down and left-right there is good stability. Power, VCC and Qty.1 digital output (currently assigned to launch pad LEDs) are brought out to each PCB for any future expansion (e.g. ambient rear illumination etc.), The launchpad had version 0.01 of my general purpose IO code so that a windows program can read the status via com port serial command ("r"). here is the launchpad code: // General purpose serial I/O (9600 baud) for launchpad // Peter R.H. 12/30/2010 onwards // heavily modified example 9600 uart code and other items // history // 1/1/2011 - "t" command not yet working. // original uart example notes //****************************************************************************** // MSP430G2xx1 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 *// // // MSP430G2xx1 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | CCI0B/TXD/P1.1|--------> // | | 9600 8N1 // | CCI0A/RXD/P1.2|<-------- // // D. Dang // Texas Instruments Inc. // October 2010 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include "msp430g2231.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); //void ConfigureAdcTempSensor(void); // vars long temp; long IntDegF; long IntDegC; unsigned int TXByte; //------------------------------------------------------------------------------ // main() //------------------------------------------------------------------------------ void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //for temperature reading TACTL = TASSEL_2 | MC_2; while (TAR < 30); // --- 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 // Set all pins but RXD, P1.3, P1.4, P1.5, P1.7 to output P1DIR = 0xFF & ~UART_RXD & ~0x08 & ~0x10 & ~0x20 & ~0x80; //unable to set P1.3 to pull low so set all the others to pull up (!) P1IN |= BIT4; //enables input P1REN |= BIT4; // enables resistor P1OUT |= BIT4; //resistor set to pull up P1IN |= BIT5; //enables input P1REN |= BIT5; // enables resistor P1OUT |= BIT5; //resistor set to pull up P1IN |= BIT7; //enables input P1REN |= BIT7; // enables resistor P1OUT |= BIT7; //resistor set to pull up P2OUT = 0x00; P2SEL = 0x00; P2DIR = 0xFF; __enable_interrupt(); TimerA_UART_init(); // Start Timer_A UART TimerA_UART_print("\r\r\rREADY.\r\n"); for (; { // Wait for incoming character __bis_SR_register(LPM0_bits); // Echo received character TimerA_UART_tx(rxBuffer); // Update board outputs according to received byte if (rxBuffer == '1') P1OUT |= 0x01; if (rxBuffer == '!') P1OUT &= ~0x01; if (rxBuffer == '6') P1OUT |= 0x40; if (rxBuffer == '^') P1OUT &= ~0x40; if (rxBuffer == 't') { ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled temp = ADC10MEM; // oF = ((A10/1024)*1500mV)-923mV)*1/1.97mV = A10*761/1024 - 468 IntDegF = ((temp - 630) * 761) / 1024; // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278 IntDegC = ((temp - 673) * 423) / 1024; TXByte = (unsigned char)(IntDegC); TimerA_UART_tx(TXByte); TXByte = (unsigned char)(','); TimerA_UART_tx(TXByte); TXByte = (unsigned char)(IntDegF); TimerA_UART_tx(TXByte); } if (rxBuffer == 'r') { TimerA_UART_tx(';'); if ((8 & P1IN)) TimerA_UART_tx('1'); // if P1.3 set else TimerA_UART_tx('0'); if ((16 & P1IN)) TimerA_UART_tx('1'); // if P1.4 set else TimerA_UART_tx('0');rrr if ((32 & P1IN)) TimerA_UART_tx('1'); // if P1.5 set else TimerA_UART_tx('0'); if ((128 & P1IN)) TimerA_UART_tx('1'); // if P1.6 set else TimerA_UART_tx('0'); TimerA_UART_tx('.'); } } } //------------------------------------------------------------------------------ // 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 = TIMERA0_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 = TIMERA1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching case TAIV_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; } } //------------------------------------------------------------------------------ // ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR) } On the windows desktop side I am using the free software iRotate which provide hotkeys for roating the monitor layout. http://www.entechtaiwan.com/util/irotate.shtm I then coded an AutoIt program to poll the launchpad via serial and simualte pressign the correct irotate hot-keys. I have the irotate program and this autoit one in my windows startup folder. If you duplicate this project you may have to change this code if your tilt switches are different orientations and/or pins my autoit code is: ; Monitor rotate code ; Peter 1/1/2011 ; based upon serial code by "martin" ; http://www.autoitscript.com/forum/topic/45842-serial-port-com-port-udf/ ; http://www.mosaiccgl.co.uk/AutoItDownloads/confirm.php?get=COMMGv2.zip #include #include 'CommMG.au3';or if you save the commMg.dll in the @scripdir use #include @SciptDir & '\commmg.dll' #include #include #include #include ; keep track of new/old monitor states $m1old="" $m1="" $m2old="" $m2="" ; ^ = Control , + = shift , ! = ALT ; monitor 1 HotKeys $sup1="^!{UP}" $sdown1="^!{DOWN}" $sleft1="^!{LEFT}" $sright1="^!{RIGHT}" ; monitor 2 HotKeys $sup2="^+{UP}" $sdown2="^+{DOWN}" $sleft2="^+{LEFT}" $sright2="^+{RIGHT}" while ProcessExists("iRotate.exe")=False sleep(1000) ; allow irotate to start up WEnd sleep(2000) $serror="" _CommSetPort(5, $serror, 9600, 8, 0, 1, 0, 0, 0) while 1 sleep(200) _CommSendString("r",0) sleep(500) $sread = _CommGetLine(".",10,800) ;MsgBox(0,"responce",$sread) ;monitor 1 $m1=stringmid($sread,4,2) if $m1<>$m1old Then switch $m1 case "00" send($sup1,0) case "10" send($sright1,0) case "01" send($sleft1,0) case "11" send($sdown1,0) Endswitch EndIf $m1old=$m1 ;monitor 2 $m2=stringmid($sread,3,1)&stringmid($sread,6,1) if $m2<>$m2old Then switch $m2 case "00" send($sup2,0) case "10" send($sright2,0) case "01" send($sleft2,0) case "11" send($sdown2,0) Endswitch EndIf $m2old=$m2 sleep(1300) WEnd It uses the autoit serial routines from "Martin" http://www.autoitscript.com/forum/topic/45842-serial-port-com-port-udf/ Enjoy! circuit pictures in the next post.
  5. Well it doesn't crash, but the 't' command retuns nothing until another character is sent from the PC, and it always repsonds with the same values even if i warm the chip. Very confusing... //****************************************************************************** // MSP430G2xx1 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 *// // // MSP430G2xx1 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | CCI0B/TXD/P1.1|--------> // | | 9600 8N1 // | CCI0A/RXD/P1.2|<-------- // // D. Dang // Texas Instruments Inc. // October 2010 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** // Modified Peter R.H. 12/30/2010 onwards #include "msp430g2231.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); //void ConfigureAdcTempSensor(void); // vars long temp; long IntDegF; long IntDegC; unsigned int TXByte; //------------------------------------------------------------------------------ // main() //------------------------------------------------------------------------------ void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //for temperature reading TACTL = TASSEL_2 | MC_2; while (TAR < 30); // --- 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 // Set all pins but RXD, P1.3, P1.4, P1.5, P1.7 to output P1DIR = 0xFF & ~UART_RXD & ~0x08 & ~0x10 & ~0x20 & ~0x80; //unable to set P1.3 to pull low so set all the others to pull up (!) P1IN |= BIT4; //enables input P1REN |= BIT4; // enables resistor P1OUT |= BIT4; //resistor set to pull up P1IN |= BIT5; //enables input P1REN |= BIT5; // enables resistor P1OUT |= BIT5; //resistor set to pull up P1IN |= BIT7; //enables input P1REN |= BIT7; // enables resistor P1OUT |= BIT7; //resistor set to pull up P2OUT = 0x00; P2SEL = 0x00; P2DIR = 0xFF; __enable_interrupt(); TimerA_UART_init(); // Start Timer_A UART TimerA_UART_print("\r\r\rREADY.\r\n"); for (; { // Wait for incoming character __bis_SR_register(LPM0_bits); // Echo received character TimerA_UART_tx(rxBuffer); // Update board outputs according to received byte if (rxBuffer == '1') P1OUT |= 0x01; if (rxBuffer == '!') P1OUT &= ~0x01; if (rxBuffer == '6') P1OUT |= 0x40; if (rxBuffer == '^') P1OUT &= ~0x40; if (rxBuffer == 't') { ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled temp = ADC10MEM; // oF = ((A10/1024)*1500mV)-923mV)*1/1.97mV = A10*761/1024 - 468 IntDegF = ((temp - 630) * 761) / 1024; // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278 IntDegC = ((temp - 673) * 423) / 1024; TXByte = (unsigned char)(IntDegC); TimerA_UART_tx(TXByte); TXByte = (unsigned char)(','); TimerA_UART_tx(TXByte); TXByte = (unsigned char)(IntDegF); TimerA_UART_tx(TXByte); } if (rxBuffer == 'r') { TimerA_UART_tx(';'); if ((8 & P1IN)) TimerA_UART_tx('1'); // if P1.3 set else TimerA_UART_tx('0'); if ((16 & P1IN)) TimerA_UART_tx('1'); // if P1.4 set else TimerA_UART_tx('0'); if ((32 & P1IN)) TimerA_UART_tx('1'); // if P1.5 set else TimerA_UART_tx('0'); if ((128 & P1IN)) TimerA_UART_tx('1'); // if P1.6 set else TimerA_UART_tx('0'); TimerA_UART_tx('.'); } } } //------------------------------------------------------------------------------ // 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 = TIMERA0_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 = TIMERA1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching case TAIV_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; } } //------------------------------------------------------------------------------ // ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR) }
  6. I put those lines (anywhere) in my code and serial comms either doesn't work, or stops after a few chars. Am I missing something? What would be a compete code block to get the temperature ADC reading (including any delay needed to settle) either in the "t" section or the main loop? thank you.
  7. Thank you. It would take some time to pour over the code and understand the syntax. For my immediate needs I re purposed the example 9600 baud UART code. Using the 2 LEDS P1.0 and P1.6 as outputs and the other lines as digital inputs. However "grafting" the temperature sensor code for the example fails, I no longer get working serial communications. The other (minor) issue is i couldn't set P1.3 to pull down, so I set all other pins to pull up for simplicity. I guess I can carry on wishing for a well documented + simple function library /frame work for simple pin reading/writing. I'm not interested in going to low power mode, or omtimising the very last byte of code size- I rather have a quicker firmware development so I can tackle the other hardware and software. My (horrible code) is: //****************************************************************************** // MSP430G2xx1 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 *// // // MSP430G2xx1 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | CCI0B/TXD/P1.1|--------> // | | 9600 8N1 // | CCI0A/RXD/P1.2|<-------- // // D. Dang // Texas Instruments Inc. // October 2010 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** // Modified Peter R.H. 12/30/2010 onwards #include "msp430g2231.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); //void ConfigureAdcTempSensor(void); // vars long temp; long IntDegF; long IntDegC; unsigned int TXByte; //------------------------------------------------------------------------------ // main() //------------------------------------------------------------------------------ void main(void) { // this does not work // temp reading setup // WDTCTL = WDTPW + WDTHOLD; // Stop WDT // ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4 // ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE; // __enable_interrupt(); // Enable interrupts. // TACCR0 = 30; // Delay to allow Ref to settle // TACCTL0 |= CCIE; // Compare-mode interrupt. // TACTL = TASSEL_2 | MC_1; // TACLK = SMCLK, Up mode. // LPM0; // Wait for delay. // TACCTL0 &= ~CCIE; // Disable timer Interrupt // __disable_interrupt(); // end fo temp 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 // Set all pins but RXD, P1.3, P1.4, P1.5, P1.7 to output P1DIR = 0xFF & ~UART_RXD & ~0x08 & ~0x10 & ~0x20 & ~0x80; //unable to set P1.3 to pull low so set all the others to pull up (!) P1IN |= BIT4; //enables input P1REN |= BIT4; // enables resistor P1OUT |= BIT4; //resistor set to pull up P1IN |= BIT5; //enables input P1REN |= BIT5; // enables resistor P1OUT |= BIT5; //resistor set to pull up P1IN |= BIT7; //enables input P1REN |= BIT7; // enables resistor P1OUT |= BIT7; //resistor set to pull up P2OUT = 0x00; P2SEL = 0x00; P2DIR = 0xFF; __enable_interrupt(); TimerA_UART_init(); // Start Timer_A UART TimerA_UART_print("\r\r\rREADY.\r\n"); for (; { // Wait for incoming character __bis_SR_register(LPM0_bits); // Echo received character TimerA_UART_tx(rxBuffer); // Update board outputs according to received byte if (rxBuffer == '1') P1OUT |= 0x01; if (rxBuffer == '!') P1OUT &= ~0x01; if (rxBuffer == '6') P1OUT |= 0x40; if (rxBuffer == '^') P1OUT &= ~0x40; if (rxBuffer == 't') { ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled // oF = ((A10/1024)*1500mV)-923mV)*1/1.97mV = A10*761/1024 - 468 temp = ADC10MEM; IntDegF = ((temp - 630) * 761) / 1024; // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278 temp = ADC10MEM; IntDegC = ((temp - 673) * 423) / 1024; TXByte = (unsigned char)(IntDegC); TimerA_UART_tx(TXByte); TXByte = (unsigned char)(','); TimerA_UART_tx(TXByte); TXByte = (unsigned char)(IntDegF); TimerA_UART_tx(TXByte); } if (rxBuffer == 'r') { TimerA_UART_tx(';'); if ((8 & P1IN)) TimerA_UART_tx('1'); // if P1.3 set else TimerA_UART_tx('0'); if ((16 & P1IN)) TimerA_UART_tx('1'); // if P1.4 set else TimerA_UART_tx('0'); if ((32 & P1IN)) TimerA_UART_tx('1'); // if P1.5 set else TimerA_UART_tx('0'); if ((128 & P1IN)) TimerA_UART_tx('1'); // if P1.6 set else TimerA_UART_tx('0'); TimerA_UART_tx('.'); } } } //------------------------------------------------------------------------------ // 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 = TIMERA0_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 = TIMERA1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching case TAIV_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; } } //------------------------------------------------------------------------------ //this does not work // ADC10 interrupt service routine //#pragma vector=ADC10_VECTOR //__interrupt void ADC10_ISR (void) //{ // __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR) //} //#pragma vector=TIMERA0_VECTOR //__interrupt void ta0_isr(void) //{ // TACTL = 0; // LPM0_EXIT; // Exit LPM0 on return //}
  8. Hi Everyone, I just received my TI LaunchPAd kit and have been searching for a general purpose IO program for it to speed up my hardware development (via a PC) before I dive into specific MSP code. I was hoping there might already be something out there that allows simple serial terminal control of the MSP430G2231 as if it were an "instrument". The TI example program "msp430g2xx1_ta_uart9600.c Timer_A, Ultra-Low Pwr Full-duplex UART 9600, 32kHz ACLK" is a start but only allows for setting of 8 digital output pins and the setting is done at the byte level so a bit of a pain compared to working at a terminal with "English" commands. An ideal program (IMO) would be compatible with keyboard commands from 9600 baud terminal software (e.g Putty) i.e. simple ASCII readable commands and responses, terminated with character strings, optional echo. Allow setting of individual pins as digital input, digital output , pwm output, or analog input Allow setting and reading of individual pin values Reading of internal temperature the command set could be something like: S[x],[i/o/p/a] set pin "x" as "i" input, "o" output, "p" pwm output , "a" analog input R[x] read pin "x" , returns "err" if (previously) set as an output, otherwise returns "1" or "0" if set as a digital input or value "0" to "1024" if an analog input W[x],[0-1024] write pin "x" the value 0-1024 . 0 or 1 allowable for digital outputs, 0-1024 allowable for PWM output. Return "err" if out of range or pin previously configured as digital or analog input. T[C/F] get temperature in degrees "C" or "F" to 1 decimal place eg. "23.5" The aim is to avoid writing PC software to manage bits /byte formatting and specific MSP code when trying to prototype/debug (slow) hardware when commands from a terminal program would seem the most appropriate way to develop an idea quickly.
×
×
  • Create New...