STM32L010でWS2812Bを光らせる。(節電8MHz内部電圧1.5V) HAL


目的
GPIOのテスト
4Mhzでは、光らなかった。

いろいろ
4MHzで出来ると思って作っているから
しさしぶりに約4時間もハマった
4MhzだとPWMのオフがWS2812でうまく認識出来なかった。
あと接触不良もあって長引いた。
4MHz,800KHzのだいだい2倍の間隔にしたらWS2912Bが光った



/* STM32L010F6P6  -> Mbed NUCLEO-L011K4 program by caa45040 */

#include "mbed.h"

#define L_NUM 30

int l[L_NUM*3]; //max30 led

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

//DigitalOut myled(PA_4);

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

// 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()  GPIOA->ODR=on1;GPIOA->ODR=off1;GPIOA->ODR=off1;GPIOA->ODR=off1;GPIOA->ODR=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
#define bit_on1()   GPIOA->ODR=on1;GPIOA->ODR=on1;GPIOA->ODR=on1;GPIOA->ODR=on1;GPIOA->ODR=on1;GPIOA->ODR=on1;GPIOA->ODR=off1;


//void bit_on1();
//void bit_off1();

//RGB_LEDにデータをn回分送る num1は無視
int ws_led1(int num1)
{
    int al;

    __disable_irq(); // disable interrupt

    //num1で指定された分だけループする
    for(int 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

    __enable_irq(); // enable interrupt

    return(0);
}//ws_led


//メイン
int main()
{

    //クロックの初期化
    HAL_RCC_DeInit();

    //電圧を下げる
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);//4Mhz 1.5 560uA

    /*
        //4MHz
        RCC_OscInitTypeDef RCC_OscInitStruct = {0};
        RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
        RCC_OscInitStruct.HSIState = RCC_HSI_DIV4;
        RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
        RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
        HAL_RCC_OscConfig(&RCC_OscInitStruct);
        RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
        RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                      |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
        RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
        RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
        RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
        RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
        HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
    */

    // 8Mhz
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);

    //GPIOの初期化
    GPIO_INIT1();
    GPIOA->ODR=off1;
    wait_ms(20);

    l[0] = 0;
    l[1] = 12;
    l[2] = 0;

    l[3] = 12;
    l[4] = 0;
    l[5] = 0;

    l[6] = 0;
    l[7] = 0;
    l[8] = 12;

    while(1) {
        ws_led1(3);
        wait_ms(100);
    }

} //main