STM32L010とWS2812B(160個、未定?)を単一の値で光らせる。(ON OFF あり)


x NOP (ノップ?)やループでタイミングを取らずにダイレクト
x 割り込みを止めないと誤作動する

目的
ぞくに言う「テープLED」「NeoPixel」「5050」を光らせる
GPIOのテスト



#include "mbed.h"

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

#define G0  0
#define R0  12
#define B0  0

char l[160*3]; //max160 led

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

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

    __disable_irq(); // disable interrupt

    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

    __enable_irq(); // enable interrupt

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

//RGB_LEDに0データをn回分送る
int ws_led_cl(int num1)
{

    __disable_irq(); // disable interrupt

    //num1で指定された分だけループする
    for(int ii=0; ii<(num1*8); ii++) {
        bit_off1(); //ビットが0
    }//for

    __enable_irq(); // enable interrupt

    return(0);
}//ws_led

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

    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};

    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    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();

    //状態を1づつ進める
    for(int ii=0; ii<160; ii++) {

        //1個のデータをセット
        l[(ii*3)+0] = G0;
        l[(ii*3)+1] = R0;
        l[(ii*3)+2] = B0;

    }//for

    while(1) {

        if( HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0 ) {
            //ws2812bへ0データを送る
            ws_led_cl(160*3);
        } else {
            //ws2812bへデータを送る
            ws_led(160*3);
        }
        //0.1秒待つ
        wait_ms(100);

    } //while

} //main