#include #include "msp430g2131.h" //------------------------------------------------------------------------------ // Definitions //------------------------------------------------------------------------------ #define SPEED_REF BIT0 // P1.0 #define LED BIT1 // P1.1 #define PHASE BIT2 // P1.2 #define DIRECTION BIT3 // P1.3 #define ADC_VREF BIT4 // P1.4 #define ENABLE BIT6 // P2.6 //------------------------------------------------------------------------------ // Global variables //------------------------------------------------------------------------------ //unsigned int s_checksum = 0; unsigned int i, m_cnt, counter, flag = 0; unsigned int cnt = 0; unsigned int DutyCycle = 0; // PWM duty cycle unsigned int ADC_val = 0; unsigned int high = 400; unsigned int low = 0; // 1600; unsigned int master_data[12]; // array to store the 12B data from the master unsigned int slave_data[12] = {0x7E, 0x5D, 0x78, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x00, 0x00, 0x00, 0x00}; // array to store the 12B data from the slave unsigned int *pslaveArray = slave_data; // pointer pointing to slave_data array //------------------------------------------------------------------------------ // Declare functions //------------------------------------------------------------------------------ /* * Function to calculate checksum */ unsigned int checksum(unsigned int array[], int size) { unsigned int sum = 0; unsigned int j = size; for( ; j > 0; j--) { sum += array[j-1]; } return sum; } /* * Function to check the master array */ void master_check(unsigned int master_array[12]) { // Combine both the duty cycle (DC) values from the master as integer values to compare them later unsigned int asked_DC = (master_array[3] << 8) + master_array[2]; unsigned const int safe_DC = 0x00 + 0x1C; ////// CHECK IF I NEED TO BIT SHIFT // unsigned int crc_code = master_array[10] + master_array[11]; // Add the last 2 elements of master's array ////// CHECK IF I NEED TO BIT SHIFT // unsigned int m_checksum = checksum(master_array, 10); // Calculate the value of checksum for the master's array // if(m_checksum == crc_code) // if the calculated checksum is the same as the last 2 bytes in the master's array proceed // { slave_data[2] = 0x02; //change the board_status to unstable(moving) // check if the asked DC from the master is less than the limit DC. // if(asked_DC <= safe_DC) // Yes then change that value into the slave data array accordingly // { CCTL1 &= ~CCIE; TACTL &= ~TAIE; DutyCycle = asked_DC; high = DutyCycle; //low = 2000 - high; CCTL1 |= CCIE; TACTL |= TAIE; /** DutyCycle = asked_DC; CCR1 = DutyCycle; **/ // } // else // No then put the limit DC value into the slave data array accordingly // { // DutyCycle = safe_DC; // high = DutyCycle; // low = 100 - high; // CCR1 = DutyCycle; // } // } } /* * Function to initialize values */ void init(void) { IE1 |= WDTIE; // Enable WDT interrupt BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; // P1SEL &= ~PHASE; // Make sure P1.2 peripheral functionality is disabled P1SEL = PHASE + LED; // Using timer output on pins 1.1 and 1.2 P1OUT = 0x00; // P1.x Reset // P1DIR = 0xF6; // P1.3,0 inputs, else outputs P1DIR = 0x56; P2SEL = 0x00; // P2.x no options P2OUT = 0x00; // P2.x Reset P2DIR = 0x01; // P2.6 (ENX) pin output, else inputs // P2SEL = ENABLE; // Select secondary functionality on P2.6, tying it to TA0.1 // P2OUT = 0x00; // P2.x reset // P2DIR = 0xFF; // P2.x outputs // CCTL0 = OUTMOD_7; // CCTL1 = OUTMOD_7; // CCR1 in reset/set mode // CCR0 = 64 - 1; // 6-bit PWM period // CCR1 = 13; // CCR1 Duty cycle to 20% // TACTL = TASSEL_2 + MC_1; // SMCLK source, up mode CCTL0 = CCIS_0 + OUTMOD_4 + CCIE; // CCR0 toggle, interrupt enabled, CCI0A input on CCI CCTL1 = CCIS_0 + OUTMOD_4 + CCIE; TACTL = TASSEL_2 + MC_2 + TAIE; // SMCLK source, continuous mode, int enabled ADC10CTL0 = ADC10SHT_2 + ADC10ON; // + ADC10IE; // VCC ref ADC10CTL1 = INCH_0; // Input A0 ADC10AE0 |= 0x01; // PA.0 ADC option select //ADC10AE0 |= INCH_0; // Input A0 USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIOE; // Port, SPI slave USICTL1 |= USIIE; // Counter interrupt, flag remains set USICTL0 &= ~USISWRST; // USI released for operation USISRL = 0xCD; // init-load data into the lower byte of the serial register USISRH = 0xEF; // init-load data into the higher byte of the serial register USICNT = USI16B + 16; // init-load counter + enable 16-bit shift register mode } //------------------------------------------------------------------------------ // Main function //------------------------------------------------------------------------------ int main(void) { WDTCTL = WDT_MDLY_8; // Set Watchdog Timer interval to ~30ms // __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupt init(); while(1) { _BIS_SR(LPM0_bits + GIE); // Enter LPM0 with interrupts // P1OUT |= ADC_VREF; // Enable poti divider ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start while (ADC10IFG & ADC10CTL0); // Wait for conversion complete ADC10CTL0 &= ~ADC10IFG; // Clear converstion flag // P1OUT &= ~ADC_VREF; // Disable poti divider // DutyCycle = 63 - (ADC10MEM>>4); // Mask upper 6-bits // CCR1 = DutyCycle; // PWM duty cycle to DRV if (DIRECTION & P1IN) // Forward direction? { P1OUT |= ENABLE; } else // Reverse { P1OUT &= ~ENABLE; } if (cnt == 1) { //if (CCR0 == (CCR0 + 60)) //if (TAR == (CCR0 = 60)) //{ // ADC_val == ADC10MEM; //} slave_data[11] = low; if ((low - slave_data[11]) == 60) { ADC_val = ADC10MEM; cnt = 0; } } } } // Watchdog Timer interrupt service routine #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void) { _BIC_SR_IRQ(LPM3_bits); // Clear LPM0 bits from 0(SR) } // USI interrupt service routine #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USI_VECTOR __interrupt void universal_serial_interface(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USI_VECTOR))) universal_serial_interface (void) #else #error Compiler not supported! #endif { if(flag == 0 || ((USISRH == 0x7E) && (USISRL == 0x5D))) { flag = 1; m_cnt = 0; } if(flag == 1) { master_data[m_cnt] = USISRH; master_data[m_cnt+1] = USISRL; m_cnt = m_cnt + 2; } if (m_cnt >= 10) { flag = 0; if((master_data[0] == 0x7E) && (master_data[1] == 0x5D)) //Check if the master header is right master_check(master_data); } if(counter >= 12) { counter = 0; //slave_data[3] = ADC10MEM; //sampling lower 8 bytes first //slave_data[4] = ADC10MEM >> 8; //shift the upper 8 bytes to the left to sample them slave_data[3] = ADC_val; //sampling lower 8 bytes first slave_data[4] = ADC_val >> 8; // slave_data[5] = DutyCycle; // slave_data[6] = DutyCycle >> 8; //slave_data[5] = CCR1; //slave_data[6] = CCR1 >> 8; // s_checksum = checksum(slave_data, 10); // slave_data[10] = s_checksum; // slave_data[11] = s_checksum >> 8; } pslaveArray = slave_data + counter; //USISRL = *pslaveArray; //USISRH = *(pslaveArray+1); USISRL = *(pslaveArray+1); USISRH = *(pslaveArray); USICNT = USI16B + 16; counter = counter + 2; } // Timer A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A0 (void) // Generate 20Hz frequency with 20% constant duty cycle for sensor { if(CCTL0 & CCI) // If output currently high { CCR0 += 10000; // 20% high cnt = 1; low = low + 1; // if (CCR0 == (CCR0 + 60)) // { // ADC_val == ADC10MEM; // } } else { CCR0 += 40000; // 80% low } //low = low + 1; } // Timer A1 Interrupt Vector (TA0IV) handler #pragma vector=TIMER0_A1_VECTOR __interrupt void Timer_A1(void) // Generate 500Hz frequency for DRV motor { switch( TA0IV ) { case 2: if(CCTL1 & CCI) // If output currently high { CCR1 += high; } else { low = 2000 - high; CCR1 += low; } break; default: break; } //low = low + 1; } /** // ADC10 interrupt service routine #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) #elif defined(__GNUC__) void __attribute__ ((interrupt(ADC10_VECTOR))) ADC10_ISR (void) #else #error Compiler not supported! #endif { //ADC_val = ADC10MEM; __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR) } **/