忍者ブログ

Azukish

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

2024/05/07

[PR]

×

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

コメント

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

2016/08/28

MSP430G2でUARTを使ってみる。(2016/9/5追記)

こんばんは。久しぶりです。
最近、プログラミング熱がまたちょいと出てきたので、今度はUARTを使ってプログラムしてみることにしました。
日本語の記事がほとんど無くて、ほぼ手探り状態でやったので、もしかすると認識が間違ってる部分があるかもしれません。
こんな簡単な事をするのにも3時間ほどかかってます 笑
もっと基本的な事はMSP430G2 Launchpad買った+割り込みに関する備忘録(けっこう長文)|Azukishに載ってるので、全く分からない場合はその辺を読んでおくと良いかもしれません。




まず、コードを一番始めに載せちゃいます。
#include <msp430.h>
#include <msp430g2553.h>

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

	DCOCTL = 0; // Select lowest DCOx and MODx settings
	BCSCTL1 = CALBC1_1MHZ; // Set DCO
	DCOCTL = CALDCO_1MHZ;

	P1SEL |= BIT2;
	P1SEL2 |= BIT2;	// Enable TXD (P1.2)

	UCA0CTL1 |= UCSSEL_2;	// USCI clock source = SMCLK = 1MHz at default
	UCA0BR0 = 0x68;			// Frequency divider for UART
	UCA0BR1 = 0x00;			// 9600Hz is needed, but 1MHz/104=9615Hz is set
	UCA0MCTL = UCBRS0;		// UCBRSx=1

	UCA0CTL1 &= ~UCSWRST;	// Initialize UCSI state machine
	UCA0TXBUF = 'a';		// Send message
	UC0IE |= UCA0TXIE;		// USCI_A0 RX interrupt

	__bis_SR_register(CPUOFF + GIE);
}

// Send Interrupt
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void) {
	UC0IE &= ~UCA0TXIE;
}


こんな感じです。また例にならって一つ一つ備忘録的に付けていきましょう。


WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set DCO
DCOCTL = CALDCO_1MHZ;
まずmain関数の中のこの部分。

1行目はオマジナイです。なので省略。

2行目以降はDCOという内部のクロックを室温(25℃)で1MHzになるように設定しています。
考えれば当たり前な話ですが、USB等による通信ではこのクロックというのが非常に重要です。
基本的にデータというものはビットによって送信されます。
で、送信側と受信側のクロックを合わせておかないと、データにズレが生じてしまいます。
そのクロックのことを、どうやらボーレートと呼ぶらしいです(注→一番下)。
今回は9600Hz(PuttyでSerialを選択するとデフォルトになるやつ)で通信をしました。
1MHzから分周して9600Hzに近い値を取り出そうという算段です。
で、この設定なのですが、ユーザーガイドの24.2.1 DCO Calibration TLV Structureに載ってます。
この通りにすれば良いので、ある程度の精度の1MHz、8MHz、12MHz、16MHzは簡単に作れそうですね。

次に進みます。


P1SEL |= BIT2;
P1SEL2 |= BIT2;	// Enable TXD (P1.2)
今回はUARTを簡単な方法で実現しようとしています。 前はタイマと同期してピンの出力がON/OFFしてくれるようなプログラムでしたが、今回はP1.2がUARTの出力(Transmit=UCA0TXD)に使われるとのことです。
ちなみにP1.1は入力(Receive=UCA0RXD)に使われるようです。
この情報は↓のような形でMSP430G2553のデータシートに載ってます。


UCA0CTL1 |= UCSSEL_2;	// USCI clock source = SMCLK = 1MHz at default
UCA0BR0 = 0x68;			// Frequency divider for UART
UCA0BR1 = 0x00;			// 9600Hz is needed, but 1MHz/104=9615Hz is set
UCA0MCTL = UCBRS0;		// UCBRSx=1
ここでは1MHzのSMCLK(=デフォルトでDCOCLK)からボーレートの9600Hzを作っています。
しかし、UCA0BRxは単なる分周に過ぎないので、1MHzから9600Hzぴったりを作るのはなかなか難しそうです。
104で割ると一応は9615Hzとなり、温度による誤差程度に収まりそうな感じですが、よく使う値をいちいち計算するのは面倒です。
あと、数式は載ってるのですが、長ったらしくて読んでないのでUCBRSとかの値もどうやって決めりゃいいのか分からない・・・
ということでユーザーガイドの15.3.13 Typical Baud Rates and Errorsのデカい表にその辺はだいたい記載されています。
これを見て、UC0BR0=104=0x68、UCA0MCTL=1=UCBRS0を設定すればおおよそその値に近づけてくれるようです(送信の場合は欲しい周波数の99.5%~100.6%に収まるみたいですね)。


UCA0CTL1 &= ~UCSWRST;	// Initialize UCSI state machine
UCA0TXBUF = 'a';		// Send message
UC0IE |= UCA0TXIE;		// USCI_A0 RX interrupt
__bis_SR_register(CPUOFF + GIE);
では、main関数の最後に行きましょう。
UARTは使わないときには常にUCSWRSTが1になっていて、UARTを使うために必要な諸々がリセットされっぱなしになっているようです。
まず、それを0にして初期状態にします。
次に、送る文字を設定します。
サンプルなどを見る限り、UARTでは文字列を接続機器に送る場合、1文字1文字処理していくようです。
なので、ここでは文字"列"ではなく、文字を送ります。そのため、ダブルクォーテーション(")ではなく、シングルクォーテーション(')で書きました。
これが書けたらあとは割り込みのために、IE2のUCA0TXIEを1にしてLPMに入ればOKです。


#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void) {
	UC0IE &= ~UCA0TXIE;
}
最後に割り込み部になります。
割り込みが何たるか、どのように書くのか、は様々な人が色々な説明の仕方をしているので、そちらを参照してください。
送信時に起きる割り込みは1行目~2行目のように書けば大丈夫そうです。
この割り込みで何を行うかというと、二度と割り込みが起こらないようにしています。
main部のプログラム的に一度文字を送ったらそれでおしまいなのですが、面倒な事になっても嫌なので、ここでは割り込みのイネーブルをオフにしています。


これで、プログラムが終わりました。
で、ここからが迷ったところなのですが、このままではたぶんUARTがPCで確認できません。
というのも、MSP430G2 LaunchpadにはUARTが二種類あり、HWモードとSWモードというものがあるようです。
それはジャンパで設定するようです。
どういう違いがあるのかは確認できていないのですが、買ったばかりの状態ではジャンパがSWモードになっていて、このままでは動きません。
なので、ジャンパを90度回転させて再び突っ込みます。


(2016/9/5追記→PuTTY使わなくてもデフォルトでUARTを受け取る機能がありました。)
実行画面の再生の三角ボタンの左側にパソコンのボタンのようなものがあって、これがターミナル機能らしいです。
無い場合は[View]→[Other]→[Terminal]→[Terminal]で開けます。
で、これを開くと次のようにボーレートなどを選択する画面が出てくるので、COMの部分だけ下に書いてあるようにデバイスマネージャから取ってきて(大体はデフォルトのままで大丈夫だと思います)、OKをクリック。
そうするとTerminalが開くので、この状態で三角の実行ボタンをクリックすれば次のように指定した文字が表示されると思います。
(追記ここまで、以下古い情報だけど一応載せておく)
さらに、統合開発環境CCSv6にはUARTによる通信を受け取ったりする機能が無いようなので、PuTTYを利用します。
PuTTYはPuTTY Download Pageから最新版をダウンロードして使ってください。
ダウンロードしたexeファイルをそのまま実行すると↑のような画面が出てくると思うので、Connection typeをSerialに、Serial lineをCOMxにして、Speedは9600に設定してOpenをクリックしてください。
Serial lineに入力すべきものはデバイスマネージャのポート(COMとLPT)の中にあると思います。
Openを押して、CCSからプログラムをコンパイル・実行すると、↓のようにaと表示されると思います。
これで、UARTによってMSP430からPCにデータが送られて来たことが分かります。PCからMSP430に対してもデータを送ることができて、それはTXではなくRXの方を使えば似たようなプログラムでできると思います。
気が向いたらまた書いてみようと思います。
今回は以上です。何か質問等あったらコメント欄にお願いします。


参考にしたページ:
全般的に→MSP430 LaunchPad Tutorial - Part 4 - UART Transmission - Enrico Garante
ジャンパの設定とか→Problem communicating with UART on the MSP430G2553 - MSP Low-Power Microcontroller Forum - MSP Low-Power Microcontrollers - TI E2E Community


上の方の注:ボーレートと転送速度に関して
ボーレートという言葉自体、今回初めて聞きました 笑
詳しくはよく分からないけれど、ボーレートと転送速度とは似て非なるものらしいです。
というのも、ボーレートは単なる転送に用いられるクロック周波数みたいなもので、単位時間内でどれだけ変調できるか、みたいな話みたい。
そうすると、ボーレート≧転送速度みたいな関係になるのかな。で、その差が広がれば広がるほど通信の信頼性が上がったりするのかな?
ボーレート(baudrate)と転送速度(bps) | KEI SAKAKI's PAGE.

(2016/9/5追記)
P.S. 拍手ボタンなるものを追加してみた。場所的に非常にアレなので、配置とか見た目とかを後で改善します。もしもページが気に入ったら気まぐれ的にボタン押してね。

拍手

コメント













カレンダー

04 2024/05 06
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 31

アーカイブ

AD

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