MSP-EXP432P401Rの説明書の回路図を見ると、
ピンP1.2と、P1.3はXDS110-ETとつながっていて、UARTのRXD,TXDになっている。これらのピンとPCとの通信することができる。DriverLibのExampleをインポートして動作を確認してみる。
インポートしたらさすがにエラーはないので、ビルトして書き込みを行う。
PCと接続されているCOMポートの番号をデバイスマネジャーで確認する。上の場合は8番側。シリアルの通信ターミナルを開いてキーボードに何か書いて送付するとエコーバックしてくる。
ArduinoIDEをインストールしているならCOMを8番に設定して、シリアルモニタを代用するでもOK
送信した文字がそのままバックして画面に出てくるってしろもの。
でこれで、ボーレートとか必要ところだけ編集すればまあ動かせる。
const eUSCI_UART_ConfigV1 uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
78, // BRDIV = 78
2, // UCxBRF = 2
0, // UCxBRS = 0
EUSCI_A_UART_NO_PARITY, // No Parity
EUSCI_A_UART_LSB_FIRST, // LSB First
EUSCI_A_UART_ONE_STOP_BIT, // One stop bit
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
EUSCI_A_UART_8_BIT_LEN // 8 bit data length
};
EUSCI_A_UART_CLOCKSOURCE_SMCLK:クロックの指定。SMCLK(サブシステム、マスタークロック)速いHSMCLKってのもあるが、SMCLKを指定している。
SMCLKは、DCO(digitally controlled oscillator)をデフォルトでは元にしている。このDCOは、後の方で、12MHzに変更している。(デフォルトでは3MHz)。BRDIVの設定は、
http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
で計算しろと書いてあるので、必要事項をいれると、パラメーターを計算してくれて、その通りに設定する。UCxBRF とUCxBRS の部分は、それぞれfirstModRegとsecondModRegに対応して、EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATIONはoverSamplingが1の時に。定義が
#define EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION 0x01
となっているので、0x01を書いても同じ。overSamplngが0なら0x00を記載するか、対に定義されているEUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION。
EUSCI_A_UART_NO_PARITY, EUSCI_A_UART_LSB_FIRST, EUSCI_A_UART_ONE_STOP_BITの部分は通信する相手にあわせて変更する。
【ピンアサイン】
/* Selecting P1.2 and P1.3 in UART mode */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
説明は割愛
/* Setting DCO to 12MHz */
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
CSは、Clock systemのこと。
CS_DCO_FREQUENCY_1_5,
CS_DCO_FREQUENCY_3,
CS_DCO_FREQUENCY_6,
CS_DCO_FREQUENCY_12,
CS_DCO_FREQUENCY_24,
CS_DCO_FREQUENCY_48
から選べる。
/* Configuring UART Module */
MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);
上で定義したuartConfigの内容を反映させて初期化する。
/* Enabling interrupts */
MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
MAP_Interrupt_enableInterrupt(INT_EUSCIA0);
MAP_Interrupt_enableSleepOnIsrExit();
MAP_Interrupt_enableMaster();
MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
何か受信したらインターラプトするように設定して、ISRのルーチンに飛ぶようにするコマンド。
MAP_Interrupt_enableInterrupt(INT_EUSCIA0);
ここから3行はUART自体のインターラプトを許容するようにしている。
MAP_Interrupt_enableSleepOnIsrExit();
はインターラプトに入ったら消費電力削減のためにCPUを眠らせるコマンド。
/* EUSCI A0 UART ISR - Echoes data back to PC host */
void EUSCIA0_IRQHandler(void)
{
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE);
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
{
MAP_UART_transmitData(EUSCI_A0_BASE, MAP_UART_receiveData(EUSCI_A0_BASE));
}
}
MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE)でインターラプトの状態を確認する状態をstatusに代入して、
status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG
何か受信したら、MAP_UART_transmitDataでデータを送信している。
送信内容が、受信したそのものを送るので、MAP_UART_receiveData(EUSCI_A0_BASE)となっている。
UART_receiveData(EUSCI_A0_BASE)で受け取るのは1バイトのみで、1バイトづつエコーして送信している動作になる。
上の例だと、”test"とPCから送っても、t,e,s,tと4回繰り返しているだけで、文字列としては処理できない。
マルチビット(multi bytes)をUARTでPCから受信する例は以下のようになる
mainより上で変数を定義しておく。一つ前の状態を残しておけるように二つ配列を用意しておく。
/* UART_RX variable */
static char UART_RX_buffer[64];
static char UART_RX_buffer_temp[64];
uint8_t UART_RX_buffer_index=0;
IRQハンドラーを以下のようにする。
void EUSCIA0_IRQHandler(void)
{
char c;
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE);
MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status);
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
{
c=MAP_UART_receiveData(EUSCI_A0_BASE);
MAP_UART_transmitData(EUSCI_A0_BASE, c);
UART_RX_buffer_temp[UART_RX_buffer_index]=c;
memcpy(UART_RX_buffer, UART_RX_buffer_temp, sizeof(UART_RX_buffer_temp));
UART_RX_buffer_index++;
if (c==0x0a){
memset(UART_RX_buffer_temp, 0x00, sizeof(UART_RX_buffer_temp));
UART_RX_buffer_index=0;
}
}
MAP_Interrupt_disableSleepOnIsrExit();
}
UART_RX_bufferとUART_RX_buffer_tempでコピーを取得しているのは、改行したら初期化するという処理をするため。
改行コードを読み取ったら、インデックスをゼロに戻して、配列を初期化したいが
コピーを取らないとせっかく取得した文字列が消えるから、改行を受けっとっても前の状態を保持しておくため。
最後の行の、 MAP_Interrupt_disableSleepOnIsrExit();でインターラプトから元のmainのルーチンに戻ることになり、結果が、UART_RX_bufferに格納される。
コメント
コメントを投稿