ozymandias 7 Posted March 7, 2012 Share Posted March 7, 2012 Project: control 3 MSP430G2231's using a single G2231 as a bridge/converter/demultiplexer that recieves data through the USB the bridge takes bytes and puts alternately sends them to recievers 1-3. the recievers' P1.0 and P1.6 go to stepper motor controllers to step on rising edge and control direction, respectively. "bridge" part: -recieves bytes from 2400 8N1 input to P1.1 (requires launchpad 'RXD' jumper to be removed and the pin on the FTDI side connected to P1.1) -after reception, transmits each byte out of P1.6 as MOSI and P1.5 as SCLK. -cycles through bringing one of three output pins low as a chip select #include #include // Conditions for 2400 Baud SW UART, ACLK = 32768 #define Bitime_5 0x06 // ~ 0.5 bit length + small adjustment #define Bitime 0x0E // 427us bit length ~ 2341 baud #define RXD 0x02 #define TXD 0x20 #define LED1 0x01 #define LED2 0x40 unsigned char RXTXData; unsigned char BitCnt; unsigned char temp; static void __inline__ delay(register unsigned int n); int main (void){ WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer CCTL0 = OUT; // TXD Idle as Mark TACTL = TASSEL_1 + MC_2; // ACLK, continuous mode P1SEL = TXD + RXD; // P1DIR = TXD + LED1 + BIT4 + BIT3; P1OUT = LED1 + BIT4 + BIT3; USICTL0 = USIPE7 | USIPE6 | USIPE5 | USIMST | USIOE | USISWRST; // Port, SPI Master USICTL1 = USICKPH | USIIE; USICKCTL = 0xE4;// /128 aclk? temp = 0; while(1){ P1OUT |= LED1 + BIT4 + BIT3; BitCnt = 0x8; // Load Bit counter CCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE; // Sync, Neg Edge, Cap _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interr until char RXed if(temp == 2){ temp = 0; }else{ temp = temp +1; } } } // #pragma vector=TIMERA0_VECTOR interrupt(TIMERA0_VECTOR) Timer_A (void){ CCR0 += Bitime; // Add Offset to CCR0 if( CCTL0 & CAP ){ // Capture mode = start bit edge CCTL0 &= ~ CAP; // Switch from capture to compare mode CCR0 += Bitime_5; }else{ RXTXData = RXTXData >> 1; if (CCTL0 & SCCI) // Get bit waiting in receive latch RXTXData |= 0x80; BitCnt --; // All bits RXed? if ( BitCnt == 0){ USISRL = RXTXData; if(temp == 0){ P1OUT &= ~LED1; P1OUT |= BIT4 + BIT3; }else if(temp == 1){ P1OUT &= ~BIT4; P1OUT |= LED1 + BIT3; }else if(temp == 2){ P1OUT &= ~BIT3; P1OUT |= LED1 + BIT4; } USICNT |= 0x08; USICTL0 &= ~USISWRST; while (!(USIIFG & USICTL1)); USICTL0 |= USISWRST; delay(0); P1OUT |= LED1 + BIT4 + BIT3; CCTL0 &= ~ CCIE; // All bits RXed, disable interrupt _BIC_SR_IRQ(LPM3_bits + GIE); // Clear LPM3 bits from 0(SR) } } } static void __inline__ delay(register unsigned int n) { __asm__ __volatile__ ( "1: \n" " dec %[n] \n" " jne 1b \n" : [n] "+r"(n)); } The reciever recieves the byte from the bridge and in state machine fashion puts the byte in: -a counter for number of steps to take -determines to set or clear a direction bit -sets TACCR0 to control toggle rate #include #include unsigned int bufff; unsigned char count; int main(void){ WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1OUT = 0x00; // P1.4 set, else reset P1DIR = 0x01 + BIT6; // P1.0 output, else input USICTL0 |= USIPE7 + USIPE5; // Port, SPI slave USICTL1 |= USIIE; // Counter interrupt, flag remains set USICTL0 &= ~USISWRST; // USI released for operation USICNT = 8; // init-load counter bufff = 0; count = 0; TACTL = TASSEL_1 | MC_1; //Set TimerA to use auxiliary clock in UP mode TACCTL0 = CCIE; //Enable the interrupt for TACCR0 match TACCR0 = 2; _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt while(1){ } } // USI interrupt service routine interrupt(USI_VECTOR) universal_serial_interface(void){ if(count == 0){//bufff if(USISRL > 0x7A){ bufff = bufff + 0xFF00; }else{ bufff = bufff + USISRL; } }else if(count == 1){//dir if(USISRL > 0x3F){ P1OUT |= BIT6; }else{ P1OUT &= ~BIT6; } }else if(count == 2){//speed TACCR0 = USISRL; }else{ count = 0; } count = count + 1; if(count == 3){ count = 0; } USICNT = 8; // re-load counter } interrupt(TIMERA0_VECTOR) TIMERA0_ISR(void) { if( bufff > 0){ P1OUT ^= BIT0; bufff = bufff - 1; } } PROBLEMS: -the bridge can't pass data through it too fast. one must wait about ~200ms until the next byte is sent to prevent data loss. (the code isn't optimized and kinda "fatty" in all likelihood). -since the TimerA assignments from USI data occur in the USI-ISR (and i haven't found a reliable way to do it otherwise), the data isn't 'pushed' into TimerA until the next byte is recieved. -it would be cool to not have to modify the jumpers on the launchpad to do the UART, but its based on TI code that worked so i went with it. dacoffey, turd and bluehash 3 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.