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



x STM8S-Discovery ボード
x NOP (ノップ?)やループでタイミングを取らずにダイレクト
x 割り込みを止めないと少しジャムる

x arduinoUNOとくらべるとなんか遅い。
x ALレジスタが1個?

目的
GPIOのテスト

構成
windows 10 20H2
Arduino
1.8.13(Windows Store 1.8.42.0)


![o_con26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a4320e56-f1bd-f8d9-a476-54c937111eff.jpeg)


![o_con33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/96c8ec7e-e573-db76-5859-f758c3bf48d0.jpeg)


![o_con34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/66a3c046-5cf1-ad1e-618d-b4acd51c5ec6.jpeg)


![o_con35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/db78ddce-20cc-0a81-9986-d08c17cea96f.jpeg)




マクロ化とクロックの安定化


```c++


#define L_NUM 8

char l[L_NUM*3]; //max8 led

const char train_x[16][L_NUM*3] = 
{//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
};

#define PD_ODR *(volatile uint8_t *)0x500F

// 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 
#define bit_off1()  PD_ODR=1;PD_ODR=0;PD_ODR=0;PD_ODR=0;PD_ODR=0;PD_ODR=0;PD_ODR=0;PD_ODR=0;

// 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
#define bit_on1()   PD_ODR=1;PD_ODR=1;PD_ODR=1;PD_ODR=1;PD_ODR=1;PD_ODR=1;PD_ODR=1;PD_ODR=0;

//RGB_LEDにデータをn回分送る
void ws_led()
{
  char al;
  disableInterrupts();
  //num1で指定された分だけループする
  for(char ii=0;ii<(L_NUM*3);ii++){
    al=l[ii];
    if( al & 0b10000000 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
    if( al & 0b01000000 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
    if( al & 0b00100000 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
    if( al & 0b00010000 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
    if( al & 0b00001000 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
    if( al & 0b00000100 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
    if( al & 0b00000010 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
    if( al & 0b00000001 ){bit_on1();/*ビットが1*/}else{bit_off1();/*ビットが0*/}
  }//for
  enableInterrupts();
}//ws_led

//RGB_LEDに0データをn回分送る
void ws_led_cl()
{
  disableInterrupts();
  //num1で指定された分だけループする
  for(char ii=0;ii< (L_NUM*3)  ;ii++){
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0

    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
  }//for
  enableInterrupts();
}//ws_led

//初期設定
void setup() {

  //外部の水晶16Mhzにする クロック安定かの為
  CLK_ClockSwitchConfig ( CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE );

  //GPIOの初期化
  pinMode(PD0, OUTPUT);

}//setup

//メインループ
void loop() {

  //状態を1つ進める
  for(char jj=0;jj<16;jj++){

    //1ライン(8個送る)
    for(char ii=0;ii<(3*L_NUM);ii++){
      l[ii] = train_x[jj][ii];
    }//for ii

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

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

}//loop




````






改良前

```c++



#define L_NUM 8

char l[L_NUM*3]; //max8 led

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
};

#define PD_ODR *(volatile uint8_t *)0x500F

// 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

    PD_ODR = 0b00000001; //1 0.125
    PD_ODR = 0b00000000; //2 0.250
    PD_ODR = 0b00000000; //3 0.375
    PD_ODR = 0b00000000; //4
    PD_ODR = 0b00000000; //5

    PD_ODR = 0b00000000; //1
    PD_ODR = 0b00000000; //2
    PD_ODR = 0b00000000; //3
    PD_ODR = 0b00000000; //4
    //PD_ODR = 0b00000000; //5

}//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

    PD_ODR = 0b00000001; //1
    PD_ODR = 0b00000001; //2
    PD_ODR = 0b00000001; //3
    PD_ODR = 0b00000001; //4
    PD_ODR = 0b00000001; //5

    PD_ODR = 0b00000001; //1
    PD_ODR = 0b00000001; //2
    PD_ODR = 0b00000000; //3 0.375
    PD_ODR = 0b00000000; //4 0.250
    PD_ODR = 0b00000000; //5 0.125

}//bit_on1


//RGB_LEDにデータをn回分送る
void ws_led()
{
  disableInterrupts();
  //num1で指定された分だけループする
  for(char ii=0;ii<(L_NUM*3);ii++){

      if( l[ii] & 0b10000000 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b01000000 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00100000 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00010000 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00001000 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00000100 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00000010 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

      if( l[ii] & 0b00000001 ){
        bit_on1(); //ビットが1 
      } else {
        bit_off1(); //ビットが0
      }//endif

  }//for
  enableInterrupts();
}//ws_led

//RGB_LEDに0データをn回分送る
void ws_led_cl()
{
  disableInterrupts();
  //num1で指定された分だけループする
  for(char ii=0;ii< (L_NUM*3)  ;ii++){
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0

    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
    bit_off1(); //ビットが0
  }//for
  enableInterrupts();
}//ws_led

void setup() {

  //GPIOの初期化
  pinMode(PD0, OUTPUT);

}//setup

void loop() {

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

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

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


}//loop




```