USBでPCと接続する発振器&周波数カウンタ

パルス発振器があると便利なので、製作しましょう.

どんなことをできるようにするか?
パルス発振器機能
周波数
10Hz〜200kHz
デューティ
1%〜99%
出力ピン
TIM2_CH1   PD4   (45pin) (CN4-9)   +出力
TIM2_CH2   PD3  
(44pin) (CN4-8)   −出力
周波数カウンタ機能
周波数表示
約1秒毎に表示
デューティ表示
約1秒毎に表示
入力ピン
TIM1_CH1   PC1   (26pin) (CN2-2)
表示
PCのTerminal soft画面

COM PORT パラメータ
115200bps  8bit  odd-parity
周波数表示インジケータ
LED
コマンド
周波数設定コマンド
f 1000↓       周波数1000Hz
duty設定コマンド
d 33↓       duty比33%
verboseモードコマンド
v↓           verbose/非verboseをトグル

STM8S内部回路構成
TIM1
周波数カウンタ回路
割り込みあり
TIM2
パルス発振器回路

TIM3
PCのTerminal画面へ表示するインターバル
割り込みあり
UART
PCとの通信用
割り込みあり
clock
外部16MHz水晶を使用(HSE)


総合ブロック図
TIM2によるパルス出力を、そのままTIM1の周波数測定入力に接続しています.
つまり、STM8SのTIM2で生成したパルスを、STM8SのTIM1で測定し直すという回路になっています.

UARTでPCと通信するとはどういうことか?
STM8S-DISCOVERYのUARTは、PCのCOM PORTに接続し通信するための回路です.
しかし、今のPCにはCOM PORTは付いてないので、FT232というICでUSBに変換します.
そして、USBケーブルでPCに接続します.
PCではTerminalソフトをつかって通信します.
したがって、PCを操作する人間から見えるのは、terminal ソフトという通信アプリの画面です.


割り込み構成
TIM1 input capture割り込み
12番
外部ピンに入力されるパルス信号の周期をカウントする.
パルス信号の1周期ごとに割り込みをかける.
TIM1を利用するので、16bitカウンタで、クロックは16MHzである.
測定値は、1周期の長さと、HIGH区間の長さである.
割り込みがかかるごとに、測定結果をTIM1_ICvalueという名の変数に格納する.
__________|~~~~~~~|_______________|~~~~~~~|__________
          <----------------------->  TIM1_ICvalue1
          <------->   TIM1_ICvalue2
TIM3 update割り込み
15番
PC上のterminal画面へ表示するインターバルを発生させる約1秒のタイマ.
ここでは、16MHz÷1024÷10000=1.54Hz の割り込みを発生させる.
UART受信割り込み
21番
UARTが文字を受信したら割り込みをかける.

画面表示例
非verboseモード

verboseモード



ハードウエアの準備

@USBシリアル変換回路
まず、UARTをUSBに変換する回路を、STM8S-DISCOVERYにどうやって取り付けるかを説明します.
秋月のUSBシリアル変換基板をSTM8S-DISCOVERYに取り付けます.
回路図は下記です.配線は下記回路図の4本です.
●STM8SのPD5とPD6には、UARTの送信信号と受信信号が出てきますので、それをUSBシリア ル基板に配線しています.
STM8S-DISCOVERYでは、電源はFLASH焼き回路から5V or 3.3Vが供給されますが、これを切断し、USBシリアル変換基板から3.3Vが供給されるようにします.
ただし5Vじゃダメってことではありません.3.3Vにしたのはなんとなくです.
そのために、ジャンパーをつぎの1)2)のように設定 してください.
  1) USBシリアル変換基板のジャンパーピンは、下図の赤色の位置にします.
  2) STM8S-DISCOVERYのJP1のジャンパーピンは、外しておきます.



STM8S-DISCOVERYのボードレイアウトはこうなっています.


USBシリアル変換基板の取付完了状態はこのようになります.
右の黄色の囲いがUSBシリアル変換回路です.同基板に刺さっているMini-USBがPCのUSBへ行きます.
中央の水色の囲いがSTM8Sマイコンです.USBシリアル変換回路と配線されています.
左の赤い囲いは、ブロック図には描きませんでしたがSTM8Sを焼くために必須な回路です.同基板に刺さっているUSBケーブルは、STM8Sを焼くためのケーブルです.やはりPCに接続します.
この回路は、PCのUSBポートを都合2ヶ占有することになります.


プログラムを焼いてしまえば、焼き用のUSBケーブルは不要になるわけで、下図のようにUSBを外してしまいたくなるのが人情です.
ところが、USBケーブルを外しただけでは、STM8Sにリセットがかかってしまって動かなくなってしまいます.
そこで、下の写真の丸の中にあるSB1とSB2をハンダごてでOPENにしてやればリセット線が切断されるので、STM8Sが動きます.
この方法は憶えておきましょう.



ATIM1_CH1の改造
STM8S-DISCOVERY基板のオリジナルではTIM1_CH1はタッチパネル機能に使われており、CN2-2に接続されていません.
ハンダごてで改造が必要です.
下の写真のようにSB3のハンダジャンパーを付け替えてください.
写真がわかりにくいかもですが、

@ABと3つのランドが並んでいるとして、オリジナルのSTM8S-DISCOVERYではA+Bがハンダショートされています.
これを変更し@+Aをハンダでショートさせます.
そうすることでTIM1_CH1がCN2-2に接続されます.
この写真は改造後です.


B
周期測定回路の入力ピンとパルス発振器の出力ピンを接続する
最後に、STM8S-DISCOVERY上で周期測定回路とパルス発振器を接続します.
  −TIM1_CH1  PC1 (26pin) (CN2-2) が周期測定回路の入力ピン
  −
TIM2_CH1  PD4 (45pin) (CN4-9) がパルス発振器の出力ピン
この両者を接続します.
上の方にSTM8S-DISCOVERYのボードレイアウト図が貼ってあるのでそれを見てください.



ソースコードの解説

サンプルプログラムをこちらに置いてあります.

ソースコードは、main.c と usrlib-uart.c の2つです.
usrlib-uart.cはUART関連ルーチンだけをまとめた
自作のソースファイルです.


main.c

●#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "stm8s.h"
#include "usrlib-uart.h"

C標準関数をインクルードします.
stm8s.hは、ライブラリを使うためのおきまりのインクルードです.
UARTを動かす自作のルーチン usrlib-uart.c をつかうために、usrlib-uart.h をインクルードします.

●#define fMASTER    16000000  // 16MHz
TIM1へ入力されるクロック周波数は16MHzなのでそれをdefineしておきます.

●CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
クロック設定についてはこちらのページをみて思い出しましょう.
この設定ですと、外付け水晶16MHz(HSE)が、CPUにもタイマにも供給
されるようになります.

●GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_HIGH_FAST);
割り込みの度にLEDをチカチカさせます.そのためにPD0を出力に設定しています.
GPIOについてはこちらのページを見て思い出しましょう.

●TIM1_DeInit();
周波数測定するTIM1の設定の開始です.念のためTIM1_DeInit()でTIM1をdefault値に設定しておきます.

●@TIM1_PrescalerConfig(0, TIM1_PSCRELOADMODE_UPDATE);
TIM1に入力されるクロックである16MHzを、分周するかどうかの設定をします.
下図の@のところを設定しているわけです.
第1引数が0なので、分周比は1、つまり分周しません.したがってTIM1の16bitカウンタは16MHzのクロックで動きます.
第1引数は、0〜65535までの範囲を設定できます.0で分周なし、1で2分周、Nで(N+1)分周します.
第2引数は、
TIM1_PSCRELOADMODE_UPDATEを決め打ちでいいでしょう.
ただし、発信周波数が50Hzなどのように低いときには分周比を大きくするように下の方で制御します.

●A
TIM1_PWMIConfig(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0);
タイマーにはいろいろな使い方がありますが、周波数測定をすることを、STM8SのdocumentではPWM input signal measurementと呼称しています.
この関数は、TIM1を周波数測定機能に設定する根幹となる関数です.
下図のAの部分を設定しています.

第1引数 TIM1_CH1を入力ピンに設定しています
第2引数 positiveエッジでカウント開始に設定しています
第3引数 InputCapture1とInputCapture2を逆転させるような機能ですが、TIM1_ICSELECTION_DIRECTTI だけ憶えておけばいいでしょう
第4引数 割り込み頻度を下げたいときに使います.
周期測定をするときは、たいてい1周期毎に割り込みをかけます.
すると、TIM1_CH1に入力される信号が100Hzだったら10mSecごとに割り込みが発生しますが、10kHzだったら100uSecごとに割り込みが発生します.
しかし、100uSecごとに割り込み処理するのは無理です.STM8Sがそんなに高速に処理出来っこありません.
なので、TIM1_CH1に入力される信号を間引けば割り込み間隔も長くなって助かるわけです.
こういう処理の遅さはソフトウエアで処理する場合には避けようがありません.
どうしても100kHzの1周期毎にきっちりと測定したいなら、FPGAを使って純hardware処理するしかないでしょう.
さて、この引数の選択肢は、こうなっています.この引数は重要です.
TIM1_ICPSC_DIV1   間引きなし
TIM1_ICPSC_DIV2   1つ間引き    (2分周ではないので注意しましょう)
TIM1_ICPSC_DIV4   3つ間引き
TIM1_ICPSC_DIV8   7つ間引き

第5引数 外部ピンから入力した信号にはノイズが乗っていることがあるので、誤動作を避けるためにフィルタを挿入する場合にこの引数で設定します.
この回路は10Hz〜200kHzまでの外部入力をサポートしますので、この引数を非ゼロにする場合は、入力周波数レンジに応じて1〜15を最適化する必要に迫られます.それはプログラミングが難しいので省略しました.
 
0: フィルタなし
  1: fMASTERで2クロック後に再チェック
  2: fMASTERで4クロック後に再チェック
  3: fMASTERで8クロック後に再チェック
  4: fMASTER/2で6
クロック後に再チェック
  5: fMASTER/2で8クロック後に再チェック
  6: fMASTER/4で6クロック後に再チェック
  7: fMASTER/4で8クロック後に再チェック
  8: fMASTER/8で6クロック後に再チェック
  9: fMASTER/8で8クロック後に再チェック
10: fMASTER/16で5クロック後に再チェック
11: fMASTER/16で6クロック後に再チェック
12: fMASTER/16で8クロック後に再チェック
13: fMASTER/32で5クロック後に再チェック
14: fMASTER/32で6クロック後に再チェック
15: fMASTER/32で8クロック後に再チェック     (fMASTER=16MHzのときは16uSec後に再チェック)

●BTIM1_SelectInputTrigger( TIM1_TS_TI1FP1 );
上図のBのところを設定しています.
周期を測定するためには、カウンタが入力パルス信号のエッジでクリアされてほしいわけです.
そのためにはまず、カウンタへTIM1_CH1由来の信号を注入したいわけです.
引数の
TIM1_TS_TI1FP1 だと上図のBのノードがカウンタへ接続されます.

●CTIM1->SMCR = (TIM1->SMCR & ~TIM1_SMCR_SMS) | 0b100; // TIM1->SMCR->SMS=100 (Reset mode)
この行はライブラリ関数callではなくて、TIM1のレジスタをダイレクトにいじっています.
なぜかというと、ライブラリ関数に、ここをいじるのに適した関数がなさそうだったからです.
この設定の意図はこうです.
BでカウンタへTIM1_CH1由来の信号を注入するように設定しました.
ここでは、カウンタが入力信号のエッジでクリアされるように設定しています.
STM8S documentではReset modeと呼称されています.

●TIM1_ITConfig(TIM1_IT_CC1, ENABLE);
引数のTIM1_IT_CC1は「InputCapture1で割り込みかけてね」という意味です.
すなわち、入力パルス信号のエッジで割り込みがかかります.

TIM1_Cmd(ENABLE);
TIM1を動かします.

●TIM2_DeInit();
TIM2_TimeBaseInit(TIM2_PRESCALER_1, 15999);
TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 4800, TIM2_OCPOLARITY_HIGH); // output TIM2_CH1 PD4
TIM2_OC2Init(TIM2_OCMODE_PWM2, TIM2_OUTPUTSTATE_ENABLE, 4800, TIM2_OCPOLARITY_HIGH); // output TIM2_CH2 PD3
TIM2_Cmd(ENABLE);

タイマはTIM1,2,3,4の4つあります.そのうちTIM2を発振器として活用するための設定です.
ただ発振するだけなので割り込みはかけません.  (TIM1でのパルス発振方法はこちらで解説してます)
上記の設定でどうしてこういう信号を発生させられるのかを説明しますと、
TIM2_TimeBaseInit(TIM2_PRESCALER_1, 15999)
この関数で16MHzを16000カウントします.
これで1kHzの三角波(下図青線)を発生させたことになります.
TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 4800, TIM2_OCPOLARITY_HIGH)
この関数で4800でコンパレートしてTIM2_CH1に出力することになります.duty30%です.(下図)
TIM2_OC2Init(TIM2_OCMODE_PWM2, TIM2_OUTPUTSTATE_ENABLE, 4800, TIM2_OCPOLARITY_HIGH)
この関数で4800でコンパレートしてTIM2_CH2に出力することになります.
第1引数が
TIM2_OCMODE_PWM2なのでTIM2_CH1のコンプリメンタリ信号がでます.(下図)
この関数のいじり所としては、
TIM2_OUTPUTSTATE_DISABLE
にすれば何も出力されなくなります.
4800
を変えればdutyを変えられます.
TIM2_OCPOLARITY_LOW にすれば出力が反転されます.
周波数とdutyは可変ですので、ソースコードの下の方で、15999と4800は上書きされます.


TIM3_DeInit();
TIM3_TimeBaseInit(TIM3_PRESCALER_1024 , 10000); // 16MHz/1024/10000=1.56Hz
TIM3_ITConfig(TIM3_IT_UPDATE, ENABLE);
TIM3_Cmd(ENABLE);

このプログラムはタイマをたくさん使いますねー.
TIM3はUARTに周波数測定結果を送信するインターバル割り込みを発生させます.
TIM3_TimeBaseInit()の第1引数は、TIM1へ入ってくる16MHzクロックを1024分周してねと設定しています.
第2引数は、それを10001サイクルカウントせよと設定しています.
その結果、16MHz/1024/10000=1.56Hzでカウンタがグルグル回ります.
TIM3_ITConfig()はカウンタがoverflowしたら割り込みしてくれと設定しています.
ゆえに1.56HzでTerminalソフト画面に周波数測定結果が表示されることになります.
割り込みルーチンは後ででてきます.
TIM1,TIM2,TIM3,TIM4による割り込みのやりかたはこちらのページを参照したください.

●UART2_DeInit();
UART2_Init((u32)115200, UART2_WORDLENGTH_9D, UART2_STOPBITS_1, UART2_PARITY_ODD, UART2_SYNCMODE_CLOCK_DISABLE, UART2_MODE_TXRX_ENABLE);   
UART2_ITConfig(UART2_IT_RXNE_OR, ENABLE);
UART2_Cmd(ENABLE);
UARTを使うための設定ですが、解説は割愛します.UARTについてはこちらのページを参照してください.

●enableInterrupts();
割り込みを許可しています.

●SerialPutString("start\r\n");
Terminalソフト画面に「start」という文字を表示しています.
SerialPutString()は、
usrlib-uart.c の中にソースコードがあります.

●while (1)      {      UART_Menu();    }
main()の最後の仕事は、UART_Menu()を延々とcallし続けることです.
UART_Menu()はUARTから飛んでくるコマンド処理をやります.


●void TIM1_IC_isr(void) interrupt 12
{
    TIM1_IC_value1 = TIM1_GetCapture1()+2;  // get value
    TIM1_IC_value2 = TIM1_GetCapture2()+2;  // get value
    TIM1_ClearFlag(TIM1_FLAG_CC1);
}

mainルーチンで「InputCapture1で割り込みかけてね」と設定しました.
これにより
TIM1が入力パルスの1サイクルごとに割り込みをかけますと、このルーチンに飛んできます.
TIM1によるこのタイプの割り込みは12番だと決まっているので、interrupt 12と書いてあります.
やっていることはシンプルです.
InputCapture1の値を、変数
TIM1_IC_value1に格納します.
InputCapture2の値を、変数TIM1_IC_value2に格納します.
割り込みフラグをクリアします.

●void TIM3_Update_isr(void) interrupt 15
mainルーチンで「1.56Hzで割り込みかけてね」と設定しました.
これによりTIM3が割り込みをかけますと、このルーチンに飛んできます.
TIM1によるこのタイプの割り込みは15番だと決まっているので、interrupt 15と書いてあります.
やってることは、周波数とdutyを計算してUART経由でTerminalソフトに向けて送信することです.

●GPIO_WriteReverse(GPIOD,GPIO_PIN_0); // LED indicator
インジケータとして表示毎にLEDをオンオフさせています.

MEASURED_HZ = (float)fMASTER / (float)TIM1_clk_prescale / (float)TIM1_IC_value1;
MEASURED_DUTY = (float)TIM1_IC_value2 / (float)TIM1_IC_value1 * 100.0 ;
周波数とdutyを浮動小数点計算しています.

●sprintf(TXStr,"OSC: %.2fHz %.1f%% ",OSC_HZ,OSC_DUTY);
SerialPutString(TXStr);
if(verbose)    {
   sprintf(TXStr,"(PRS%u ARR%u) ",1<<TIM2_clk_prescale,(u16)ARR);
   SerialPutString(TXStr);    }
sprintf(TXStr,"-> MEAS: %.2fHz %.1f%% ",MEASURED_HZ,MEASURED_DUTY);
SerialPutString(TXStr);
if(verbose)    {
    sprintf(TXStr,"(PRS%u %u/%u)",TIM1_clk_prescale,TIM1_IC_value2,TIM1_IC_value1);
    SerialPutString(TXStr);    }
SerialPutString("\r\n");

UART経由でTerminalソフトに向けて計算結果を送信しています.
verboseフラグが立っているときには、プリスケーラとカウンタ値も送信するので、下図のような画面になります.


●if(TIM1_clk_prescale_calibrate_request==1)
    {
        if(TIM1_IC_value1>(u16)32000) TIM1_clk_prescale_calibrate_request=0; // calibration complete
        else
        {
            TIM1_clk_prescale=(u16)((float)TIM1_clk_prescale*0.9);
            if(TIM1_clk_prescale==0)
            {
                TIM1_clk_prescale=1;
                TIM1_clk_prescale_calibrate_request=0; // calibration complete
            }
            TIM1_PrescalerConfig(TIM1_clk_prescale-1, TIM1_PSCRELOADMODE_UPDATE); // change prescaler
        }
    }
これは何をやっているかというと、周波数測定のためのカウンタが16bitしかないので、10Hz〜200kHzという広範囲の周波数測定を精度良く行う ために、TIM1のclockプリスケーラを最後の行で適応的に変えています. どんな周波数のパルス信号が入力されたか知る由のないTIM1としては、なるべく広範囲の周波数に対応するべくTIM1のclockプリスケーラがデフォ ルトで1/25に設定されるようにしてあるんですが、1/25だと高い周波数のパルス信号入力時にはカウンタが大きな値にまで成長しませんので、カウンタ 値の大きさを見てTIM1のclockプリスケーラを逐次0.9倍に小さくしてゆきます.
if(TIM1_IC_value1>(u16)32000) がその判断をしているところです.

●TIM3_ClearFlag(TIM3_FLAG_UPDATE);
割り込みフラグをクリアします.
これを怠ると次回の割り込みがかかりません.


●void UART_Menu(void)
UARTから飛んでくるコマンドを処理するルーチンです.

●if(UART_STR_EXIST==1 || First==1)
コマンド処理は、常にするわけではなくて、UARTから文字列が来た場合
(UART_STR_EXIST==1)と、reset後の最初(First==1)だけです.

●fieldnumber = separate_line(command);
これは自作関数で、UARTから来た文字列commandを、単語毎に分解する関数です.

●if(fieldnumber==0) goto OSC;
fieldnumberは、UARTから来た文字列が含む単語の数を表しています.
単語が0個だということは、Enter キーが押されたと判断されますので、OSCへ飛びます.

●else if(Field[0][0]=='f' && fieldnumber==2){a=atof(Field[1]);if(a<10 || 200000<a)goto NG; OSC_HZ=a; goto OSC; }
else if(Field[0][0]=='d' && fieldnumber==2){a=atof(Field[1]);if(a<1 || 99<a)goto NG; OSC_DUTY=a; goto OSC; }
else if(Field[0][0]=='v' && fieldnumber==1){if(verbose==0)verbose=1;else verbose=0; goto RET;}
else goto NG;
UARTから来た文字列をチェックしています.
受け入れ可能なのは次の3パターンです.
   f 1000↓         OSCへ飛ぶ
   d  45↓           OSCへ飛ぶ
   v↓                RETへ飛ぶ
該当しない場合はNGへ飛んでcommand NGを表示します.

●OSC:
TIM2_clk_prescale=0;
while(1){ // prescale and ARR decision
     int i;
     ARR=fMASTER/OSC_HZ;
     for(i=1;i<=TIM2_clk_prescale;i++) ARR/=2;
     if(ARR>65500) TIM2_clk_prescale++;
     else break;
}
TIM2を発振器として設定するところです.
TIM2のプリスケーラをいくつにしたら良いかを決定しています.変数は
TIM2_clk_prescale です.
TIM2のプリスケーラは、0なら1分周、1なら2分周、Nなら(N+1)分周という働きをします.
プリスケーラが決まったら、16bitカウンタのmax値であるARRも決めます.
というか、ARRが65535を超えない範囲で最大化するように
TIM2_clk_prescaleを決定しているのが本音なんですが.

●duty=(u16)(ARR*OSC_DUTY/100.0);
所望のdutyを得るためのパラメータを決めます.

●TIM2_DeInit();
TIM2_TimeBaseInit(TIM2_clk_prescale, (u16)ARR-1);  // 16MHz/prescale/arr
TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, duty, TIM2_OCPOLARITY_HIGH); // output PD4
TIM2_OC2Init(TIM2_OCMODE_PWM2, TIM2_OUTPUTSTATE_ENABLE, duty, TIM2_OCPOLARITY_HIGH); // output PD3
TIM2_Cmd(ENABLE);
main()でTIM2を設定しましたが、ここで得たARRとdutyでTIM2の設定を上書きします.
念のため、TIM2のプリスケーラは、2のべき乗でしか設定できません.

●TIM1_clk_prescale=25;  // prescaler start value
TIM1_clk_prescale_calibrate_request=1; // start frequency counter calibration
TIM1_PrescalerConfig(TIM1_clk_prescale-1, TIM1_PSCRELOADMODE_UPDATE);
TIM2の設計が変更された、つまり周波数が変更された、よって周波数測定TIM1のプリスケーラも再度最適化する必要に迫られる運びと成りました.
そこで、TIM1のプリスケーラを1/25に設定し、プリスケーラの再調整をするように要求フラグを立てています.
TIM1のプリスケーラ調整ルーチンはTIM3割り込みルーチン内にあります.
この場所でTIM1のプリスケーラを再調整しないのは、測定結果を表示する都度プリスケーラが逐次修正されるようにしたかったからです.
そのほうが目に見えますので.

●RET:
SerialPutString("f 20.4 ---> 20.4 Hz (10-200000)\r\n");
SerialPutString("d 10.0-99.0 ---> duty percent (1-99)\r\n");
SerialPutString("v ---> verbose mode\r\n\n");
UART_STR_EXIST=0;
return;
menuを表示してUART_Menu()からreturnします.

●NG:
SerialPutString("COMMAND NG!\r\n");
goto RET;
コマンドが変な場合はmenuを表示する前に、COMMAND NGと表示します.

usrlib-uart.c

これの説明は省略します.
UARTについてかるくですが説明したページはこちらです.



動作結果

Terminal softの表示は、下図のように、約1秒ごとに1行ずつ表示されます.

周波数を変更するときには、 Termina soft画面で たとえば f 134000↓ と打ちます.

dutyを変更するときは、Termina soft画面で たとえば d 45↓ と打ちます.

表示の第一行目の意味は、
   OSC:  発振器の設定の意味
   134000.00Hz   発信器が発生している周波数
   33.3%   発信器が発生しているパルスのduty
   MEAS:   周波数カウンタの測定値の意味
   106666.66Hz    周波数カウンタが測定した周波数
   50.0%   周波数カウンタが測定したduty.
となります.
行方向にMEASの表示が変化してゆきますが、これがTIM1プリスケーラ再調整の効果です.
16行目以降は、TIM1プリスケーラが調整完了したとみえて、表示が134453.78Hzというまともな値に落ち着いています.


カウンタ値などを表示させたいときには、
Termina soft画面で v↓ と打ちますと、表示が複雑になります.
(PRS1 ARR119)の意味は、
    TIM2発信器のプリスケーラの分周比=1
    TIM2発信器のカウンタのmax値=119
になっているです.
(PRS25 39/119)の
意味は
    TIM1周波数カウンタのプリスケーラの分周比=1/25
    TIM1周波数カウンタの値が、周期=119、HIGH区間=39
になっているです.

再度
Termina soft画面で v↓ と打つと ( )の表示は消えます.


inserted by FC2 system