STM32L010とS-5851Aで液晶温度計 (Mbed)(AQM0802A)(節電4MHz内部電圧1.5V) HAL



目的
電池使用を考えて論理値約5mAから約0.5mAに
なったはず。(未測定)(約5mAは、LED程度)



x Mbedのリビジョン143

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり


![o_con72.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b72e5a59-13f5-0c88-e8b9-fce49594dff0.jpeg)


![o_con73.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a8fc799c-1412-7438-4295-d5e42e9271e1.jpeg)



```c++



#include "mbed.h"

I2C_HandleTypeDef hi2c1;

//I2Cの初期化
void I2C_INIT1()
{
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};

    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    __HAL_RCC_I2C1_CLK_ENABLE();


    //I2C_HandleTypeDef hi2c1;

    hi2c1.Instance = I2C1;
    hi2c1.Init.Timing = 0x00000708;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    HAL_I2C_Init(&hi2c1);

    HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE);

    HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0);

}//I2C_INIT1




//メイン関数
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);



    const int ADDR       = 0x90; //  address 5851
    //const int ADDR       = 0x72; //  address 751
    const int ADDR_LCD   = 0x7C; //  address

    //液晶の初期化の文字列
    uint8_t INIT_com[]= {
        0x0,0x38,
        0x0,0x39,
        0x0,0x4,
        0x0,0x14,
        0x0,0x70,
        0x0,0x56,
        0x0,0x6C,
        0x0,0x38,
        0x0,0xC,
        0x0,0x1,
        0x40,0x41
    };

    //画面のクリア
    uint8_t INIT_cls[]= {0x0,0x1};


    wait_ms(2); //HAL_Delay(10);がなぜか正常に動かないので一旦呼び出し


    //I2Cの初期化
    I2C_INIT1();

    //液晶の初期化
    HAL_Delay(200); //液晶の安定待ち
    for(int ii=0; ii<11; ii++) {
        HAL_I2C_Master_Transmit(&hi2c1, ADDR_LCD, &INIT_com[ii*2], 2, 3000);
        HAL_Delay(3);
    } //for

    int     tempval;        //温度
    char    data_read[6];   //i2cバッファー
    int     n10;            //10の桁
    uint8_t b[6];           //バッファー

    //無限ループ
    while (1) {
        //液晶のクリア
        HAL_I2C_Master_Transmit(&hi2c1, ADDR_LCD, INIT_cls, 2, 3000);
        HAL_Delay(3);

        //温度センサーの初期化
        //set address 0
        HAL_I2C_Master_Transmit(&hi2c1, ADDR, (uint8_t *)"\000", 1, 3000); //addres 0
        HAL_Delay(1);

        //温度の読み込み
        // Read temperature register
        HAL_I2C_Master_Receive(&hi2c1, ADDR, b, 1, 3000);

        //温度の保存
        // Calculate temperature value in Celcius
        tempval =  b[0];

        //tempval = 12; //debug

        //計算
        // Calculation temp
        //10の割り算 0から1028までは、正しい。主に0から999 ((n*205)>>11)
        n10     = (tempval*205)>>11;      //10の桁 tempval/10
        tempval = tempval - ( n10 * 10 ); //1の桁  tempval%10

        //液晶に出力 xなぜか連続送信するとバグる為に個別送信
        // Display result
        data_read[0] = '0' + n10;
        data_read[1] = '0' + tempval;
        data_read[2] = 0;
        for(int ii=0; ii < 2 ; ii++) {
            b[0]='@';
            b[1]=data_read[ii];
            HAL_I2C_Master_Transmit(&hi2c1, ADDR_LCD, b,  2, 3000);
            HAL_Delay(1);
        }//for

        //1秒待つ
        HAL_Delay(1000);
    }//while
}//main





```





いろいろ直す前


```c++



#include "mbed.h"

#define ADDR        ((0x48)<<1) //  address 5851
//#define ADDR        (0x39<<1)   //  address 751
#define ADDR_LCD    (0x7C)      //  address

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

I2C_HandleTypeDef hi2c1;

//I2Cの初期化
void I2C_INIT1()
{
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};

    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    __HAL_RCC_I2C1_CLK_ENABLE();


    //I2C_HandleTypeDef hi2c1;

    hi2c1.Instance = I2C1;
    hi2c1.Init.Timing = 0x00000708;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    HAL_I2C_Init(&hi2c1);

    HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE);

    HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0);

}//I2C_INIT1

//液晶の初期化の文字列
uint8_t INIT_com[]= {
    0x0,0x38,
    0x0,0x39,
    0x0,0x4,
    0x0,0x14,
    0x0,0x70,
    0x0,0x56,
    0x0,0x6C,
    0x0,0x38,
    0x0,0xC,
    0x0,0x1,
    0x40,0x41
};

//画面のクリア
uint8_t INIT_cls[]= {0x0,0x1};

//メイン関数
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);

    //I2Cの初期化
    I2C_INIT1();

    //液晶の初期化
    wait_ms(200);
    for(int ii=0; ii<11; ii++) {
        HAL_I2C_Master_Transmit(&hi2c1, ADDR_LCD, &INIT_com[ii*2], 2, 3000);
        wait_ms(3);
    } //for

    int     tempval;        //温度
    char    data_read[6];   //i2cバッファー
    int     n10;            //10の桁
    uint8_t b[6];           //バッファー

    //無限ループ
    while (1) {
        //液晶のクリア
        HAL_I2C_Master_Transmit(&hi2c1, ADDR_LCD, INIT_cls, 2, 3000);
        wait_ms(3);

        //温度センサーの初期化
        //set address 0
        b[0]=0;
        HAL_I2C_Master_Transmit(&hi2c1, ADDR, b, 2, 3000); //addres 0

        //温度の読み込み
        // Read temperature register
        HAL_I2C_Master_Receive(&hi2c1, ADDR, b, 1, 3000);

        //温度の保存
        // Calculate temperature value in Celcius
        tempval =  b[0];

        //tempval = 12; //debug

        //計算
        // Calculation temp
        n10 = DVI10(tempval);             //10の桁
        tempval = tempval - ( n10 * 10 ); //1の桁

        //液晶に出力 xなぜか連続送信するとバグる為に個別送信
        // Display result
        data_read[0] = '0' + n10;
        data_read[1] = '0' + tempval;
        data_read[2] = 0;
        for(int ii=0; ii< 2 ; ii++) {
            b[0]='@';
            b[1]=data_read[ii];
            HAL_I2C_Master_Transmit(&hi2c1, ADDR_LCD, b,  2, 3000);
            wait_ms(1);
        }//for

        //1秒待つ
        wait_ms(1000);
    }//while
}//main



```