让你的Launchpad/RF2500控制音乐播放

cc1989summer   2011-7-8 16:36 楼主

接上篇https://bbs.eeworld.com.cn/thread-294145-1-1.html

 

TI 给出了Capacitive Touch BoosterPack(触摸板)附带的上位机软件软件。

MediaPad.rar (254.02 KB)
(下载次数: 131, 2011-7-8 16:36 上传)

而该软件即具有控制音乐播放之功能,用户接口就是串口,相应指令即可实现相应的控制功能。

 

打开播放器          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实现下一曲

回复评论 (10)

不错哦,这个只是控制吗?音乐是通过什么放呢?
点赞  2011-7-9 01:37

回复 沙发 wstt 的帖子

任意播放器,比如 千千静听 或者 windows media player等
点赞  2011-7-10 14:31
你得那些控制指令是怎么获得的呢?
点赞  2011-7-10 23:05
LZ这个相当于和PC联系在一起了,很好,很有意思
写详细点给你加精吧!
再送芯币作奖励!
点赞  2011-7-10 23:06
有个叫girder的软件,可以接收串口,做很多事,比如控制播放器,控制ie,等等。可以自己设定。
点赞  2011-10-16 17:51
很酷的~~~玩玩 学习下
点赞  2011-10-16 19:53
蛮有意思的,顶一下啊!
点赞  2011-10-17 00:55
串口收进来再变成virtual key发给系统 以前发过过用红外遥控解码控制pc的~
我们是不为一切驻留的亡魂
点赞  2011-10-17 10:46
群主还知道其他指令不
点赞  2011-11-20 21:30
这个也想玩玩呢 嘿嘿
点赞  2011-11-20 22:31
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复