📄 msp430f2012writewav.c
字号:
//******************************************************************************
// MSP430F2012WriteWAV.c - This software is designed for eZ430-Speech to write
// external SPI Flash with audio data by converting
// asynchronous UART data to SPI. A program similar to
// Hyperterminal can be used to load the audio file.
//
//
// MSP430F20xx
// -----------------
// /|\| |
// | | |
// --|RST |
// | |
// | TA1/TXD/P1.2|-------->
// | | 38400 8N1
// | CCI0A/RXD/P1.1|<--------
// | |
// | P1.0|---->/HOLD M25P64
// | |
// | P1.3|---->/S (Chip Select) M25P64
// | |
// | P1.5/SCLK|-------->
// | P1.6/SDO|--------> SPI master
// | P1.7/SDI|<--------
//
//
// P. Forstner
// Texas Instruments Inc.
// January 2009
// Built with IAR Embedded Workbench Version: v4.11
// Built with CCE Version: 3.1 Build 3.2.3.6.4
//******************************************************************************
#define RXD 0x02 // RXD on P1.1
#define TXD 0x04 // TXD on P1.2
#define SCLK 0x20 // SCLK on P1.5
#define SDO 0x40 // SDO on P1.6
#define SDI 0x80 // SDO on P1.7
/// Conditions for 4800 Baud SW UART, SMCLK = 16MHz
// #define Bitime50 1666 // ~50% bit length
// #define Bitime80 2666 // ~ 80% bit length
// #define Bitime99 3300 // ~ 99% bit length
// #define Bitime 3333 // 16MHz / 4800 Baud = 3333
// Conditions for 9600 Baud SW UART, SMCLK = 16MHz
// #define Bitime50 833 // ~50% bit length
// #define Bitime80 1333 // ~ 80% bit length
// #define Bitime99 1650 // ~ 99% bit length
// #define Bitime 1666 // 16MHz / 9600 Baud = 1667
// Conditions for 19200 Baud SW UART, SMCLK = 16MHz
// #define Bitime50 416 // ~50% bit length
// #define Bitime80 666 // ~ 80% bit length
// #define Bitime99 825 // ~ 99% bit length
// #define Bitime 833 // 16MHz / 19200 Baud = 833
// Conditions for 38400 Baud SW UART, SMCLK = 16MHz
#define Bitime50 208 // ~ 50% bit length
#define Bitime80 333 // ~ 80% bit length
#define Bitime99 412 // ~ 99% bit length
#define Bitime 416 // 16MHz / 38400 Baud = 416
#define FlashVccPOUT P2OUT
#define FlashVccPDIR P2DIR
#define FlashVccBIT BIT7 // P2.7 is M25P64 Vcc
#define FlashSelPOUT P1OUT
#define FlashSelPDIR P1DIR
#define FlashSelBIT BIT3 // P1.3 is M25P64 SELECT
#define LEDPOUT P1OUT
#define LEDPDIR P1DIR
#define LEDBIT BIT0 // P1.0 is LED
unsigned int RXTempData;
unsigned int TXTempData;
unsigned char RXData;
unsigned char TXData;
unsigned char RXBitCnt;
unsigned char TXBitCnt;
unsigned char RXUARTDataValid;
unsigned char RXUARTOverrun;
unsigned int RXCounter;
unsigned int TXCounter;
unsigned char TXDataUSI;
unsigned char RXDataUSI;
unsigned char USIcompleteRX;
unsigned char BinValue;
unsigned char RXhex16;
unsigned char hex16;
unsigned char hex1;
unsigned char RcvIdx;
void TX_UART (void);
void RX_UART_Start (void);
void TX_USI (void);
void HEX2BIN (void);
void BIN2HEX (void);
#include <msp430x20x3.h>
void main (void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
// Control signals of external Flash
FlashVccPOUT |= FlashVccBIT;
FlashVccPDIR |= FlashVccBIT; // Flash Vcc is MSP430 output = HIGH
__delay_cycles(550000);
FlashSelPOUT |= FlashSelBIT;
FlashSelPDIR |= FlashSelBIT; // Flash SELECT is MSP430 output = HIGH
FlashSelPDIR &= ~FlashSelBIT; // Flash SELECT is MSP430 output = LOW
FlashSelPDIR |= FlashSelBIT; // Flash SELECT is MSP430 output = HIGH
LEDPOUT |= LEDBIT;
LEDPDIR |= LEDBIT; // status LED is MSP430 output = HIGH
// Initialize Software UART with Timer_A2
CCTL1 = OUT; // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode
P1SEL |= TXD + RXD; // Configure I/Os for UART
P1DIR |= TXD; // Configure I/Os for UART
RXUARTDataValid = 0; // No char yet received
RXUARTOverrun = 0; // No RX buffer overrun yet
// Initialize SPI master with USI
USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE; // Init I/Os, SPI master
USICTL1 |= USICKPH; // sample on rising edge
USICKCTL = USIDIV_7 + USISSEL_2; // USICLK = SMCLK / 127 = 125kHz
USICTL0 &= ~USISWRST; // USI released for operation
USIcompleteRX = 0; // No RX transmission result
__delay_cycles(40000); // Time for VCC to rise to 3.3V
if ((CALDCO_16MHZ == 0xFF) || (CALBC1_16MHZ == 0xFF))
{
while(1) // Blink LED if calibration data
{ // missing
LEDPOUT ^= LEDBIT; // Toggle LED
__delay_cycles(60000);
}
}
DCOCTL = CALDCO_16MHZ; // DCO = 16MHz calibrated
BCSCTL1 = CALBC1_16MHZ; // DCO = 16MHz calibrated
__bis_SR_register(GIE); // Enable Inteerupts GIE
// Mainloop
RcvIdx = 0;
RXCounter = 0;
TXCounter = 0;
RX_UART_Start(); // UART ready to RX one Byte
while (1)
{
if (RXUARTDataValid)
{
if (((RXData >= '0') && (RXData <= '9')) || ((RXData >= 'A') && (RXData <= 'F')))
{
switch (RcvIdx)
{
case 0:
RXhex16 = RXData;
RXUARTDataValid = 0;
RcvIdx++;
break;
case 1:
hex16 = RXhex16;
hex1 = RXData;
RXUARTDataValid = 0;
RcvIdx = 0;
HEX2BIN ();
FlashSelPOUT &= ~FlashSelBIT; // Flash CS = low
TXDataUSI = BinValue;
TX_USI();
break;
default:
FlashSelPOUT |= FlashSelBIT; // Flash CS = high
RcvIdx = 0;
}
}
else
{
RcvIdx = 0;
FlashSelPOUT |= FlashSelBIT; // Flash CS = high
}
}
if (USIcompleteRX)
{
BinValue = RXDataUSI;
BIN2HEX();
TXData = hex16; // send the SPI rcv data with UART
TX_UART(); // TX Back RXed Byte Received
TXData = hex1; // send the SPI rcv data with UART
TX_UART(); // TX Back RXed Byte Received
USIcompleteRX = 0; // no valid USI RX data
}
}
}
//******************************************************************************
// Transmit byte with USI in SPI mode
//******************************************************************************
void TX_USI (void)
{
USISRL = TXDataUSI; // init-load data
USIcompleteRX = 0; // indicate transmission in progress
USICNT = 8; // init-load counter
USICTL1 |= USIIE; // Counter int., flag remains set
}
//******************************************************************************
// Function Transmits Character from TXData Buffer
//******************************************************************************
void TX_UART (void)
{
while ( TACCTL1 & CCIE ); // Wait for previous TX completion
TXBitCnt = 10; // Load Bit counter, 8data + ST/SP
TXTempData = 0xFF00 + TXData; // Add stop bit + idle bits to TXData
TACCR1 = TAR +14; // Current state of TA counter
// + 14 TA clock cycles till first bit
TACCTL1 = OUTMOD2 + OUTMOD0 + CCIE; // TXD = '0' = start bit, enable INT
}
//******************************************************************************
// Function Readies UART to Receive Character into RXTXData Buffer
//******************************************************************************
void RX_UART_Start (void)
{
RXBitCnt = 8; // Load Bit counter
TACCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE; // Sync, Neg Edge, Cap
}
//******************************************************************************
// HEX2BIN converts the HEX character 'ab' into a binary value
//******************************************************************************
void HEX2BIN (void)
{
if ((hex16 >= '0') && (hex16 <= '9')) BinValue = (hex16 - '0') << 4;
else BinValue = (hex16 - 'A' + 10) << 4;
if ((hex1 >= '0') && (hex1 <= '9')) BinValue = (hex1 - '0') + BinValue;
else BinValue = (hex1 - 'A' + 10) + BinValue;
}
//******************************************************************************
// BIN2HEX converts the binary number 'bin' into the HEX value 'ab'
//******************************************************************************
void BIN2HEX (void)
{
char number;
number = (BinValue >> 4) & 0x0F;
if (number < 10) hex16 = number + '0';
else hex16 = number + 'A' - 10;
number = (BinValue & 0x0F);
if (number < 10) hex1 = number + '0';
else hex1 = number + 'A' - 10;
}
//******************************************************************************
// Timer A0 interrupt service routine - UART RX
//******************************************************************************
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A0_ISR (void)
{
TACCR0 += Bitime; // Add Offset to CCR0
if( TACCTL0 & CAP ) // Capture mode = start bit edge
{
TACCTL0 &= ~CAP; // Switch from capture to compare mode
TACCR0 += Bitime50;
}
else
{
RXTempData = RXTempData >> 1;
if (TACCTL0 & SCCI) // Get bit waiting in receive latch
RXTempData |= 0x80;
RXBitCnt --; // All bits RXed?
if ( RXBitCnt == 0)
{
RXData = (char) RXTempData;
if (RXUARTDataValid) RXUARTOverrun = 1;
RXUARTDataValid = 1; // RXData is valid
RXBitCnt = 8; // Re-Load Bit counter for next RX char
TACCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE; // Sync, Neg Edge, Cap
// wait for next falling RX edge
// which is the next start bit
// last bit has been received
__bic_SR_register_on_exit(LPM4_bits); // Clear all LPM bits from 0(SR)
}
}
}
//******************************************************************************
// Timer A1 interrupt service routine - UART TX
//******************************************************************************
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A1_ISR (void)
{
switch (__even_in_range(TAIV, 10)) // Use calculated jump table branching
{
case 2: if(TXBitCnt == 0) // TACCR1 CCIFG - UART TXD
{
TACCTL1 &= ~CCIE; // All bits TXed, disable interrupt
// last bit = stop-bit has been transmitted
}
else
{
if(TXBitCnt == 1)
TACCR1 += Bitime80; // Stop bit is a bit shorter to
else // get time for CPU processing
TACCR1 += Bitime99; // Add Offset to CCR0
// For full speed echo TX should
// be a bit faster than RX to
// avoid overruns
TACCTL1 |= OUTMOD2; // TX '0'
if(TXTempData & 0x01)
TACCTL1 &= ~ OUTMOD2; // TX '1'
TXTempData = TXTempData >> 1;
TXBitCnt --;
}
break;
case 4: break; // TACCR2 CCIFG
case 6: break; // Reserved
case 8: break; // Reserved
case 10: break; // TAIFG
default: break;
}
}
//******************************************************************************
// USI interrupt service routine
//******************************************************************************
#pragma vector=USI_VECTOR
__interrupt void universal_serial_interface(void)
{
USICTL1 &= ~USIIE; // Disable USI interrupts
RXDataUSI = USISRL; // store received data
USIcompleteRX = 1; // RX transmission result available
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -