/**************************************************************************** * file: dual_wise_template.c * author: Emil Jovanov * last change: October 6, 2003 * description: this file is a template for future programs based on the * wise configuration. this template includes basic * initialization and routines for leds and serial comm. * ****************************************************************************/ #include #include "gendef.h" #include "wdt.h" //support for watchdog timer #include "leds.h" //support for the leds #include "rs232.h" //support for RS232 comm. #include "linx.h" //support for linx #include "acc.h" //support for accelerometer //these are defines that represent which 'program' to use after reset #define DEFAULT_PRG 0x00 #define ALTERNATE_PRG 0x01 // this is the variable that will hold the info of which 'program' to use uint8 program = ALTERNATE_PRG; // this function is provided by initclk.c void SpeedUpClock(void); // functions in adc.c void init_adc(void); //initialize ADC // this fucntion creates and sends packets void send_data(void); // this is a generic delay function used just to space out events such as // turning leds on and off. this will give a blinking effect. // Delay very approximately 1 second. void delay(void) { // Note: i is an unsigned integer. If not declared unsigned, 65000 in 16 bits // becomes a negative number, and the loop is executed only once! unsigned int i; for (i = 65000; i > 0; i--); } // these variables are used in acc.c // the following variables are used to hold info about the accelerometer // variables to hold pulse width data for accelerometer x and y unsigned int PWX = 0, PWY = 0; // variables representing low period of x and y (PWM) unsigned int x_period_low = 0, y_period_low = 0; //this variable is shared by dual_wise.c and, when using adc, adc.c uint8 samples[4]={0,0,0,0}; /* program driver */ void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer SpeedUpClock(); //this comes from initclk.c UART_Initialize(); //this will enable RS232 communications LED_SETUP(); //this will setup the ability to use the LEDs. //this is provided by leds.h. //check the state of the PRG button; this will determine which program //to use //from this we will setup different parts of the controller to perform //different tasks //first we have to set it up for input P4DIR &= ~BIT4; //PRG uses P4.4 as an input P4SEL &= ~BIT4; //use P4.4 as a pin //now actually check the state of PRG //remember that PRG uses reverse logic if (!(P4IN & BIT4)) //if PRG is being pressed { //set program to the alternate program //for this file the 'alternate program' is to sample the accelerometer. program = ALTERNATE_PRG; //now setup the necessary components to use the Accelerometer init_acc(); /* initialize accelerometer */ } else //if PRG is not being pressed { //set program to the default program //for this file the 'default program' is to sample from the ADC program = DEFAULT_PRG; //now setup the necessary components to use the ADC // setup ADC interrupts and watchdog init_adc(); //initialize ADC } //end of PRG state check //setup the watch dog timer //this is provided by wdt.h WD_Timer(); _EINT(); //enable interrupts, these interrupts come from //the init routines. //get linx ready to use LINX_setup(); LINX_transmit(); delay10ms(); //this is the main body of the program, we will assume that we never stop while(1) // Repeat forever { //the following will just blink the LEDS LEDON0; //turn LED #0 on delay(); //delay for some time LEDOFF0; //turn LED #0 off } //end while(1) } //this is the function to send the two bytes of the ADC register to the PC void send_data(void) { uint8 cs,x; cs = 0; for (x=0;x<4;x++) { cs += samples[x]; UART1_putchar(samples[x]); } UART1_putchar(cs); } /***********************************************************************/ /* Watchdog interrupt service routine */ /***********************************************************************/ /* * This isr takes samples at a rate of 122Hz. * the sample are of analog channels described in the ADC12 setup. * */ /* * Watchdog Timer has the following attributes: * the clock source was selected to be ACLK, * interval is ACLK * 2^15, * it was initially cleared, * it is in interval timer mode, * RST/NMI input works as a reset input, * a rising edge triggers the NMI (Non-Maskable Interrupt) interrupt, * the WDT is fully active, * * using our 4MHz clock, we create a frequency of 122 Hz, * an interval of 8.2 ms * * Additional information can be obtained from the user's manual * starting at page 133 * */ interrupt [WDT_VECTOR] void WD( void ) { //these variables are used for accelerometer unsigned int period; unsigned int x_temp, y_temp; switch (program) { case ALTERNATE_PRG: //for this file the 'alternate program' is to sample the accelerometer. //perform the necessary WD fucntions for the accelerometer /* first disable interrupts, then make copies of data */ P1IE &= ~ACCEL_X_INT & ~ACCEL_Y_INT; x_temp = PWX; y_temp = PWY; /* first get the length of the total cycle of the */ /* accelerometer */ period = PWX + x_period_low; /* now enable interrupts */ P1IE |= ACCEL_X_INT | ACCEL_Y_INT; /* send x and y data to pc in respective order. */ /* the following is the formula used to compute the */ /* acceleration of the accelerometer. */ /* A(g) = (T1/T2 -.5)/4% where 0g = 50% duty cycle */ /* T1 is the length of modulated high period. T2 is */ /* lenght of the total cycle. */ /* send x to the PC */ /* 4095 is the current maximum used in the analog */ /* devices. */ /*x_Ag = 4095 * (x_temp/period - .5) / .04; y_Ag = 4095 * (y_temp/period - .5) / .04; */ // P1OUT ^= 0x01; samples[0] = x_temp & 0xFF; samples[1] = (x_temp >> 8) & 0x0F; samples[2] = y_temp & 0xFF; samples[3] = (y_temp >> 8) & 0x0F; //send the samples out. send_data(); break; case DEFAULT_PRG: //for this file the 'default program' is to sample from the ADC. //perform the necessary WD fucntions for the accelerometer send_data(); ADC12CTL0 |= ADC12SC; // start sampling (trigger signal) break; default: break; } }