#include "msp430.h" #include <intrinsics.h> #include <stdint.h> #include <math.h> // Define for CE Pin of 8*8 dot #define CEon() (P1OUT |= BIT5); #define CEoff() (P1OUT &= ~BIT5); // ISR Flags volatile int ISRcall = 0; volatile int debounce2 =0; volatile uint16_t countS2 =0; // Variables ADC volatile uint16_t adcValue =0; volatile float adcSegFloat =0; volatile unsigned long adcSeg =0; volatile int temp =0; // Variables for 8*8 Dot Matrix volatile uint16_t TXdata8dot8 [4] = {0x00, 0x00, 0x00, 0x00}; volatile uint16_t shapeLineVerRed[8] = {~0x00, ~0x00, ~0x00, ~0x00 , ~0x10, ~0x30, ~0x70, ~0xF0}; volatile uint16_t shapeLineVerGreen[8] = { ~0x01, ~0x03, ~0x07, ~0x0F , ~0x1F, ~0x3F, ~0x3F, ~0x3F}; volatile uint16_t coin =0; void buttonS2Call(void); void timerCall(void); void adcCall(void); void DOTstatic(void); void SPIwrite(uint16_t write); ///////////////////// Call Functions from ISR-Flag//////////////////////////// void buttonS2Call(void) { // Button Port 4 interrupt call Function // Set ISRcall to ISRcall=0; debounce2=1; // Start Timer in Upmode, Div 8, CCR0=1000, gives T=80ms TB0CTL = TBSSEL_2 + MC_1 + ID_3; } void timerCall(void) { ISRcall=0; if(debounce2) { // Get ADC Value adcCall(); countS2++; if(countS2 >= 800) { // Reset counter countS2 = 0; debounce2=0; // Stop Timer TB0CTL |= MC_0; // Enable Interrupt on P1.1 P4IES |= BIT5; // Falling edge P4IFG &= ~BIT5; // Interrupt Flag becomes 1 when interrupt is called P4IE |= BIT5; // Portpin Interrupt enable } } } void adcCall(void) { // ADC ON again and Start Comnversion ADC12CTL0 |= ADC12ON; ADC12CTL0|= (ADC12ENC | ADC12SC); // Divide into 8 Segments with 4096/544 and round with math.h adcSeg = (long)roundf(adcValue/544); //Come back from ISR and Call dot DOTstatic(); } void DOTstatic() { if(coin==0) { // Following shows bargraph with colour //RED LED TXdata8dot8[0] = shapeLineVerRed[adcSeg]; // Blue OFF TXdata8dot8[2] = 0xFF; // color blue off // Green LED TXdata8dot8[1] = shapeLineVerGreen[adcSeg]; TXdata8dot8[3] = (0x24); CEoff(); // when CE is low, display receives data SPIwrite(TXdata8dot8[0]); //transfer data[0] (red) SPIwrite(TXdata8dot8[2]); //transfer data[2] (green) SPIwrite(TXdata8dot8[1]); // transfer data[1] (blue) SPIwrite(TXdata8dot8[3]); // tansfer data[3] matrix displays CEon(); // when CE is High } else { // Off time of LEDS TXdata8dot8[0] =0xFF; // red off TXdata8dot8[2] = 0xFF; // color blue off TXdata8dot8[1] = 0xFF; // green off TXdata8dot8[3] = (0x18); CEoff(); // when CE is low, display receives data SPIwrite(TXdata8dot8[0]); //transfer data[0] to the matrix(red) SPIwrite(TXdata8dot8[2]); //transfer data[2] to the matrix(green) SPIwrite(TXdata8dot8[1]); // transfer data[1] to the matrix(blue) SPIwrite(TXdata8dot8[3]); // tansfer data[3] to the matrix CEon(); // when CE is High, means that matrix begin to display } } void SPIwrite(uint16_t write) { CEoff(); // loop here till Buffer is ready // the fill TXbuffer while(!(UCB0IFG & UCTXIFG)) { ; } // Load Buffer UCB0TXBUF = write; // Delay 100us necessary!!! // without last Byte can't be decoded __delay_cycles(100); } int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop Watchdog // Disable the GPIO power-on default high-impedance mode to activate // previously configured port settings, This is important PM5CTL0 &= ~LOCKLPM5; //////////////////////////////Clock to SMCLK=1MHz/////////////////////////////// // Set clock to min DCO 1Mhz, User guide p. 104 CSCTL0_H = CSKEY >> 8; // Unlock clock registers CSCTL1 = DCOFSEL_0 | DCORSEL; // Set DCO to 1MHz with DCOFSEL_0 CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers CSCTL0_H = 0; // Lock CS registers //////////////////////////////GPIOS///////////////////////////////////////////////// // Configure Switches on Ports P4.5 , direct to GND without PUllup//////// P4DIR &= ~BIT5; // Define Direction P4.5 = Input P4REN |= BIT5; // Define Pullup enable P1.1 P4OUT |= BIT5; // Define Pullup not Pulldown P4IES |= BIT5; // Falling edge P4IFG &= ~BIT5; // Interrupt Flag becomes 1 when interrupt is called P4IE |= BIT5; // Portpin Interrupt enable // Configure LEDS on Ports P4.6 and P1.0, direct to GND without PUllup//////// P4DIR |= BIT6; // Define Direction P4.6 = Output P1DIR |= BIT0; // Define Direction P1.0 = Output P4OUT |= BIT6; // Output to 1 P1OUT |= BIT0; // Output to 1 ///////Timer B0/////////////////////////////////////////// ///////TIMER A0//////////////////////////////////////////// TB0CCTL0 = CCIE; // TBCCR0 interrupt enabled TB0CCR0 = 10000; // PWM Period TB0CCTL1 = OUTMOD_2; // TBCCR1 reset/set TB0CCR1 = 5000; // TBCCR1 =1 // SMCLK, 1MHz, MC1=Upmode, Divider 8, Timer disabled with MC_0 TB0CTL = TBSSEL_2 + MC_0 + ID_3; // //TB0CTL = TBSSEL__SMCLK | MC__UP; ///////SPI B0//////////////////////////////////////////// // 1 step is Set UCSWRST before configure SPI, GPIOS UCB0CTLW0 |= UCSWRST; // P2SEL1.2 =1; P2SEL0.2 = 0 to set P2.2 to SPI CLK USCIB0, Page 84 P2SEL1 |= (BIT2); // P1SEL0 &= ~(BIT2); // P1SEL1 = 1, P1SEL0 = 0 to set Periph to SPI or I2C -> See datasheet on page 83 //P1.7 = UCB0SOMI //P1.6 = UCB0SIMO P1SEL0 &= ~(BIT6|BIT7); // P1SEL1 |= (BIT6|BIT7); // Pin Direction is set by eUSCI_B0 // GPIO as Software nSS P1DIR |= BIT5; // Define Direction P1.5 = Output P1OUT |= BIT5; // Output to 1 // Initialize SPI MOde 3 UCB0CTLW0 = UCCKPL| UCMST | UCMODE_0 | UCSYNC | UCMSB |UCSSEL__SMCLK |UCSWRST; // SPI Mode 3 needs UCCKPL = 1 -> Clock High in idle, UCCKPH=0 -> write on first failing edge; //Master,UCMODE_0-> 3 - wire default mode, Synchron, keep UCSWRST ==1 or nothing happens! // Set Prescaler for 100kHz SPI clockPrescale=1MHz/100kHz=10 UCB0BRW=10; // This Releases USCIB0 from reset UCB0CTLW0 &= ~UCSWRST; // RX Enable Interrupts on receive // UCB0IE |= UCRXIE; ///////ADC A10 Pin P4.2//////////////////////////////////////////// // Configure GPIOS, POt 10kOhm is on VCC, (P4.2->A10), (P2.6->GND) // P2.6 Output and set to Low P2DIR |= BIT6; P2OUT &= ~BIT6; // P4SEL1 =1; P4SEL0.2 = 1 Page 94 P4SEL1 |= (BIT2); // P4SEL0 |= (BIT2); // CTL Register 0: Set ADC12ON Bit, before any changes in CTL Regiser // ADC12=N Bit, ADC12SHT1 for ADC10 and 16 cycles //Sample for 16 cycles from 10*TAU=10*27pF*5k and clock 6.3MHz and rounded [cyles]=10Tau*fclk ADC12CTL0 = ADC12ON | ADC12SHT1_2; // CTL register 1: Single Conversion CONSEQ0, Clock Select ADC internal ADC120SC is mode 0, 3 is smclk, NO Clock divider // Sample and Hold source is trigger from ADC12SC ADC12CTL1 = ADC12CONSEQ0 | ADC12SSEL_0 | ADC12DIV0 | ADC12SHS0; // CTL Register 2: ADC12DF = 0, for Binary unsigned format 0x0000...0xFFFF, ADCREsolution 12Bit ADC12CTL2 = ADC12RES_2; // Very Important to choose the mem register, without doesn't enter the ISR ADC12CTL3 = ADC12CSTARTADD_10; // Conversion Memory control Register for ADC10, Reference is set to VCC, GND with ADC12VRSEL=0 ADC12MCTL10 = ADC12INCH_10; // Interrups ADC10 in Register 0 ADC12IER0 = ADC12IE10; _bis_SR_register(GIE); // interrupts enabled while(1) { switch(ISRcall) { case 1: timerCall(); break; // Timer wakes up CPU every 50ms and sets ISRcall=1; case 2: __no_operation(); break; // Do nothing case 3: buttonS2Call(); break; // Switch on P4.5 default: //_bis_SR_register(CPUOFF); ;break; } } } // Button S1 left #pragma vector=PORT4_VECTOR __interrupt void Port4_ISR(void) { // Set flag for button Call ISRcall=3; // toggle green LED P1OUT ^=BIT0; // Switch off red Toggle LED P4OUT &=~BIT6; // Clear Flags or being stuck in switch ISR P4IFG &= ~BIT5; // Flag register P4IE &= ~BIT5; // Portpin Interrupt Disable } // ISR for Timer A0/////////////////////////////////////////////////////// #pragma vector=TIMER0_B0_VECTOR __interrupt void Timer_B0 (void) { // Timer interrupt every 1000 * 8 /1MHz = 8ms // Toggle variable coin coin^=coin; // Set flag for timer Call ISRcall=1; } // ADC Interrupt #pragma vector = ADC12_VECTOR __interrupt void ADC12_ISR (void) { adcValue = ADC12MEM10; // Disable Conversion ADC12CTL0 &= ~ADC12ENC; ADC12CTL0 &= ~ADC12ON; // Toggle red LED P4OUT ^=BIT6; } // SPI Inerrupt #pragma vector = USCI_B0_VECTOR __interrupt void USCIB0_Rx_ISR (void) { //RXdata=UCB0RXBUF; }