STM32 graduation design MCU AB32VG1 indoor environment temperature and humidity detection system

Article directory

  • 0 Introduction
  • 1 Project introduction
  • 2 Hardware Description
    • 2.1 AB32VG1 MCU
    • 2.2 DHT22 digital temperature and humidity sensor
  • 3 code implementation
  • 4 Realize the effect

Introduction to 0

Hi, everyone, the senior will introduce a single-chip microcomputer project to you today

Single-chip microcomputer-based indoor environment temperature and humidity detection system

You can use it for course design or graduation design

Guidance on topic selection, project sharing:

https://gitee.com/yaa-dc/warehouse-1/blob/master/iot/README.md

1 Project introduction

This design is based on the AB32VG1 development board of Zhongke Lanxun. The indoor environment is detected by DHT22. When the temperature or humidity is higher than or lower than the set value, an alarm will be issued and the current indoor temperature value will be displayed on the screen.

It is only a small function developed by the graduate school, and generally cannot be used as a graduation project

2 Hardware Description

2.1 AB32VG1 microcontroller

The main frequency of AB32VG1 is 120M, on-chip integrated RAM 192K, Flash 4Mbit, ADC, PWM, USB, UART, IIC and other resources. Provide SDK, complete drivers, support RT-Thread Studio to develop applications, configure the system graphically, open peripherals with one key, use software packages with one key, and powerful automatic code editing assistance.

2.2 DHT22 digital temperature and humidity sensor

DHT22 digital temperature and humidity sensor is a temperature and humidity composite sensor with calibrated digital signal output. It applies special digital module acquisition technology and temperature and humidity sensing technology to ensure that the product has extremely high reliability and excellent long-term stability. DHT11 is a temperature and humidity sensor. Its measurement accuracy is: humidity ±5%RH, temperature ±2°C, range: humidity 20-90%RH, temperature 0~50°C, sampling period greater than or equal to 1 second/time. The sensor includes a resistive humidity sensing element and an NTC temperature measuring element, and is connected to a high-performance 8-bit single-chip microcomputer phase. The advantages of DHT11 are: high quality, fast response, strong anti-interference ability, high cost performance, small size, low power consumption, etc.

3 code implementation

#include <board.h>

#include "dhtxx.h"



#define DBG_TAG "sensor.asair.dhtxx"

#ifdef PKG_USING_DHTXX_DEBUG

#define DBG_LVL DBG_LOG

#else

#define DBG_LVL DBG_ERROR

#endif

#include <rtdbg.h>



/* timing */

#define DHT1x_BEGIN_TIME 20 /* ms */

#define DHT2x_BEGIN_TIME 1 /* ms */

#define DHTxx_PULL_TIME 30 /* us */

#define DHTxx_REPLY_TIME 100 /* us */

#define MEASURE_TIME 40 /* us */



/**

 * This function will split a number into two parts according to times.

 *

 * @param num the number will be split

 * @param integer the integer part

 * @param decimal the decimal part

 * @param times how many times of the real number (you should use 10 in this case)

 *

 * @return 0 if num is positive, 1 if num is negative

 */

int split_int(const int num, int *integer, int *decimal, const rt_uint32_t times)

{<!-- -->

    int flag = 0;

    if (num < 0) flag = 1;



    int anum = num<0 ? -num : num;

    *integer = anum / times;

    *decimal = anum % times;



    return flag;

}



/**

 * This function will convert temperature in degree Celsius to Kelvin.

 *

 * @param c the temperature indicated by degree Celsius

 *

 * @return the result

 */

float convert_c2k(float c)

{<!-- -->

    return c + 273.15;

}



/**

 * This function will convert temperature in degree Celsius to Fahrenheit.

 *

 * @param c the temperature indicated by degree Celsius

 *

 * @return the result

 */

float convert_c2f(float c)

{<!-- -->

    return c * 1.8 + 32;

}



/**

 * This function will convert temperature in degree Fahrenheit to Celsius.

 *

 * @param f the temperature indicated by degree Fahrenheit

 *

 * @return the result

 */

float convert_f2c(float f)

{<!-- -->

    return (f - 32) * 0.55555;

}



/**

 * This function will read a bit from sensor.

 *

 * @param pin the pin of Dout

 *

 * @return the bit value

 */

static uint8_t dht_read_bit(const rt_base_t pin)

{<!-- -->

    uint8_t retry = 0;



    while(rt_pin_read(pin) & amp; & amp; retry < DHTxx_REPLY_TIME)

    {<!-- -->

        retry ++ ;

        rt_hw_us_delay(1);

    }



    retry = 0;

    while(!rt_pin_read(pin) & amp; & amp; retry < DHTxx_REPLY_TIME)

    {<!-- -->

        retry ++ ;

        rt_hw_us_delay(1);

    }



    rt_hw_us_delay(MEASURE_TIME);

    

    return rt_pin_read(pin);

}



/**

 * This function will read a byte from sensor.

 *

 * @param pin the pin of Dout

 *

 * @return the byte

 */

static uint8_t dht_read_byte(const rt_base_t pin)

{<!-- -->

    uint8_t i, byte = 0;



    for(i=0; i<8; i ++ )

    {<!-- -->

        byte <<= 1;

        byte |= dht_read_bit(pin);

    }



    return byte;

}



/**

 * This function will read and update data array.

 *

 * @param dev the device to be operated

 *

 * @return RT_TRUE if read successfully, otherwise return RT_FALSE.

 */

rt_bool_t dht_read(dht_device_t dev)

{<!-- -->

    RT_ASSERT(dev);



    uint8_t i, retry = 0, sum = 0;



#ifdef PKG_USING_DHTXX_INTERRUPT_DISABLE

    rt_base_t level;

#endif



    /* Reset data buffer */

    rt_memset(dev->data, 0, DHT_DATA_SIZE);



    /* MCU request sampling */

    rt_pin_mode(dev->pin, PIN_MODE_OUTPUT);

    rt_pin_write(dev->pin, PIN_LOW);



    if (dev->type == DHT11 || dev->type == DHT12) {<!-- -->

        rt_thread_mdelay(DHT1x_BEGIN_TIME); /* Tbe */

    } else {<!-- -->

        rt_thread_mdelay(DHT2x_BEGIN_TIME);

    }



#ifdef PKG_USING_DHTXX_INTERRUPT_DISABLE

    level = rt_hw_interrupt_disable();

#endif



    rt_pin_mode(dev->pin, PIN_MODE_INPUT_PULLUP);

    rt_hw_us_delay(DHTxx_PULL_TIME); /* Tgo */



    /* Waiting for sensor reply */

    while (rt_pin_read(dev->pin) & amp; & amp; retry < DHTxx_REPLY_TIME)

    {<!-- -->

        retry ++ ;

        rt_hw_us_delay(1); /* Trel */

    }

    if(retry >= DHTxx_REPLY_TIME) return RT_FALSE;



    retry = 0;

    while (!rt_pin_read(dev->pin) & amp; & amp; retry < DHTxx_REPLY_TIME)

    {<!-- -->

        retry ++ ;

        rt_hw_us_delay(1); /* Treh */

    };

    if(retry >= DHTxx_REPLY_TIME) return RT_FALSE;



    /* Read data */

    for(i=0; i<DHT_DATA_SIZE; i ++ )

    {<!-- -->

        dev->data[i] = dht_read_byte(dev->pin);

    }



#ifdef PKG_USING_DHTXX_INTERRUPT_DISABLE

    rt_hw_interrupt_enable(level);

#endif



    /* Checksum */

    for(i=0; i<DHT_DATA_SIZE-1; i ++ )

    {<!-- -->

        sum + = dev->data[i];

    }

    if(sum != dev->data[4]) return RT_FALSE;



    return RT_TRUE;

}



/**

 * This function will get the humidity from dhtxx sensor.

 *

 * @param dev the device to be operated

 *

 * @return the humidity value

 */

rt_int32_t dht_get_humidity(dht_device_t const dev)

{<!-- -->

    RT_ASSERT(dev);



    rt_int32_t humi = 0;



    switch(dev->type)

    {<!-- -->

    case DHT11:

    case DHT12:

        humi = dev->data[0] * 10 + dev->data[1];

        break;

    case DHT21:

    case DHT22:

        humi = (dev->data[0] << 8) + dev->data[1];

        break;

    default:

        break;

    }



    return humi;

}



/**

 * This function will get the temperature from dhtxx sensor.

 *

 * @param dev the device to be operated

 *

 * @return the temperature value

 */

rt_int32_t dht_get_temperature(dht_device_t const dev)

{<!-- -->

    RT_ASSERT(dev);



    rt_int32_t temp = 0;



    switch(dev->type)

    {<!-- -->

    case DHT11:

    case DHT12:

        temp = dev->data[2] * 10 + (dev->data[3] & 0x7f);

        if(dev->data[3] & amp; 0x80) {<!-- -->

            temp = -temp;

        }

        break;

    case DHT21:

    case DHT22:

        temp = ((dev->data[2] & amp; 0x7f) << 8) + dev->data[3];

        if(dev->data[2] & amp; 0x80) {<!-- -->

            temp = -temp;

        }

        break;

    default:

        break;

    }



    return temp;

}



/**

 * This function will init dhtxx sensor device.

 *

 * @param dev the device to init

 * @param pin the pin of Dout

 *

 * @return the device handler

 */

rt_err_t dht_init(struct dht_device *dev, const rt_base_t pin)

{<!-- -->

    if(dev == NULL)

        return -RT_ERROR;



    dev->type = DHT_TYPE;

    dev->pin = pin;



    rt_memset(dev->data, 0, DHT_DATA_SIZE);

    rt_pin_mode(dev->pin, PIN_MODE_INPUT_PULLUP);

    

    return RT_EOK;

}



dht_device_t dht_create(const rt_base_t pin)

{<!-- -->

    dht_device_t dev;



    dev = rt_calloc(1, sizeof(struct dht_device));

    if (dev == RT_NULL)

    {<!-- -->

        LOG_E("Can't allocate memory for dhtxx device");

        return RT_NULL;

    }



    dev->type = DHT_TYPE;

    dev->pin = pin;



    rt_memset(dev->data, 0, DHT_DATA_SIZE);

    rt_pin_mode(dev->pin, PIN_MODE_INPUT_PULLUP);



    return dev;

}



void dht_delete(dht_device_t dev)

{<!-- -->

    if (dev)

        rt_free(dev);

}



#include <rtthread.h>

#include <rtdevice.h>

#include <board.h>

#include "dhtxx.h"



#define DATA_PIN PKG_USING_DHTXX_SAMPLE_PIN



/* cat_dhtxx sensor data by dynamic */

static void cat_dhtxx(void)

{<!-- -->

    dht_device_t sensor = dht_create(DATA_PIN);



    if(dht_read(sensor)) {<!-- -->



        rt_int32_t temp = dht_get_temperature(sensor);

        rt_int32_t humi = dht_get_humidity(sensor);



        rt_kprintf("Temp: %d, Humi: %d\\
", temp, humi);

    }

    else {<!-- -->

        rt_kprintf("Read dht sensor failed.\\
");

    }



    dht_delete(sensor);

}



#ifdef FINSH_USING_MSH

MSH_CMD_EXPORT(cat_dhtxx, read dhtxx humidity and temperature);

#endif





#ifndef __DHTXX_H__

#define __DHTXX_H__



#include <rtthread.h>

#include <rtdevice.h>

#include <sensor.h>



#define DHTLIB_VERSION "0.9.0"

#define DHT_DATA_SIZE 5



/* sensor model type */

#define DHT11 0

#define DHT12 1

#define DHT21 2

#define DHT22 3

#define AM2301 DHT21

#define AM2302 DHT22

#define AM2320 DHT22



#if defined(PKG_USING_DHTXX_TYPE_DHT11)

#define DHT_TYPE DHT11

#elif defined(PKG_USING_DHTXX_TYPE_DHT12)

#define DHT_TYPE DHT12

#elif defined(PKG_USING_DHTXX_TYPE_DHT21)

#define DHT_TYPE DHT21

#elif defined(PKG_USING_DHTXX_TYPE_DHT22)

#define DHT_TYPE DHT22

#endif





struct dht_device

{<!-- -->

    rt_base_t pin;

    rt_uint8_t type;

    rt_uint8_t data[DHT_DATA_SIZE];

    rt_mutex_t lock;

};

typedef struct dht_device *dht_device_t;



dht_device_t dht_create(const rt_base_t pin);

void dht_delete(dht_device_t dev);



rt_err_t dht_init(struct dht_device *dev, const rt_base_t pin);

rt_bool_t dht_read(dht_device_t dev);

rt_int32_t dht_get_humidity(dht_device_t dev);

rt_int32_t dht_get_temperature(dht_device_t dev);



float convert_c2k(float c);

float convert_c2f(float c);

float convert_f2c(float f);



rt_int32_t split_int(const rt_int32_t num, rt_int32_t *integer,

                     rt_int32_t *decimal, const rt_uint32_t times);



rt_err_t rt_hw_dht_init(const char *name, struct rt_sensor_config *cfg);



#endif /* __DHTXX_H__ */

#include "oled.h"

#include "oledfont.h"



u8 OLED_GRAM[144][8];



struct OLED_sss

{<!-- -->

  uint8_t OLED_SCLK;

  uint8_t OLED_SDIN;

  uint8_t OLED_RST;

  uint8_t OLED_DC;

  uint8_t OLED_CS;

};

struct OLED_sss oled_ccc;



//Invert function

void OLED_ColorTurn(u8 i)

{<!-- -->

  if(i==0)

    {<!-- -->

      OLED_WR_Byte(0xA6,OLED_CMD);//normal display

    }

  if(i==1)

    {<!-- -->

      OLED_WR_Byte(0xA7,OLED_CMD);//inverse color display

    }

}



//rotate the screen 180 degrees

void OLED_DisplayTurn(u8 i)

{<!-- -->

  if(i==0)

    {<!-- -->

      OLED_WR_Byte(0xC8,OLED_CMD);//normal display

      OLED_WR_Byte(0xA1, OLED_CMD);

    }

  if(i==1)

    {<!-- -->

      OLED_WR_Byte(0xC0,OLED_CMD);//Reverse display

      OLED_WR_Byte(0xA0, OLED_CMD);

    }

}



void OLED_WR_Byte(u8 dat, u8 cmd)

{<!-- -->

  u8 i;

  if (cmd)

    OLED_DC_Set();

  else

    OLED_DC_Clr();

  OLED_CS_Clr();

  for(i=0;i<8;i ++ )

  {<!-- -->

    OLED_SCLK_Clr();

    if(dat &0x80)

       OLED_SDIN_Set();

    else

       OLED_SDIN_Clr();

    OLED_SCLK_Set();

    dat<<=1;

  }

  OLED_CS_Set();

  OLED_DC_Set();

}



//Enable OLED display

void OLED_DisPlay_On(void)

{<!-- -->

  OLED_WR_Byte(0x8D,OLED_CMD);//charge pump enable

  OLED_WR_Byte(0x14,OLED_CMD);//Enable the charge pump

  OLED_WR_Byte(0xAF,OLED_CMD);//Light up the screen

}



//Turn off the OLED display

void OLED_DisPlay_Off(void)

{<!-- -->

  OLED_WR_Byte(0x8D,OLED_CMD);//charge pump enable

  OLED_WR_Byte(0x10,OLED_CMD);//Turn off the charge pump

  OLED_WR_Byte(0xAF,OLED_CMD);//Close the screen

}



//Update video memory to OLED

void OLED_Refresh(void)

{<!-- -->

  u8 i,n;

  for(i=0;i<8;i ++ )

  {<!-- -->

     OLED_WR_Byte(0xb0 + i,OLED_CMD); //Set the row start address

     OLED_WR_Byte(0x00,OLED_CMD); //Set the low column start address

     OLED_WR_Byte(0x10,OLED_CMD); //Set the high column start address

     for(n=0;n<128;n ++ )

     OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);

  }

}

// clear screen function

void OLED_Clear(void)

{<!-- -->

  u8 i,n;

  for(i=0;i<8;i ++ )

  {<!-- -->

     for(n=0;n<128;n ++ )

      {<!-- -->

       OLED_GRAM[n][i]=0;//clear all data

      }

  }

  OLED_Refresh();//Update display

}



// draw dots

//x:0~127

//y:0~63

void OLED_DrawPoint(u8 x,u8 y)

{<!-- -->

  u8 i,m,n;

  i=y/8;

  m=y%8;

  n=1<<m;

  OLED_GRAM[x][i]|=n;

}



// clear a point

//x:0~127

//y:0~63

void OLED_ClearPoint(u8 x,u8 y)

{<!-- -->

  u8 i,m,n;

  i=y/8;

  m=y%8;

  n=1<<m;

  OLED_GRAM[x][i]=~OLED_GRAM[x][i];

  OLED_GRAM[x][i]|=n;

  OLED_GRAM[x][i]=~OLED_GRAM[x][i];

}





// draw line

//x:0~128

//y:0~64

void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2)

{<!-- -->

  u8 i,k,k1,k2,y0;

  if((x1<0)||(x2>128)||(y1<0)||(y2>64)||(x1>x2)||(y1>y2)) return;

  if(x1==x2) // draw a vertical line

  {<!-- -->

      for(i=0;i<(y2-y1);i ++ )

      {<!-- -->

        OLED_DrawPoint(x1,y1 + i);

      }

  }

  else if(y1==y2) //Draw a horizontal line

  {<!-- -->

      for(i=0;i<(x2-x1);i ++ )

      {<!-- -->

        OLED_DrawPoint(x1 + i,y1);

      }

  }

  else // draw a slash

  {<!-- -->

    k1=y2-y1;

    k2=x2-x1;

    k=k1*10/k2;

    for(i=0;i<(x2-x1);i ++ )

      {<!-- -->

        OLED_DrawPoint(x1 + i,y1 + i*k/10);

      }

  }

}

//x,y: coordinates of the center of the circle

//r: the radius of the circle

void OLED_DrawCircle(u8 x,u8 y,u8 r)

{<!-- -->

  int a, b, num;

    a = 0;

    b = r;

    while(2 * b * b >= r * r)

    {<!-- -->

        OLED_DrawPoint(x + a, y - b);

        OLED_DrawPoint(x - a, y - b);

        OLED_DrawPoint(x - a, y + b);

        OLED_DrawPoint(x + a, y + b);



        OLED_DrawPoint(x + b, y + a);

        OLED_DrawPoint(x + b, y - a);

        OLED_DrawPoint(x - b, y - a);

        OLED_DrawPoint(x - b, y + a);



        a + + ;

        num = (a * a + b * b) - r*r;//Calculate the distance between the drawn point and the center of the circle

        if(num > 0)

        {<!-- -->

            b--;

            a--;

        }

    }

}



//Display a character at the specified position, including some characters

//x:0~127

//y:0~63

//size: select font 12/16/24

//Moulding method column-by-column

void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1)

{<!-- -->

  u8 i,m,temp,size2,chr1;

  u8 y0=y;

  size2=(size1/8 + ((size1%8)?1:0))*(size1/2); //Get the number of bytes occupied by one character of the font corresponding to the lattice set

  chr1=chr-' '; // Calculate the offset value

  for(i=0;i<size2;i ++ )

  {<!-- -->

    if(size1==12)

        {<!-- -->temp=asc2_1206[chr1][i];} //call 1206 font

    else if(size1==16)

        {<!-- -->temp=asc2_1608[chr1][i];} //call 1608 font

    else if(size1==24)

        {<!-- -->temp=asc2_2412[chr1][i];} //call 2412 font

    else return;

        for(m=0;m<8;m ++ ) //write data

        {<!-- -->

          if(temp & amp;0x80)OLED_DrawPoint(x,y);

          else OLED_ClearPoint(x,y);

          temp<<=1;

          y + + ;

          if((y-y0)==size1)

          {<!-- -->

            y=y0;

            x + + ;

            break;

          }

        }

  }

}





//display string

//x,y: starting point coordinates

//size1: font size

//*chr: string starting address

void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1)

{<!-- -->

  while((*chr>=' ') & amp; & amp;(*chr<='~'))//Judge whether it is an illegal character!

  {<!-- -->

    OLED_ShowChar(x,y,*chr,size1);

    x + =size1/2;

    if(x>128-size1) //new line

    {<!-- -->

      x=0;

      y + =2;

    }

    chr++;

  }

}



//m^n

u32 OLED_Pow(u8 m,u8 n)

{<!-- -->

  u32 result=1;

  while(n--)

  {<!-- -->

    result*=m;

  }

  return result;

}



show 2 numbers

x,y : starting point coordinates

len : number of digits

size: font size

void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1)

{<!-- -->

  u8 t, temp;

  for(t=0;t<len;t++)

  {<!-- -->

    temp=(num/OLED_Pow(10,len-t-1)) ;

      if(temp==0)

      {<!-- -->

        OLED_ShowChar(x + (size1/2)*t,y,'0',size1);

      }

      else

      {<!-- -->

        OLED_ShowChar(x + (size1/2)*t,y,temp + '0',size1);

      }

  }

}



//display Chinese characters

//x,y: starting point coordinates

//num: the serial number corresponding to the Chinese character

//Moulding mode column and row

void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1)

{<!-- -->

  u8 i,m,n=0,temp,chr1;

  u8 x0=x,y0=y;

  u8 size3=size1/8;

  while(size3--)

  {<!-- -->

    chr1=num*size1/8 + n;

    n + + ;

      for(i=0;i<size1;i + + )

      {<!-- -->

        if(size1==16)

            {<!-- -->temp=Hzk1[chr1][i];}//call 16*16 font

        else if(size1==24)

            {<!-- -->temp=Hzk2[chr1][i];}//call 24*24 font

        else if(size1==32)

            {<!-- -->temp=Hzk3[chr1][i];}//call 32*32 font

        else if(size1==64)

            {<!-- -->temp=Hzk4[chr1][i];}//call 64*64 font

        else return;



            for(m=0;m<8;m++)

              {<!-- -->

                if(temp &0x01)OLED_DrawPoint(x,y);

                else OLED_ClearPoint(x,y);

                temp>>=1;

                y + + ;

              }

              x + + ;

              if((x-x0)==size1)

              {<!-- -->x=x0;y0=y0 + 8;}

              y=y0;

       }

  }

}



//num displays the number of Chinese characters

//space The interval displayed each time

void OLED_ScrollDisplay(u8 num,u8 space)

{<!-- -->

  u8 i,n,t=0,m=0,r;

  while(1)

  {<!-- -->

    if(m==0)

    {<!-- -->

      OLED_ShowChinese(128,24,t,16); //write a Chinese character and save it in OLED_GRAM[][] array

      t + + ;

    }

    if(t==num)

      {<!-- -->

        for(r=0;r<16*space;r + + ) //display interval

         {<!-- -->

          for(i=0;i<144;i ++ )

            {<!-- -->

              for(n=0;n<8;n++)

              {<!-- -->

                OLED_GRAM[i-1][n]=OLED_GRAM[i][n];

              }

            }

           OLED_Refresh();

         }

        t=0;

      }

    m++;

    if(m==16){<!-- -->m=0;}

    for(i=0;i<144;i ++ ) // realize left shift

    {<!-- -->

      for(n=0;n<8;n++)

      {<!-- -->

        OLED_GRAM[i-1][n]=OLED_GRAM[i][n];

      }

    }

    OLED_Refresh();

  }

}



//Configure the starting position of writing data

void OLED_WR_BP(u8 x, u8 y)

{<!-- -->

  OLED_WR_Byte(0xb0 + y,OLED_CMD);//Set the row start address

  OLED_WR_Byte(((x & amp;0xf0)>>4)|0x10,OLED_CMD);

  OLED_WR_Byte((x & amp;0x0f),OLED_CMD);

}



//x0, y0: starting point coordinates

//x1, y1: end point coordinates

//BMP[]: image array to be written

void OLED_ShowPicture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[])

{<!-- -->

  u32 j=0;

  u8 x=0,y=0;

  if(y%8==0)y=0;

  else y + =1;

  for(y=y0;y<y1;y++)

   {<!-- -->

     OLED_WR_BP(x0,y);

     for(x=x0;x<x1;x + + )

     {<!-- -->

       OLED_WR_Byte(BMP[j],OLED_DATA);

       j + + ;

     }

   }

}



//OLED initialization

void OLED_Init(void)

{<!-- -->

  oled_ccc.OLED_SCLK = rt_pin_get("PA.3");

  oled_ccc.OLED_SDIN = rt_pin_get("PA.4");

  oled_ccc.OLED_RST = rt_pin_get("PF.1");

  oled_ccc.OLED_DC = rt_pin_get("PB.0");

  oled_ccc.OLED_CS = rt_pin_get("PA.5");



  rt_pin_mode(oled_ccc.OLED_SCLK, PIN_MODE_OUTPUT);

  rt_pin_mode(oled_ccc.OLED_SDIN, PIN_MODE_OUTPUT);

  rt_pin_mode(oled_ccc.OLED_RST, PIN_MODE_OUTPUT);

  rt_pin_mode(oled_ccc.OLED_DC, PIN_MODE_OUTPUT);

  rt_pin_mode(oled_ccc.OLED_CS, PIN_MODE_OUTPUT);



  rt_pin_write(oled_ccc. OLED_SCLK, PIN_HIGH);

  rt_pin_write(oled_ccc. OLED_SDIN, PIN_HIGH);

  rt_pin_write(oled_ccc. OLED_RST, PIN_HIGH);

  rt_pin_write(oled_ccc. OLED_DC, PIN_HIGH);

  rt_pin_write(oled_ccc.OLED_CS, PIN_HIGH);



  OLED_RST_Clr();//reset

  rt_thread_mdelay(200);

  OLED_RST_Set();



  OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel

  OLED_WR_Byte(0x00,OLED_CMD);//---set low column address

  OLED_WR_Byte(0x10,OLED_CMD);//---set high column address

  OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)

  OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register

  OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness

  OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0 reverse left and right 0xa1 normal

  OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0 reverse up and down 0xc8 normal

  OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display

  OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)

  OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty

  OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)

  OLED_WR_Byte(0x00,OLED_CMD);//-not offset

  OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency

  OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec

  OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period

  OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & amp; Discharge as 1 Clock

  OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration

  OLED_WR_Byte(0x12,OLED_CMD);

  OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh

  OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level

  OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)

  OLED_WR_Byte(0x02,OLED_CMD);//

  OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable

  OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable

  OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)

  OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)

  OLED_WR_Byte(0xAF, OLED_CMD);

  OLED_Clear();

}


4 Realize the effect

Guidance on topic selection, project sharing:

https://gitee.com/yaa-dc/warehouse-1/blob/master/iot/README.md