STM8と内部タイマーを使って3分タイマー (WS2812B 40個?)


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


```c++




#define L_NUM 40

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

#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()
{
  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

char al;    //秒
char al_bk; //秒のバックアップ

void setup() {

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

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

  al_bk = millis() / 1000 ;

}//setup

char rgb = 0; //r=0 g=1 b=2 silo=4
char loop_i=0;

void loop() {

  //秒が変わるまで待つ
  while(1) {
    al = millis() / 1000; //秒
    if( al != al_bk) {break;}
  }//while
  al_bk=al; //値を保存


if(rgb == 0 ){
  //状態を1づつ進める
  for(char ii=0;ii<L_NUM;ii++){
    //1個のデータをセット  
    l[(ii*3)+0] = 0;
    l[(ii*3)+1] = loop_i; 
    l[(ii*3)+2] = 0;
  }//for
  ws_led();//RGB_LEDにデータをn回分送る
  loop_i++;if(loop_i>=60){loop_i=0;rgb++;}
}else if( rgb == 1){
  //状態を1づつ進める
  for(char ii=0;ii<L_NUM;ii++){
    //1個のデータをセット  
    l[(ii*3)+0] = loop_i;
    l[(ii*3)+1] = 0;
    l[(ii*3)+2] = 0;
  }//for
  ws_led();//RGB_LEDにデータをn回分送る
  loop_i++;if(loop_i>=60){loop_i=0;rgb++;}
}else if( rgb == 2){
  //状態を1づつ進める
  for(char ii=0;ii<L_NUM;ii++){
    //1個のデータをセット  
    l[(ii*3)+0] = 0;
    l[(ii*3)+1] = 0;
    l[(ii*3)+2] = loop_i;
  }//for
  ws_led();//RGB_LEDにデータをn回分送る
  loop_i++;if(loop_i>=60){loop_i=0;rgb++;}
} else if( rgb == 3){ //3分経ったらループを停止してブリンク
  //if( al == 180  ) { //3分
    //状態を1づつ進める
    for(char ii=0;ii<L_NUM;ii++){
      //1個のデータをセット  
      l[(ii*3)+0] = 12;
      l[(ii*3)+1] = 12;
      l[(ii*3)+2] = 12;
    }//for
    ws_led();//RGB_LEDにデータをn回分送る
    //while(1){
    //}//while
}//endif


  //約1秒待つ
  delay(980);
  //delay(100);

}//loop




```