LoginSignup
0
0

More than 1 year has passed since last update.

STM32L010で周波数カウンタを作てみた。(約10khzぐらいまで)(秋月シリアル7セグ)

Last updated at Posted at 2021-08-14

x mbed2のリビジョン143

目的
基板作成が落ち着いたから
内部タイマーを使いusでオン時間で周波数を測る。
--(ディティが50対50じゃないと測れない。)--削除
周期で動くように改良 2021/8/15
秋月シリアル7セグに出力する。
レジスター直読み込みで高速化した。

赤色7セグメントLEDシリアルドライバキット(DIP化キット)
[AE-7SEG-BOARD-KIT-RED]
通販コード K-10360

h_con3.jpg

だいたい1khzを入力した

pwm_hz_82ms_2.jpg



#include "mbed.h"

//*******   ******   *****  *****  
//     *         *   *      * 
//    *         *    *****  *  ***
//  *       ****     *      *    *
//  *       *        *      *    *
//  *        *****   *****  *****

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

#define HIGH 1
DigitalIn in1(PA_1);

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

//アナログ入力の設定
//AnalogIn adc_vbat(A3); //PA_4 010
//AnalogIn adc_vbat(A0); //PA_0 010
//AnalogIn adc_vbat(A0); //767 303

#define swclk1  PA_5    //A4
#define test01  PA_6
#define swdio1  PA_7    //A6
#define en1     PA_4    //A3

DigitalOut swdclk(swclk1);
DigitalOut swdio(swdio1);
DigitalOut en(en1);

char seg[32] = {
   0x00 , //0 @ -> ' '
   0x77 , //1 A  o
   0x7c , //2 B      combined use "6"
   0x39 , //3 C
   0x5e , //4 D
   0x79 , //5 E  o
   0x71 , //6 F
   0x3d , //7 G

   0x76 , //8 H  o
   0x06 , //9 I     combined use "1"
   0x1e , //10 J
   0x75 , //11 K 
   0x38 , //12 L  o
   0x15 , //13 M
   0x37 , //14 N  o
   0x3f , //15 O  o combined use "0"

   0x73  , //16 P
   0x67  , //17 Q combined use "9"
   0x50  , //18 R
   0x6d  , //19 S combined use "5"
   0x78  , //20 T
   0x3e  , //21 U
   0x1c  , //22 V
   0x2a  , //23 W  o
   0x64  , //24 X

   0x6e  , //25 Y
   0x5b  , //26 Z combined use "2"
   0x4f  , //27 [  --> "3"
   0x66  , //28 \  --> "4"
   0x27  , //29 ]  --> "7"
   0x7f  , //26 ^  --> "8"
   0x08    //31 _
};

//             12345678   12345678   12345678   12345678
char b8[8] = {0b10000000,0b01000000,0b00100000,0b00010000,
              0b00001000,0b00000100,0b00000010,0b00000001 };

void seg1(char v)
{
    v=seg[v-64];
    for(int jj=0;jj<8;jj++){
        if( (v & b8[jj]) == 0 ){
                swdio=0; //ビットが0
        } else {
                swdio=1; //ビットが1 
        }//endif
        swdclk=1;swdclk=0; //clk
    }//for
    en=1;
    en=0;       
}//seg1


char nn[]={'O','I','Z','[','\\','S','B', ']','^','Q'};

//7segの一文字出力 nana_seg
int ns_putc(char ch) {

    if(ch == ' ') {
        ch = '@';
    } else if(ch == '.') {
        ch='@';
        seg[0]=0x80;
    } else if (ch >= '0' && ch <= '9' ) {
        ch = nn[ch-'0'];
    }

    seg1(ch);
    seg[0]=0x00;

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


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

    //文字の中身がゼロか
    while(*str1){

        //一文字出力
        ns_putc(*str1 ++);

    } //while

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



//in1のオン時間をusで測る 今のところ引数は、無効
int pulseIn(int pin1,int pu1,int timeout1)
{
    t.reset();

    //while(in1 != 0) {}

    loop_ins:
    //                      1234567890123456
    if (   (GPIOA->IDR) & 0b0000000000000010   ) { goto loop_ins;}

    //while(in1 == 0) {}

    loop_s1:
    //                            1234567890123456
    if (     (~(GPIOA->IDR))  & 0b0000000000000010    ) { goto loop_s1;}

    //led1 = 1;//debug

    int sd = t.read_us();


    //while(in1 != 0) {}

    loop_in1:
    //                      1234567890123456
    if (   (GPIOA->IDR) & 0b0000000000000010   ) { goto loop_in1;}

    //led1 = 0;//debug

    return(t.read_us()-sd);

}//pulseIn

//in1のオンオフ時間をusで測る 今のところ引数は、無効
int hzIn(int pin1,int pu1,int timeout1)
{
    t.reset();

    //while(in1 != 0) {}

    loop_ins:
    //                      1234567890123456
    if (   (GPIOA->IDR) & 0b0000000000000010   ) { goto loop_ins;}

    //while(in1 == 0) {}

    loop_s1:
    //                            1234567890123456
    if (     (~(GPIOA->IDR))  & 0b0000000000000010    ) { goto loop_s1;}

    //led1 = 1;//debug

    int sd = t.read_us();


    //while(in1 != 0) {}

    loop_in1:
    //                      1234567890123456
    if (   (GPIOA->IDR) & 0b0000000000000010   ) { goto loop_in1;}

    //while(in1 == 0) {}

    loop_e1:
    //                            1234567890123456
    if (     (~(GPIOA->IDR))  & 0b0000000000000010    ) { goto loop_e1;}


    //led1 = 0;//debug

    return(t.read_us()-sd);

}//hzIn

//メイン関数
int main() {

    char data_read[8]; //バッファー

    //7セグの初期化
    en=0;
    swdclk=0;

    ns_printf("STAR");wait_ms(200); //debug

    t.start();

    //初期値の表示
    ns_printf("0000");

    int pwmco2;
    int hz;

    //無限ループ
    while(1){

        //PWMでデータ取得
        //pwmco2=pulseIn(7 ,HIGH,2000000);
        //pwmco2=500;

        //周期でデータ取得
        pwmco2=hzIn(7 ,HIGH,2000000);
        //pwmco2=500;


        //周波数の計算
        //pwmco2=pwmco2*2;
        if(pwmco2==0){pwmco2=1;}
        hz = 1000000/pwmco2;

        //表示用の変数の初期化
        int s = hz;
        int n0,n10,n100,n1000;

        n10   = s / 10;            // 1234 -> 123
        n0    = s - (n10 *10);     // 1234 -  1230 -> 4
        n100  = n10 / 10;          // 123  -> 12
        n10   = n10 - (n100 *10);  // 123  -  120 -> 3
        n1000 = n100 / 10;         // 12   -> 1
        n100  = n100 - (n1000*10); // 12   -  10  -> 2

        //画面に表示
        data_read[0] = '0' + n1000;
        data_read[1] = '0' + n100;
        data_read[2] = '0' + n10;
        data_read[3] = '0' + n0;
        data_read[4] = 0;
        ns_printf(data_read);

        //約0.3秒待つ
        wait_ms(300);

    }//while

}//main

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



改良まえ



#include "mbed.h"

//*******   ******   *****  *****  
//     *         *   *      * 
//    *         *    *****  *  ***
//  *       ****     *      *    *
//  *       *        *      *    *
//  *        *****   *****  *****

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

#define HIGH 1
DigitalIn in1(PA_1);

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

//アナログ入力の設定
//AnalogIn adc_vbat(A3); //PA_4 010
//AnalogIn adc_vbat(A0); //PA_0 010
//AnalogIn adc_vbat(A0); //767 303

#define swclk1  PA_5    //A4
#define test01  PA_6
#define swdio1  PA_7    //A6
#define en1     PA_4    //A3

DigitalOut swdclk(swclk1);
DigitalOut swdio(swdio1);
DigitalOut en(en1);

char seg[32] = {
   0x00 , //0 @ -> ' '
   0x77 , //1 A  o
   0x7c , //2 B      combined use "6"
   0x39 , //3 C
   0x5e , //4 D
   0x79 , //5 E  o
   0x71 , //6 F
   0x3d , //7 G

   0x76 , //8 H  o
   0x06 , //9 I     combined use "1"
   0x1e , //10 J
   0x75 , //11 K 
   0x38 , //12 L  o
   0x15 , //13 M
   0x37 , //14 N  o
   0x3f , //15 O  o combined use "0"

   0x73  , //16 P
   0x67  , //17 Q combined use "9"
   0x50  , //18 R
   0x6d  , //19 S combined use "5"
   0x78  , //20 T
   0x3e  , //21 U
   0x1c  , //22 V
   0x2a  , //23 W  o
   0x64  , //24 X

   0x6e  , //25 Y
   0x5b  , //26 Z combined use "2"
   0x4f  , //27 [  --> "3"
   0x66  , //28 \  --> "4"
   0x27  , //29 ]  --> "7"
   0x7f  , //26 ^  --> "8"
   0x08    //31 _
};

//             12345678   12345678   12345678   12345678
char b8[8] = {0b10000000,0b01000000,0b00100000,0b00010000,
              0b00001000,0b00000100,0b00000010,0b00000001 };

void seg1(char v)
{
    v=seg[v-64];
    for(int jj=0;jj<8;jj++){
        if( (v & b8[jj]) == 0 ){
                swdio=0; //ビットが0
        } else {
                swdio=1; //ビットが1 
        }//endif
        swdclk=1;swdclk=0; //clk
    }//for
    en=1;
    en=0;       
}//seg1


char nn[]={'O','I','Z','[','\\','S','B', ']','^','Q'};

//7segの一文字出力 nana_seg
int ns_putc(char ch) {

    if(ch == ' ') {
        ch = '@';
    } else if(ch == '.') {
        ch='@';
        seg[0]=0x80;
    } else if (ch >= '0' && ch <= '9' ) {
        ch = nn[ch-'0'];
    }

    seg1(ch);
    seg[0]=0x00;

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


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

    //文字の中身がゼロか
    while(*str1){

        //一文字出力
        ns_putc(*str1 ++);

    } //while

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

//in1のオン時間をusで測る 今のところ引数は、無効
int pulseIn(int pin1,int pu1,int timeout1)
{
    t.reset();

    //while(in1 != 0) {}

    loop_ins:
    //                     1234567890123456
    if (   (GPIOA->IDR & 0b0000000000000010) != 0   ) { goto loop_ins;}

    //while(in1 == 0) {}

    loop_s1:
    //                     1234567890123456
    if (   (GPIOA->IDR & 0b0000000000000010) == 0   ) { goto loop_s1;}

    //led1 = 1;//debug

    int sd = t.read_us();

    //while(in1 != 0) {}

    loop_in1:
    //                     1234567890123456
    if (   (GPIOA->IDR & 0b0000000000000010) != 0   ) { goto loop_in1;}

    //led1 = 0;//debug

    return(t.read_us()-sd);

}//pulseIn

//メイン関数
int main() {

    char data_read[8]; //バッファー

    //7セグの初期化
    en=0;
    swdclk=0;

    ns_printf("STAR");wait_ms(200); //debug

    t.start();

    //初期値の表示
    ns_printf("0000");

    int pwmco2;
    int hz;

    //無限ループ
    while(1){

        //PWMでデータ取得
        pwmco2=pulseIn(7 ,HIGH,2000000);
        //pwmco2=500;

        //周波数の計算
        pwmco2=pwmco2*2;
        if(pwmco2==0){pwmco2=1;}
        hz = 1000000/pwmco2;

        //表示用の変数の初期化
        int s = hz;
        int n0,n10,n100,n1000;

        n10   = s / 10;            // 1234 -> 123
        n0    = s - (n10 *10);     // 1234 -  1230 -> 4
        n100  = n10 / 10;          // 123  -> 12
        n10   = n10 - (n100 *10);  // 123  -  120 -> 3
        n1000 = n100 / 10;         // 12   -> 1
        n100  = n100 - (n1000*10); // 12   -  10  -> 2

        //画面に表示
        data_read[0] = '0' + n1000;
        data_read[1] = '0' + n100;
        data_read[2] = '0' + n10;
        data_read[3] = '0' + n0;
        data_read[4] = 0;
        ns_printf(data_read);

        //約0.3秒待つ
        wait_ms(300);

    }//while

}//main

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




h_con3.jpg

h_con28.jpg

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0