忍者ブログ

Azukish

消えゆく世界と流れる未来に最後の灯を since 2006/4/3

2024/04/30

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

コメント

ただいまコメントを受けつけておりません。

2019/07/22

MSP-EXP430FR2433でSPIで双方がマスターになる通信をする

何を言ってるかもはや分からないと思うが、俺も正直何を言っているかよくわからなくなってきたぜ・・・
とりまMSP-EXP430FR2433が安く売ってたので2台買ったは良いものの、使いみちが不明すぎるw
そんなこんなで、どっかで記事を読んだことがあるんだけど、SPIでマルチマスターな環境を作ってみた。

やり方はそんなに難しくなくて、
1. SPIで通信をする前にGPIOで相手を叩く。
2. GPIOで叩かれた奴はスレーブ設定になる。
3. GPIOで相手を叩いた奴はマスター設定になる。
4. マスターは相手にデータを送る。

こんな感じ。
3-4の間の時間は適度に空けてやる必要がある
ホントはGPIOリードバックみたいな機能があれば良かったんだけどね。
てなわけで、つづきにソースを載せて置くのであとは適当に。




#include <msp430.h>

int main(void) {
  WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer

  // GPIO setup
  P1DIR |= BIT0;
  P1OUT &= ~BIT0;
  P2DIR |= BIT0; // P2.0 output, P2.1 input (interruption)
  P2OUT &= ~(BIT0 | BIT1);
  P2IES &= ~BIT1; // Low to High
  P2IE |= BIT1;
  P2IFG &= BIT1;
  PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high

  // Clock setup
  CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source
  CSCTL0 = 0;                // clear DCO and MOD registers
  CSCTL1 &= ~(DCORSEL_7);    // Clear DCO frequency select bits first
  CSCTL1 |= DCORSEL_3;       // Set DCO = 8MHz
  CSCTL2 = FLLD_0 + 243;     // DCODIV = 8MHz
  __delay_cycles(3);
  __bic_SR_register(SCG0);   // enable FLL
  while (CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
  CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz

  // Configure UART
  P1SEL0 |= BIT4 | BIT5;       // set 2-UART pin as second function
  UCA0CTLW0 |= UCSWRST;
  UCA0CTLW0 |= UCSSEL__SMCLK;
  UCA0BR0 = 52;                // 52=8,000,000/16/9600 (9600 baud/s)
  UCA0BR1 = 0x00;
  UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1;
  UCA0CTLW0 &= ~UCSWRST;       // Initialize eUSCI
  UCA0IE |= UCRXIE;

  // Configure SPI
  P1SEL0 |= BIT1 | BIT2 | BIT3;
  UCB0CTLW0 |= UCSWRST;                         // **Put state machine in reset**
  UCB0CTLW0 |= UCMST | UCSYNC | UCCKPL | UCMSB; // 3-pin, 8-bit SPI master, Clock polarity high, MSB
  UCB0CTLW0 |= UCSSEL__SMCLK;                   // SMCLK
  UCB0BR0 = 0x01;                               // /2,fBitClock = fBRCLK/(UCBRx+1).
  UCB0BR1 = 0;
  UCB0CTLW0 &= ~UCSWRST;                        // **Initialize USCI state machine**

  // Sleep until interruption
  __bis_SR_register(LPM3_bits | GIE); // Enter LPM3, interrupts enabled
}

// UART Received -> Be SPI Master -> Send SPI to Slave
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void) {
  P2OUT |= BIT0;
  P1OUT |= BIT0;

  __delay_cycles(100);   // Possibly optimized regarding board setup

  UCB0CTLW0 |= UCSWRST;  // **Put state machine in reset**
  UCB0CTLW0 |= UCMST;    // Master
  UCB0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
  UCB0IE &= UCRXIE;

  while (!(UCB0IFG & UCTXIFG));
  UCB0TXBUF = UCA0RXBUF;
}

// SPI Received -> Send UART to PC
#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void) {
  while (!(UCA0IFG & UCTXIFG));
  UCA0TXBUF = UCB0RXBUF;
  P1OUT &= ~BIT0;
}

// Receive P2.1 L to H -> Be SPI Slave -> Wait SPI
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void) {
  P2OUT &= ~BIT0;
  UCB0CTLW0 |= UCSWRST;  // **Put state machine in reset**
  UCB0CTLW0 &= ~UCMST;   // Slave
  UCB0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
  UCB0IE |= UCRXIE;
  P2IFG &= ~BIT1;
}


接続としては、MSP430FR2433同士の場合は下記。
GND, P1.1, P1.2, P1.3: 相手と同じピンにつなぐ
J11 (P1.1のLEDを光らせるやつ): 外す
J10 (P1.0のLEDを光らせるやつ): 付ける (マスター側が光る)
P2.1: 相手のP2.0と接続
P2.0: 相手のP2.1と接続

解説としては上で書いた通りだけれど、PCからコマンドやターミナルからUART経由でシリアル通信(baud rateは9600baud/s)がなされたら、下記のような処理を行う。
1. SPIで通信をする前にGPIOで相手を叩く。
が53-54行目
2. GPIOで叩かれた奴はスレーブ設定になる。
が75行目以降
3. GPIOで相手を叩いた奴はマスター設定になる。
が58-61行目
4. マスターは相手にデータを送る。
が64行目
最後にSPIのスレーブ側がUART経由でPCに受け取ったデータを送っている(67-73行目)けど、ここは適当に変更しても良い。
GPIO(P2.1)を変更してから相手が受信するまでの間、100サイクル分待ってるけど、これはデバイスによって最適化しても良い。

正直何に使えるかわからないけど、実験的にやってみた。ただそれだけ。
なお、上でも書いたとおり公式で時々$4.30で売ってる(いつまでか知らんけど、MSP-EXP430FR2433をカートに入れた状態でmsp430discountをクーポン欄に入力すればおk)ので、ちょこちょこチェックしてみると安く購入できるかもです。

拍手

コメント













カレンダー

03 2024/04 05
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

アーカイブ

AD

Azkishはamazon.co.jpを宣伝しリンクすることによって サイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。