让你的Launchpad/RF2500控制音乐播放
[复制链接]
接上篇https://bbs.eeworld.com.cn/thread-294145-1-1.html
TI 给出了Capacitive Touch BoosterPack(触摸板)附带的上位机软件软件。
MediaPad.rar
(254.02 KB, 下载次数: 131)
而该软件即具有控制音乐播放之功能,用户接口就是串口,相应指令即可实现相应的控制功能。
打开播放器 80 80 播放暂停 38 38 38 38 下一曲 34 34 34 34
上一曲 3C 3C 3C 3C
以上是本人暂时得出控制指令,向串口发送相应指令(比如发送4次0x34即可下一曲)
另外可以实现音量加减,但暂时没搞定对应指令。
具体到Launchpad,我们可以利用它的定时器模拟串口,
代码如下:
#include "msp430g2452.h"
//------------------------------------------------------------------------------ // Hardware-related definitions //------------------------------------------------------------------------------ #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0) #define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A)
//------------------------------------------------------------------------------ // Conditions for 9600 Baud SW UART, SMCLK = 1MHz //------------------------------------------------------------------------------ #define UART_TBIT_DIV_2 (1000000 / (9600 * 2)) #define UART_TBIT (1000000 / 9600)
//------------------------------------------------------------------------------ // Global variables used for full-duplex UART communication //------------------------------------------------------------------------------ unsigned int txData; // UART internal variable for TX unsigned char rxBuffer; // Received UART character unsigned int i;
//------------------------------------------------------------------------------ // Function prototypes //------------------------------------------------------------------------------ void TimerA_UART_init(void); void TimerA_UART_tx(unsigned char byte); void TimerA_UART_print(char *string);
void Delay(unsigned int i) { while (i != 0) { i--; } } //------------------------------------------------------------------------------ // main() //------------------------------------------------------------------------------ void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
DCOCTL = 0x00; // Set DCOCLK to 1MHz BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ;
P1OUT = 0x00; // Initialize all GPIO P1SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins P1DIR = 0x43; // Set all pins but RXD to output __enable_interrupt();
while (1) // 按键消抖
{ if ((0x08 & P1IN) == 0x00) { for(int i=0;i<4000;i++); if ((0x08 & P1IN) == 0x08) { P1OUT |= BIT6; TimerA_UART_init(); // Start Timer_A UART TimerA_UART_tx(0x34); //发送4次0x34实现下一曲
TimerA_UART_tx(0x34); TimerA_UART_tx(0x34); TimerA_UART_tx(0x34); } } } } //------------------------------------------------------------------------------ // Function configures Timer_A for full-duplex UART operation //------------------------------------------------------------------------------ void TimerA_UART_init(void) { TACCTL0 = OUT; // Set TXD Idle as Mark = '1' TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode } //------------------------------------------------------------------------------ // Outputs one byte using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_tx(unsigned char byte) { while (TACCTL0 & CCIE); // Ensure last char got TX'd TACCR0 = TAR; // Current state of TA counter TACCR0 += UART_TBIT; // One bit time till first bit TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int txData = byte; // Load global variable txData |= 0x100; // Add mark stop bit to TXData txData <<= 1; // Add space start bit }
//------------------------------------------------------------------------------ // Prints a string over using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_print(char *string) { while (*string) { TimerA_UART_tx(*string++); } } //------------------------------------------------------------------------------ // Timer_A UART - Transmit Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A0_ISR(void) { static unsigned char txBitCnt = 10;
TACCR0 += UART_TBIT; // Add Offset to CCRx if (txBitCnt == 0) { // All bits TXed? TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt txBitCnt = 10; // Re-load bit counter } else { if (txData & 0x01) { TACCTL0 &= ~OUTMOD2; // TX Mark '1' } else { TACCTL0 |= OUTMOD2; // TX Space '0' } txData >>= 1; txBitCnt--; } } //------------------------------------------------------------------------------ // Timer_A UART - Receive Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMER0_A1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0;
switch (__even_in_range(TA0IV, TA0IV_TAIFG)) { // Use calculated branching case TA0IV_TACCR1: // TACCR1 CCIFG - UART RX TACCR1 += UART_TBIT; // Add Offset to CCRx if (TACCTL1 & CAP) { // Capture mode = start bit edge TACCTL1 &= ~CAP; // Switch capture to compare mode TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0 } else { rxData >>= 1; if (TACCTL1 & SCCI) { // Get bit waiting in receive latch rxData |= 0x80; } rxBitCnt--; if (rxBitCnt == 0) { // All bits RXed? rxBuffer = rxData; // Store in global variable rxBitCnt = 8; // Re-load bit counter TACCTL1 |= CAP; // Switch compare to capture mode __bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR) } } break; } }
具体到单机版(其中一个)的RF2500,代码如下:
#include "msp430x22x4.h" void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ; P1DIR |= BIT0; P1OUT &=~BIT0; P1DIR &= ~BIT2; //P1.2口通过开关直接接地,设置为输入 P1REN |= BIT2; //P1.2口开启上拉或者下拉电阻功能 P1OUT |= BIT2; //选择上拉
P1IE |= BIT2; P1IES &= ~BIT2; //上拉电阻,开关直接接地,应选择上升沿触发 P3SEL = 0x30; // P3.4,5 = USCI_A0 TXD/RXD UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 104; // 1MHz 9600 UCA0BR1 = 0; // 1MHz 9600 UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled while(1); }
// Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { P1OUT ^= BIT0; UCA0TXBUF = 0x34; while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = 0x34; while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = 0x34; while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = 0x34; while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? P1IFG &= ~BIT2; // P1.2 IFG cleared }
//发送4次0x34实现下一曲
|