今回もMSPマイコンについて備忘録2を記します。
<プログラム内容>
可変抵抗を動かしてアナログ指令値を変えることで、PWM変調にてLEDの明るさを更新させます。また、分周したクロックも別のLEDに出力することで可視化します。
ピン配置と役割は以下の通り。
P4.1 -> Red LED........; PWM変調調光
P4.2 -> Blue LED.......; 1Hz クロックで点滅
P4.3 -> Green LED.....; 2kHz クロックで点滅
P6.0 -> 可変抵抗入力..; AD変換入力
メインクロックとは別でクロックが2つもあるのは、メインクロックから別のクロックを作ってみるテストです。
まずはフローチャート
![]() |
Timer-Bのコンペアマッチに反応してG_LEDを反転させCLK1が生成される。CLK1に従ってインクリメントするTB_CM変数がTpwm2にコンペアマッチすると、B_LEDが反転し、CLK2が生成される。 |
次に、回路図。
3つのLEDはタイマーBの出力に割り当てられているポート4にそれぞれ接続。可変抵抗の中間電位をA0に入力してアナログ指令値を得る |
また、実験風景。
![]() |
各LEDの役割は示した通り。下記の動画では、左上の可変抵抗をグリグリ回して赤LEDの明るさを変化させる |
可変抵抗を回すことで赤LEDの明るさが変化しています。青LEDは約1Hzで、緑LEDは視認できませんが2kHzで点滅しているのが確認できます。
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <msp430.h> //MSP430F2619TPM | |
/** | |
* main.c | |
*/ | |
// 端子設定 ///////////////////////////////////////////////////////// | |
// LED | |
#define test_LED 0b00000001 // P1.0 test_LED | |
#define RED_LED 0b00000010 // P4.1 RED_LED [TB1] | |
#define BLUE_LED 0b00000100 // P4.2 BLUE_LED [TB2] | |
#define GREEN_LED 0b00001000 // P4.3 GREEN_LED[TB3] | |
// ADC | |
#define ADC0 0b00000001 // P6.0 可変抵抗 入力 | |
// Timer B | |
#define Tpwm 8000000/4000 // TimerBの分周用カウンタ | |
#define Tpwm2 4000/2 // TimerBのさらなる分周用カウンタ | |
/////////////////////////////////////////////////////////////////// | |
/* グローバル変数 *///////////////////////////////////////////////////// | |
int INTERRUPT_FLAG = 0; // 割り込み種類フラグ | |
unsigned int TB_CM = 0; // TimerBがコンペアマッチするごとにインクリメント | |
//////////////////////////////////////////////////////////////////// | |
/* 関数定義 *///////////////////////////////////////////////////////// | |
void setup( void ); | |
//////////////////////////////////////////////////////////////////// | |
/* 初期設定 *//////////////////////////////////////////////////////// | |
void setup() { | |
WDTCTL = WDTPW + WDTHOLD; // Stop WathcDog Timer, | |
SVSCTL &= ~SVSFG; // 低電圧フラグを消去 Supply Voltage Supervisor | |
SVSCTL = 0x60 + PORON; // SVS POR enabled @ 2.5V 電圧低下検出.この電圧以下ではマイコンリセット. | |
while(!(SVSCTL & SVSON)); // 電圧監視機能がONになるまで待機 | |
BCSCTL1 = CALBC1_8MHZ; // Set RSELx | |
DCOCTL = CALDCO_8MHZ; // Set DCOx and MODx = MCLK :8MHZ | |
P1DIR = test_LED; // P1.0:OUT | |
P4DIR = RED_LED | BLUE_LED | GREEN_LED; // P4.1,4.2,4.3:OUT, the others;IN | |
P4SEL = RED_LED; // | BLUE_LED | GREEN_LED; | |
P6SEL = ADC0; // P6.0; Primary peripheral module function = A0 | |
// Setup ADC // // The ADC12OSC is generated internally and is in the 5-MHz range | |
ADC12CTL0 = SHT0_2 + SHT1_2 + REFON + ADC12ON; // ADC12OSC(~5MHZ), 16 cycle, Set sampling time:xxus, turn on ADC12 | |
ADC12CTL1 = SHP + ADC12SSEL_0; // Use sampling timer, Single-channel, single-conversion | |
//// 各チャンネルの設定 //// | |
ADC12MCTL0 = SREF_0 + INCH_0; // VRef = AVcc, channel = A0 | |
// SHT0x:Bits 11-8 Sample-and-hold time. for registers ADC12MEM0 to ADC12MEM7. | |
// 0000:4 ADC12CLK cycles 0001:8 ADC12CLK cycles | |
// 0010:16 ADC12CLK cycles 0011:32 ADC12CLK cycles | |
// 0100:64 ADC12CLK cycles 0101:96 ADC12CLK cycles | |
// 0110:128 ADC12CLK cycles 0111:192 ADC12CLK cycles | |
// 1000:256 ADC12CLK cycles 1001:384 ADC12CLK cycles | |
// 1010:512 ADC12CLK cycles 1011:768 ADC12CLK cycles | |
// 1100:1024 ADC12CLK cycles 1101:1024 ADC12CLK cycles | |
// 1110:1024 ADC12CLK cycles 1111:1024 ADC12CLK cycles | |
// setup Timer_B // | |
TBCTL = TBSSEL_2 + ID_0 + MC_1 + TBIE; // Timer_B Control resister (13.3.1 TBCTL, Timer_A Control Register P.391) | |
// 00 TBCLK :外部入力のタイマー用クロック(P1.0 TBCLK) | |
// 01 ACLK :補助クロック(外部32768HZ発振子) /(div) | |
// 10 SMCLK :サブシステムクロック(DCOから) /(div) | |
// 11 INCLK :外部入力クロック(P2.1 TAINCLK) | |
TBCCR0 = Tpwm; // TBCCRx:Bits 15-0 TBCCRx:Timer_B Capture/Compare Resister (13.3.3 TBCCRx, Timer_B Capture/Compare Register x, P.390) | |
TBCCR1 = Tpwm*0.3; // | |
TBCCTL0 = CCIE; // 13.3.4 TBCCTLx, Capture/Compare Control Register, P. | |
TBCCTL1 = OUTMOD_7; // | |
__bis_SR_register(GIE); // 汎用割り込み許可 | |
ADC12CTL0 |= ENC; // ADC go working | |
} | |
//////////////////////////////////////////////////////////////////// | |
//////////////////////////////////////////////////////////////////// | |
/*!!! ************************************************ | |
* タイマー割り込みの処理 | |
******************************************************/ | |
#pragma vector = TIMERB0_VECTOR // Datasheet, Interrupt Vector Addresses P.16 | |
__interrupt void TIMER_B0(void) // Timer interrupt 発生時に割り込む関数の定義 | |
{ | |
TBCTL &= ~TBIFG; // タイマーの割り込みフラグのクリア | |
INTERRUPT_FLAG = 1; | |
TB_CM++; | |
} | |
//////////////////////////////////////////////////////////////////// | |
//////////////////////////////////////////////////////////////////// | |
int main(void) | |
{ | |
setup(); // システム初期設定.これ以前には何も処理をしないこと | |
int AD0 = 0; | |
int Tpwm1 = Tpwm2; | |
P1OUT = test_LED; | |
P4OUT = 0x00; | |
ADC12CTL0 |= ADC12SC; // ADC12 enable, start conversion | |
while(1){ | |
if(INTERRUPT_FLAG == 1){ | |
AD0 = ADC12MEM0; | |
ADC12CTL0 |= ADC12SC; // ADC12 enable, start conversion | |
TBCCR1 = Tpwm*(AD0*0.7 + 4095*0.05)/4095; | |
if(TB_CM > Tpwm1){ | |
TB_CM = 0; | |
P4OUT ^= BLUE_LED; | |
} | |
} | |
P4OUT ^= GREEN_LED; | |
} | |
} |
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
前回の備忘録1でも触れた内容については触れず、新しく出てきたところだけ触れていきます。
<51行>
50. // Setup ADC // The ADC12OSC is generated internally and is in the 5-MHz range
51. ADC12CTL0 = SHT0_2 + SHT1_2 + REFON + ADC12ON;
AD変換器に関する初期設定1
( U. G. P.575 23.3.1 ADC12CTL0, ADC12 Control Register 0 )
・SHT0x,1x : ADC12の0チャネル-7チャネル, 8チャネル-15チャネルに関する
前回の備忘録1でも触れた内容については触れず、新しく出てきたところだけ触れていきます。
<51行>
50. // Setup ADC // The ADC12OSC is generated internally and is in the 5-MHz range
51. ADC12CTL0 = SHT0_2 + SHT1_2 + REFON + ADC12ON;
AD変換器に関する初期設定1
( U. G. P.575 23.3.1 ADC12CTL0, ADC12 Control Register 0 )
・SHT0x,1x : ADC12の0チャネル-7チャネル, 8チャネル-15チャネルに関する
Sample Hold Timeを指定する。ADC用クロックを何周期使ってアナログ入力値を
安定させるかを決めます。
// 0000:4 ADC12CLK cycles 0001:8 ADC12CLK cycles
// 0010:16 ADC12CLK cycles 0011:32 ADC12CLK cycles
// 0100:64 ADC12CLK cycles 0101:96 ADC12CLK cycles
// 0110:128 ADC12CLK cycles 0111:192 ADC12CLK cycles
// 1000:256 ADC12CLK cycles 1001:384 ADC12CLK cycles
// 1010:512 ADC12CLK cycles 1011:768 ADC12CLK cycles
// 1100:1024 ADC12CLK cycles 1101:1024 ADC12CLK cycles
// 1110:1024 ADC12CLK cycles 1111:1024 ADC12CLK cycles
・MSC : マルチサンプリング変換フラグ。AD変換は16チャネル用意されているが、あるタイミングで
全てのチャネルの変換を開始する場合に立てる。
・REFON : 変換に使用する基準電圧をマイコン内部で生成するか決定する。使わないならエコのためOFF
・REF2_5V : 内蔵基準電圧の値を決める
// 0 : 1.5V
// 1 : 2.5V
・ADC12ON : 1を立てるとADC12が起動する
・ENC : Enable Convertion 1を立てるとAD変換が使用可能になる
・ADC12SC : 初期設定完了後に、1を立てたときからAD変換が開始される
52. ADC12CTL1 = SHP + ADC12SSEL_0;
( U. G. P.577 23.3.2 ADC12CTL1, ADC12 Control Register 1 )
AD変換器に関する初期設定2
・SHSx : Sample and Hold を開始するソースを選択する, Timerを選択するとCMがフラグとなる
// 00 : ADC12SC bit 01 : Timer_A.OUT1// 10 : Timer_B.OUT0 11 : Timer_B.OUT1
・SHP : Sample and Hold のモード選択
// 0 : SAMPCON signal is sourced from the sample-input signal.
// 1 : SAMPCON signal is sourced from the sampling timer.
・ADC12SSELx : AD変換のクロックソースを選択
// 00 : ADC12OSC 01 : ACLK// 10 : MCLK 11 : SMCLK
54. ADC12MCTL0 = SREF_0 + INCH_0; // VRef = AVcc, channel = A0
( U. G. P.578 23.3.4 ADC12MCTL0, ADC12 Conversion Memory Control resisters )
AD変換器に関する初期設定3
AD変換器に関する初期設定3
・EOS : End of sequency 1を立てると、複数チャネルを同時に変換するモードにて最後のチャネルであることを示す
・SREFx : AD変換に使用する基準電圧を+側・-側ともに選択
// 000 VR+ = AVCC and VR- = AVSS
// 001 VR+ = VREF+ and VR- = AVSS
// 010 VR+ = VeREF+ and VR- = AVSS
// 011 VR+ = VeREF+ and VR- = AVSS
// 100 VR+ = AVCC and VR- = VREF-/ VeREF-
// 101 VR+ = VREF+ and VR- = VREF-/ VeREF-
// 110 VR+ = VeREF+ and VR- = VREF-/ VeREF-
// 111 VR+ = VeREF+ and VR- = VREF-/ VeREF
・INCHx : AD変換するチャネルを選択 ( 1010のTDは内部温度を測れる内蔵温度センサ )
// 0000 A0, 0001 A1, 0010 A2, 0011 A3, 0100 A4,// 001 VR+ = VREF+ and VR- = AVSS
// 010 VR+ = VeREF+ and VR- = AVSS
// 011 VR+ = VeREF+ and VR- = AVSS
// 100 VR+ = AVCC and VR- = VREF-/ VeREF-
// 101 VR+ = VREF+ and VR- = VREF-/ VeREF-
// 110 VR+ = VeREF+ and VR- = VREF-/ VeREF-
// 111 VR+ = VeREF+ and VR- = VREF-/ VeREF
・INCHx : AD変換するチャネルを選択 ( 1010のTDは内部温度を測れる内蔵温度センサ )
// 0101 A5, 0110 A6, 0111 A7, 1000 VeREF+, 1001 VREF- /VeREF-
// 1010 Temperature diode, 1011 (AVCC - AVSS) / 2
// 1100 GND, 1101 GND, 1110 GND, 1111 GND
<68行>
67. // setup Timer_B //
68. TBCTL = TBSSEL_2 + ID_0 + MC_1 + TBIE;
タイマーBに関する初期設定1
( U. G. P.391 13.3.1 Timer_B Control Register TBCTL )
・TBSSEL : タイマーBのクロックソースを選択
// 00 TBCLK :外部入力のタイマー用クロック(P1.0 TBCLK)
// 01 ACLK :補助クロック(外部32768HZ発振子) /(div)
// 10 SMCLK :サブシステムクロック(DCOから) /(div)
// 11 INCLK :外部入力クロック(P2.1 TAINCLK)
<74-75行>
74. TBCCR0 = Tpwm;
75. TBCCR1 = Tpwm*0.3;
・TBCCRx : 各チャネルごとにコンペアマッチする値を指定する(タイマーの周期やデューティを指定)
<76-77行>
76. TBCCTL0 = CCIE;
77. TBCCTL1 = OUTMOD_7; //
・TBCCTLx : 各チャネルごとにタイマーの設定をする
<89-100行>
93. #pragma vector = TIMERB0_VECTOR // Datasheet; Interrupt Vector Addresses P.16
94. __interrupt void TIMER_B0(void) // Timer interrupt 発生時に割り込む関数の定義
95. {
99. } ・タイマーBによる割り込み動作を記述する
<117行>
117. ADC12CTL0 |= ADC12SC; // ADC12 enable, start conversion
・SCフラグを立ててADC12の変換開始する。変換が終了すると自動的にSC=0となるから、
もう一度変換をかけたいときはもう一度SC=1とすればいい。
<122行>
122. if(INTERRUPT_FLAG == 1){ }
・タイマーBの割り込み時にINTERRUPT_FLAGが立つので、そのつど if ルートに入る
<123行>
123. AD0 = ADC12MEM0;
・A0の変換結果はADC12MEM0に格納されるので、int型変数AD0に読みだす。
以上。
-------------------------------------------------------
これで、ボタンスイッチ入力・PWM出力・AD変換・割り込み[タイマー、AD変換]までできるようになりました。
次回はポートからの割り込みとLCDへの出力あたりを書けたらなと思います。
0 件のコメント:
コメントを投稿