Created
April 18, 2013 22:48
-
-
Save Guitlle/5416848 to your computer and use it in GitHub Desktop.
Osciloscopio para la launchpad MSP430 con el chip msp430g2553. Tiene 8 velocidades y funciona vía el puerto seria (UART) para que funcione deben voltear los JUMPERs que dicen TX y RX (hardware uart). A 9600 baudios por segundo, se le envía un caracter y la launchpad responde con 200 datos obtenidos mediante el ADC . Requiere que el cristal que t…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "msp430g2553.h" | |
#include "stdbool.h" | |
#define LED BIT6 | |
#define RXD BIT1 | |
#define TXD BIT2 | |
unsigned int i; // for loop variable | |
volatile unsigned char rx_flag = 0; | |
volatile unsigned char tx_flag = 0; | |
volatile unsigned char rx_char = 0; | |
volatile unsigned char tx_char = 0; | |
void Set_DCO(); | |
void print(char *); | |
void print_newline(); | |
void print_hexb(register unsigned char); | |
void print_hexw(register unsigned int); | |
unsigned char ugetc(); | |
void uputc(register unsigned char c); | |
void print(); | |
// ASCII values for the commands | |
#define TEST 0x31 | |
#define CALIB 0x32 | |
#define M_A3 0x33 | |
#define M_TEMP 0x34 | |
#define M_VCC 0x35 | |
#define BURST1 97 | |
#define BURST2 98 | |
#define BURST3 99 | |
#define BURST4 100 | |
#define BURST5 101 | |
#define BURST6 102 | |
#define BURST7 103 | |
#define IDLE 0x00 | |
#define AWAKE_ME 0x01 | |
bool ADCDone; // ADC Done flag | |
unsigned int ADCValue; // Measured ADC Value | |
unsigned char datos[400], Estado; | |
/** | |
* Reads ADC 'chan' once using AVCC as the reference. | |
**/ | |
void Single_Measure(unsigned int chan) | |
{ | |
ADC10CTL0 &= ~ENC; // Disable ADC | |
ADC10CTL0 = ADC10SHT_3 + ADC10ON + ADC10IE; // 64 clock ticks, ADC On, enable ADC interrupt | |
ADC10CTL1 = ADC10SSEL_3 + chan; // // Set 'chan', SMCLK | |
ADC10CTL0 |= ENC + ADC10SC; // Enable and start conversion | |
} | |
/** | |
* Reads ADC 'chan' once using an internal reference, 'ref' determines if the | |
* 2.5V or 1.5V reference is used. | |
**/ | |
void Single_Measure_REF(unsigned int chan, unsigned int ref) | |
{ | |
ADC10CTL0 &= ~ENC; // Disable ADC | |
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ref + ADC10IE; // Use reference, | |
// 64 clock ticks, internal reference on | |
// ADC On, enable ADC interrupt, Internal = 'ref' | |
ADC10CTL1 = ADC10SSEL_3 + chan; // Set 'chan', SMCLK | |
__delay_cycles (400); // Delay to allow Ref to settle | |
ADC10CTL0 |= ENC + ADC10SC; // Enable and start conversion | |
} | |
void loop(){ | |
if(ADCDone) // If the ADC is done with a measurement | |
{ | |
ADCDone = false; // Clear flag | |
print_hexw(ADCValue); | |
print_newline(); | |
} | |
ugetc(); | |
switch(rx_char) // Switch depending on command value received | |
{ | |
case CALIB: | |
print ("BCSCTL1 ");print_hexb(BCSCTL1);print_newline(); | |
print ("DCOCTL ");print_hexb(DCOCTL); | |
print_newline();break; | |
case TEST: | |
print("#TEST LED\n\r"); | |
P1OUT ^= BIT6; // toggle led | |
break; | |
case M_A3: | |
Single_Measure(INCH_0); // Reads A0 only once | |
break; | |
case M_TEMP: | |
Single_Measure_REF(INCH_10, 0); // Reads the temperature sensor once | |
break; | |
case M_VCC: | |
Single_Measure_REF(INCH_11, REF2_5V); // Reads VCC once (VCC/2 internally) | |
break; | |
case BURST1: | |
case BURST2: | |
case BURST3: | |
case BURST4: | |
case BURST5: | |
case BURST6: | |
case BURST7: | |
ADC10CTL0 = ADC10SHT_1 + MSC + ADC10ON + ADC10IE ; | |
print("#Transmitiendo BURST"); | |
switch (rx_char){ | |
case BURST1: | |
ADC10CTL1 = CONSEQ_2 + INCH_0 + ADC10SSEL_3; | |
print(" DIV0 "); | |
break; | |
case BURST2: | |
ADC10CTL1 = CONSEQ_2 + INCH_0 + ADC10DIV_1 + ADC10SSEL_3; | |
print(" DIV1 "); | |
break; | |
case BURST3: | |
ADC10CTL1 = CONSEQ_2 + INCH_0 + ADC10DIV_3 + ADC10SSEL_3 ; | |
print(" DIV3 "); | |
break; | |
case BURST4: | |
ADC10CTL1 = CONSEQ_2 + INCH_0 + ADC10DIV_7 + ADC10SSEL_3; | |
print(" DIV7 "); | |
break; | |
case BURST5: | |
ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE ; | |
ADC10CTL1 = CONSEQ_2 + INCH_0 + ADC10DIV_7 + ADC10SSEL_3; | |
print(" DIV7 "); | |
break; | |
case BURST6: | |
ADC10CTL0 = ADC10SHT_3 + MSC + ADC10ON + ADC10IE ; | |
ADC10CTL1 = CONSEQ_2 + INCH_0 + ADC10DIV_7+ADC10SSEL_3; | |
print(" DIV7 "); | |
break; | |
case BURST7: | |
ADC10CTL1 = CONSEQ_2 + INCH_0 + ADC10SSEL_1; // AMCLK | |
print(" DIV8 "); | |
break; | |
} | |
print_newline(); | |
// ADC10ON, interrupt enabl | |
ADC10DTC1 = 200; // 225 conversions | |
ADC10AE0 |= BIT0; // P1.0 ADC option select | |
ADC10CTL0 &= ~ENC; | |
while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active | |
ADC10SA = (unsigned int) datos; // Data buffer start | |
P1OUT |= BIT6; // Set GREEN LED on | |
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start | |
Estado = AWAKE_ME; | |
__bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit | |
P1OUT &= ~BIT6; // Clear GREEN LED off | |
for (i=0;i<400;i+=2){ | |
print_hexb(datos[i+1]); | |
print_hexb(datos[i]); | |
print_newline(); | |
} | |
break; | |
default:; | |
} | |
} | |
/** | |
* ADC interrupt routine. Pulls CPU out of sleep mode | |
**/ | |
#pragma vector=ADC10_VECTOR | |
__interrupt void ADC10_ISR (void) | |
{ | |
if (Estado == AWAKE_ME){ | |
Estado = IDLE; | |
__bic_SR_register_on_exit(CPUOFF); // Enable CPU | |
return; | |
} | |
ADCValue = ADC10MEM; // Saves measured value. | |
ADCDone = true; // Sets flag for main loop. | |
__bic_SR_register_on_exit(CPUOFF); // Enable CPU so the main while loop continues | |
} | |
void main(void) | |
{ | |
WDTCTL = WDTPW + WDTHOLD; // Stop WDT | |
Set_DCO(); | |
//***************** INIT USCI UART | |
P1DIR |= LED; | |
P1OUT |= LED; | |
//BCSCTL2 |= BIT1; // SMCLK = DCOCLK / 2 | |
P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD | |
P1SEL2 = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD | |
UCA0CTL1 |= UCSSEL_2; // SMCLK | |
UCA0BR0 = 0x80; // 9600 | |
UCA0BR1 = 0x1; // 9600 | |
UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 | |
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** | |
IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt | |
__bis_SR_register(GIE); // Enter LPM0, interrupts enabled | |
while (1){ | |
loop(); | |
} | |
} | |
unsigned char ugetc() //Waits for a valid char from the UART | |
{ | |
while (rx_flag == 0); //Wait for rx_flag to be set | |
rx_flag = 0; //ACK rx_flag | |
return rx_char; | |
} | |
void uputc(register unsigned char c) | |
{ | |
while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? | |
UCA0TXBUF = c; // TX -> c | |
} | |
void print(char *str) //Sends a String to the UART. | |
{ | |
while(*str) uputc(*str++); //Advance though string till end | |
return; | |
} | |
#pragma vector = USCIAB0RX_VECTOR | |
__interrupt void USCI0RX_ISR(void) | |
{ | |
rx_char = UCA0RXBUF; | |
rx_flag = 1; | |
} | |
//-------------------------------------------------------------------------- | |
void Set_DCO() // Set DCO to 3.6864 MHz | |
//-------------------------------------------------------------------------- | |
{ | |
#define Delta 3686400/4096 // 3686400 | |
BCSCTL3 = (BCSCTL3 & ~XCAP_3) | XCAP_0; | |
__delay_cycles(0xFFFF); | |
unsigned int Compare, Oldcapture = 0; | |
BCSCTL1 |= DIVA_3; // ACLK = LFXT1CLK/8 | |
TACCTL0 = CM_1 | CCIS_1 | CAP; // CAP, ACLK | |
TACTL = TASSEL_2 | MC_2 | TACLR; // SMCLK, continuous mode, clear | |
while (1) { | |
while (!(CCIFG & TACCTL0)); // Wait until capture occurred | |
TACCTL0 &= ~CCIFG; // Capture occurred, clear flag | |
Compare = TACCR0; // Get current captured SMCLK | |
Compare = Compare - Oldcapture; // SMCLK difference | |
Oldcapture = TACCR0; // Save current captured SMCLK | |
if (Delta == Compare) break; // If equal, leave "while(1)" | |
else if (Delta < Compare) { | |
DCOCTL--; // DCO is too fast, slow it down | |
if (DCOCTL == 0xFF) // Did DCO roll under? | |
if (BCSCTL1 & 0x0f) | |
BCSCTL1--; // Select lower RSEL | |
} | |
else { | |
DCOCTL++; // DCO is too slow, speed it up | |
if (DCOCTL == 0x00) // Did DCO roll over? | |
if ((BCSCTL1 & 0x0f) != 0x0f) | |
BCSCTL1++; // Select higher RSEL | |
} | |
} | |
TACCTL0 = 0; // Stop TACCR0 | |
TACTL = 0; // Stop Timer_A | |
BCSCTL1 &= ~DIVA_3; // ACLK = LFXT1CLK | |
__delay_cycles(0x4000); | |
} | |
void print_newline() | |
{ | |
uputc('\n'); | |
uputc('\r'); | |
} | |
void print_hexb(register unsigned char c) | |
{ | |
static const unsigned char hextbl[]="0123456789ABCDEF"; | |
uputc(hextbl[c >> 4]); | |
uputc(hextbl[c& 0x0F]); | |
} | |
void print_hexw(register unsigned int c) | |
{ | |
static const unsigned char hextbl[]="0123456789ABCDEF"; | |
uputc(hextbl[c >> 12]); | |
uputc(hextbl[(c >> 8)& 0x000F]); | |
uputc(hextbl[(c >> 4)& 0x000F]); | |
uputc(hextbl[c & 0x000F]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment