STM32L010と内部タイマーを使って3分タイマー (ソフトウェアシリアル出力)(LED)


x Mbedのリビジョンは、125

目的
waitでもタイマーは、作れるがそれより正確な
内部タイマーを使って3分タイマーを作ってみた。
3分経つとLEDを点滅させる
mbedで内部タイマーが動く事がわたった。
当然ms(ミリ秒)、us(マイクロ秒)が動く事がわかつた。


参考
https://os.mbed.com/users/okini3939/notebook/timer_jp/

一文字の長さを内部タイマーを使って計って見たら
だいたい104xuSなので「よし」とする

忙しい人よう
https://os.mbed.com/users/caa45040/code/timer_test_010/


いろいろ改良後

```c++

//timer

#include "mbed.h"
 
//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)
 
//1000の割り算 180000までは、ほぼ正しい　ミリ秒を切り捨てす為に精度は、不要
#define DVI1000(n3)     (((n3>>3)*4195)>>19)

//6の割り算 主に18まで
#define DVI6(n6)        ((n6*683)>>12)
 
//Serial pc(USBTX, USBRX); // tx, rx
//Serial pc(SERIAL_TX, SERIAL_RX); //767
//Serial pc(PA_2, PA_3); //010
//Serial pc(PA_9, PA_10); //010

#define UART_DELAY 96 //  1/9600

//仮想シリアルの出力ポート
//DigitalOut TX(PA_9);
DigitalOut TX(PA_2);

//DigitalOut myled(D13);    //767
DigitalOut myled(PA_4);

//タイマーの定義
Timer t;

//d int q_st; //スタートタイム debug
//d int q_et; //エンドタイム   debug

//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch) {

    TX=1;
    
//d    q_st = t.read_us(); //debug
    
    TX=0;//START
    wait_us(UART_DELAY);
    
//d    q_et = t.read_us(); //debug

    for(int ii=0;ii<8;ii++){
        TX=(ch>>ii)&1;
        wait_us(UART_DELAY);
    }; //for

    TX=1;//Stop
    wait_us(UART_DELAY);

//d    q_et = t.read_us(); //debug 引いた数が0で1041ufなら正解
         
    return(0);
    
} //pc_putc

//文字列の表示
int pc_printf(char *str1) {

    //文字の中身がゼロか
    while(*str1){
            
        //一文字出力
        pc_putc(*str1 ++);
                        
    } //while

    //戻り値
    return(0);
}//pc_printf

//10文字分のバッファー
char str10[10];

//d int l_num,aaa,bbb,ccc,qqq; //debug
//d char ch_hex_a_b[10];   //debug

int main() {

    //初期化
    TX=1;wait_ms(2);    //文字分のウエート
    pc_printf("\r\n");  //ゴミの吐き出し
        
//d    pc_printf("\r\n");
//d    pc_printf("Hello World!\r\n");
    
    //タイマーの開始
    t.start();
    //pc.printf("Hello World!\r\n");
    //t.stop();


//d    //dbbug
//d    for(int ll=0;ll<40;ll++){
//d        pc_putc('A');
//d        //q_st = t.read_us(); //debug
//d        //wait_us(104);
//d        //q_et = t.read_us(); //debug
//d        l_num = (q_et-q_st)/10;
//d        bbb=DVI10(l_num);
//d        ccc=l_num-(bbb*10);
//d        l_num=bbb;
//d        aaa=DVI10(l_num);
//d        bbb=l_num-(aaa*10);
//d        ch_hex_a_b[0] = '0' + aaa;
//d        ch_hex_a_b[1] = '0' + bbb;
//d        ch_hex_a_b[2] = '0' + ccc;
//d        ch_hex_a_b[3] = 'X';
//d        ch_hex_a_b[4] = 'u';
//d        ch_hex_a_b[5] = 'S';
//d        ch_hex_a_b[6] = 0;
//d        pc_printf(ch_hex_a_b);
//d        pc_printf("\r\n");
//d        wait_ms(1000);
//d    }
//d    pc_printf("\r\n");


    //初期値の表示
    pc_printf("0m00s\r\n");

    //最初のウエート
    wait_ms(990);

    int a,b,c,d,e; //分秒
    int a_bk=0;    //秒のバックアップ

    //無限ループ
    while(1) { 
        //pc.printf("The time taken was %f seconds\r\n", t.read()); //767
        //pc.printf("The time taken was %d seconds\r\n",  DVI1000( t.read_ms() )  ); //767
        
        //秒が変わるまで待つ
        while(1) {
            a = DVI1000( t.read_ms() ); //秒
            if( a != a_bk) {break;}
        }//while
        a_bk=a; //値を保存
                
        //1秒毎のブリンク
        myled = 1;
        wait_ms(10);
        myled = 0;
        
        //秒から分の分離
        b = DVI10( a ); //1シフト 123秒の時は、12が戻る
        c = a - (b*10); //1の桁 123秒の時は、3が戻る
        d = DVI6( b ); //分 12の時は、3分
        e = b - ( d * 6 ); // 秒の10の桁　12- 3分*6 = 0
        //pc.printf("%d %t %d %t %d \r\n",  d , e , c  ); //767
        
        //分秒の表示
        str10[0] = ('0'+d);
        str10[1] = ('m');
        str10[2] = ('0'+e);
        str10[3] = ('0'+c);
        str10[4] = ('s');
        str10[5] = ('\r');
        str10[6] = ('\n'); 
        str10[7] = (0); 
        pc_printf(str10);
        
        //3分経ったらループを停止してブリンク
        if( a == 180 /*3分*/ ) {
            while(1){
                myled = 1;
                wait_ms(500);
                myled = 0;
                wait_ms(500);
            }//while
        }//if
         
        //pc.printf("The time taken was %d seconds\r\n", t.read_ms()); //767
        //pc.printf("The time taken was %d seconds\r\n", t.read_us()); //767
        
        //約1秒を待つ
        wait_ms(980);
    } //while

} //main

//容量削減
void error(const char* format, ...){}

```

いろいろ改良前

```c++


//timer

#include "mbed.h"
 
//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)
 
//1000の割り算 180000までは、ほぼ正しい　ミリ秒を切り捨てす為に精度は、不要
#define DVI1000(n3)     (((n3>>3)*4195)>>19)

//6の割り算 主に18まで
#define DVI6(n6)        ((n6*683)>>12)
 
//Serial pc(USBTX, USBRX); // tx, rx
//Serial pc(SERIAL_TX, SERIAL_RX); //767
//Serial pc(PA_2, PA_3); //010
//Serial pc(PA_9, PA_10); //010

#define UART_DELAY 96 //  1/9600

//仮想シリアルの出力ポート
//DigitalOut TX(PA_9);
DigitalOut TX(PA_2);

//DigitalOut myled(D13);
DigitalOut myled(PA_4);

//タイマーの定義
Timer t;

//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch) {
        
    TX=1;
    TX=0;//START
    wait_us(UART_DELAY);

    for(int ii=0;ii<8;ii++){
        TX=(ch>>ii)&1;
        wait_us(UART_DELAY);
    }; //for

    TX=1;//Stop
    wait_us(UART_DELAY);
             
    return(0);
    
} //pc_putc

int main() {
    
    //タイマーの開始
    t.start();
    //pc.printf("Hello World!\r\n");
    //t.stop();

    //初期値の表示
    pc_putc('0');
    pc_putc('m');
    pc_putc('0');
    pc_putc('0');
    pc_putc('s');
    pc_putc('\r');
    pc_putc('\n');

    //最初のウエート
    wait_ms(990);

    int a,b,c,d,e; //分秒
    int a_bk=0;    //秒のバックアップ

    //無限ループ
    while(1) { 
        //pc.printf("The time taken was %f seconds\r\n", t.read()); //767
        //pc.printf("The time taken was %d seconds\r\n",  DVI1000( t.read_ms() )  ); //767
        
        //秒が変わるまで待つ
        while(1) {
            a = DVI1000( t.read_ms() ); //秒
            if( a != a_bk) {break;}
        }//while
        a_bk=a; //値を保存
                
        //1秒毎のブリンク
        myled = 1;
        wait_ms(10);
        myled = 0;
        
        //秒から分の分離
        b = DVI10( a ); //1シフト 123秒の時は、12が戻る
        c = a - (b*10); //1の桁 123秒の時は、3が戻る
        d = DVI6( b ); //分 12の時は、3分
        e = b - ( d * 6 ); // 秒の10の桁　12- 3分*6 = 0
        //pc.printf("%d %t %d %t %d \r\n",  d , e , c  ); //767
        
        //分秒の表示
        pc_putc('0'+d);
        pc_putc('m');
        pc_putc('0'+e);
        pc_putc('0'+c);
        pc_putc('s');
        pc_putc('\r');
        pc_putc('\n');        
        
        //3分経ったらループを停止してブリンク
        if( a == 180 /*3分*/ ) {
            while(1){
                myled = 1;
                wait_ms(500);
                myled = 0;
                wait_ms(500);
            }//while
        }//if
         
        //pc.printf("The time taken was %d seconds\r\n", t.read_ms()); //767
        //pc.printf("The time taken was %d seconds\r\n", t.read_us()); //767
        
        //約1秒を待つ
        wait_ms(980);
    } //while

} //main

//容量削減
void error(const char* format, ...){}



```

![timer_test_010_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e81fdec4-f5df-5601-4ff2-7e34e94277f7.jpeg)

![timer_test_010_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1f5c2fb6-ba37-fc12-0a2a-3f4f8acbbcd8.jpeg)