STM32L010とWS2812B(8個)でテーブルの値の通り光らせる。 HAL


x NOP (ノップ?)やループでタイミングを取らずにダイレクト
x Mbed2のリビジョンは、143

目的
GPIOのテスト

創意工夫点
テーブルの値をロムに格納

![o_con3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d852f0df-01c6-cb32-222f-6399744c4d44.jpeg)


忙しい人よう


https://os.mbed.com/users/caa45040/code/HAL_WS_PRG_010_2/



![o_con33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/aa65485e-c67f-3f95-116a-fd14b7732840.jpeg)


![o_con34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/73f2a106-aa67-d11d-c7a2-e7fdf03fc0b9.jpeg)



![o_con35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8436dc0e-af85-5bc7-b265-9577e239ec73.jpeg)




清書した。

```c++

#include "mbed.h"

//myled         1.827Mhz 010
//GPIOA->ODR    7,995Mhz 010

int l[90]; //max30 led

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

const char train_x[16][3*8] = 
{//G0,R0,B0  G1,R1,B1  G2,R2,B2  G3,R3,B3  G4,R4,B4  G5,R5,B5  G6,R6,B6  G7,R7,B7
  { 2,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //0
  { 0, 0, 0, 32, 2,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //1
  { 0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //2
  { 0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //3
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //4
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  2,32,32,  0, 0, 0,  0, 0, 0}, //5
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32, 2,32,  0, 0, 0}, //6
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2}, //7
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32, 2,32,  0, 0, 0}, //8 
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  2,32,32,  0, 0, 0,  0, 0, 0}, //9
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //10
  { 0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //11
  { 0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //12
  { 0, 0, 0, 32, 2,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //13
  { 2,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //14
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}  //15
};

//              5432109876543210
#define on1   0b0000000000010000
#define off1  0b0000000000000000

#define M_ON1   GPIOA->ODR=on1;GPIOA->ODR=on1;GPIOA->ODR=on1;GPIOA->ODR=on1;
#define M_OFF1  GPIOA->ODR=off1;GPIOA->ODR=off1;GPIOA->ODR=off1;GPIOA->ODR=off1;

// 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 
void bit_off1(){
   //0.3us 800khz
        M_ON1;
        M_ON1;
        GPIOA->ODR = on1;

        M_OFF1;
        M_OFF1;
        M_OFF1;
        M_OFF1;
        M_OFF1;
        M_OFF1;
        M_OFF1;
        GPIOA->ODR = off1;
}//bit_off1

// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
void bit_on1(){
   //1us 800khz
        M_ON1;
        M_ON1;
        M_ON1;
        M_ON1;
        M_ON1;
        M_ON1;
        M_ON1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;

        M_OFF1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
}//bit_on1

//ws2812bにデータを送る
int ws_led(int num1)
{
    int on_off;

    for(int ii=0;ii<num1;ii++){

        //8ビット分送る
        for(int jj=0;jj<8;jj++){

            on_off = l[ii] & b8[jj];

            if( on_off == 0 ){                
                bit_off1();//ビットが0
            } else {
                bit_on1();//ビットが1 
            }//endif

        }//for 8bit


    }//for max30byt

    return(0);//リターン
}

//GPIOの初期化
void GPIO_INIT1() {

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}//GPIO_INIT1

//メイン
int main() {

    //GPIOの初期化
    GPIO_INIT1();

  while(1){

    for(int jj=0;jj<16;jj++){
      for(int ii=0;ii<(3*8);ii++){
        l[ii] = train_x[jj][ii];
      }//for ii

      //ws2812bへデータを送る
      ws_led(3*8);

      //0.2秒待つ
      wait_ms(200);
    }//for jj

  } //while

} //main



```





マクロでソースを短くした。


```c++

#include "mbed.h"

//myled         1.827Mhz 010
//GPIOA->ODR    7,995Mhz 010

//              5432109876543210
#define on1   0b0000000000010000
#define off1  0b0000000000000000

//GPIOの初期化
void GPIO_INIT1() {

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}//GPIO_INIT1


int l[90]; //max30 led

void bit_on1();
void bit_off1();

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

//ws2812bにデータを送る
int ws_led(int num1)
{
    int on_off;

    for(int ii=0;ii<num1;ii++){

        //8ビット分送る
        for(int jj=0;jj<8;jj++){

            on_off = l[ii] & b8[jj];

            if( on_off == 0 ){                
                bit_off1();//ビットが0
            } else {
                bit_on1();//ビットが1 
            }//endif

        }//for 8bit


    }//for max30byt

    return(0);//リターン
}

const char train_x[16][3*8] = 
{//G0,R0,B0  G1,R1,B1  G2,R2,B2  G3,R3,B3  G4,R4,B4  G5,R5,B5  G6,R6,B6  G7,R7,B7
  { 2,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //0
  { 0, 0, 0, 32, 2,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //1
  { 0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //2
  { 0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //3
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //4
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  2,32,32,  0, 0, 0,  0, 0, 0}, //5
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32, 2,32,  0, 0, 0}, //6
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2}, //7
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32, 2,32,  0, 0, 0}, //8 
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  2,32,32,  0, 0, 0,  0, 0, 0}, //9
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //10
  { 0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //11
  { 0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //12
  { 0, 0, 0, 32, 2,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //13
  { 2,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //14
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}  //15
};




//メイン
int main() {

    //GPIOの初期化
    GPIO_INIT1();

  while(1){

    //l[3*0+0] = 31;
    //l[3*0+1] = 32;
    //l[3*0+2] = 33;
    //
    //l[3*1+0] = 30;
    //l[3*1+1] = 10;
    //l[3*1+2] = 32;
    //
    //l[3*2+0] = 10;
    //l[3*2+1] = 10;
    //l[3*2+2] = 32;

    for(int jj=0;jj<16;jj++){
      for(int ii=0;ii<(3*8);ii++){
        l[ii] = train_x[jj][ii];
      }//for ii

      //ws2812bへデータを送る
      ws_led(3*8);

      //0.2秒待つ
      wait_ms(200);
    }//for jj
    
  } //while

} //main


#define M_ON1   GPIOA->ODR=on1;GPIOA->ODR=on1;GPIOA->ODR=on1;GPIOA->ODR=on1;
#define M_OFF1  GPIOA->ODR=off1;GPIOA->ODR=off1;GPIOA->ODR=off1;GPIOA->ODR=off1;

// 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 
void bit_off1(){
   //0.3us 800khz
        M_ON1;
        M_ON1;
        GPIOA->ODR = on1;

        M_OFF1;
        M_OFF1;
        M_OFF1;
        M_OFF1;
        M_OFF1;
        M_OFF1;
        M_OFF1;
        GPIOA->ODR = off1;

}//bit_off1


// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
void bit_on1(){
   //1us 800khz
        M_ON1;
        M_ON1;
        M_ON1;
        M_ON1;
        M_ON1;
        M_ON1;
        M_ON1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;

        M_OFF1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
}//bit_on1



```


改良前

```c++


#include "mbed.h"

//myled         1.827Mhz 010
//GPIOA->ODR    7,995Mhz 010

//              5432109876543210
#define on1   0b0000000000010000
#define off1  0b0000000000000000

//GPIOの初期化
void GPIO_INIT1() {

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}//GPIO_INIT1


int l[90]; //max30 led

void bit_on1();
void bit_off1();

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

//ws2812bにデータを送る
int ws_led(int num1)
{
    int on_off;

    for(int ii=0;ii<num1;ii++){

        //8ビット分送る
        for(int jj=0;jj<8;jj++){

            on_off = l[ii] & b8[jj];

            if( on_off == 0 ){                
                bit_off1();//ビットが0
            } else {
                bit_on1();//ビットが1 
            }//endif

        }//for 8bit


    }//for max30byt

    return(0);//リターン
}

const char train_x[16][3*8] = 
{//G0,R0,B0  G1,R1,B1  G2,R2,B2  G3,R3,B3  G4,R4,B4  G5,R5,B5  G6,R6,B6  G7,R7,B7
  { 2,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //0
  { 0, 0, 0, 32, 2,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //1
  { 0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //2
  { 0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //3
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //4
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  2,32,32,  0, 0, 0,  0, 0, 0}, //5
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32, 2,32,  0, 0, 0}, //6
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2}, //7
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32, 2,32,  0, 0, 0}, //8 
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  2,32,32,  0, 0, 0,  0, 0, 0}, //9
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //10
  { 0, 0, 0,  0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //11
  { 0, 0, 0,  0, 0, 0, 32,32, 2,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //12
  { 0, 0, 0, 32, 2,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //13
  { 2,32,32,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}, //14
  { 0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0}  //15
};




//メイン
int main() {

    //GPIOの初期化
    GPIO_INIT1();

  while(1){

    //l[3*0+0] = 31;
    //l[3*0+1] = 32;
    //l[3*0+2] = 33;
    //
    //l[3*1+0] = 30;
    //l[3*1+1] = 10;
    //l[3*1+2] = 32;
    //
    //l[3*2+0] = 10;
    //l[3*2+1] = 10;
    //l[3*2+2] = 32;

    for(int jj=0;jj<16;jj++){
      for(int ii=0;ii<(3*8);ii++){
        l[ii] = train_x[jj][ii];
      }//for ii

      //ws2812bへデータを送る
      ws_led(3*8);

      //0.2秒待つ
      wait_ms(200);
    }//for jj
    
  } //while

} //main

// 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 
void bit_off1(){
   //0.3us 800khz
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;

        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;


}//bit_off1


// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
void bit_on1(){
   //1us 800khz
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;
        GPIOA->ODR = on1;

        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
        GPIOA->ODR = off1;
}//bit_on1




```