黄土马家

【ART-Pi】RTT air quality monitoring-525354A

 
Overview

                        Environmental monitoring device based on RT-Thread

1. Activity introduction

      ART-Pi is a DIY open source hardware with extended functions specially designed for embedded software engineers and open source makers after half a year of careful preparation by the RT-Thread team. Insert image description here ART-Pi official websiteOfficial website: ART-Pi (gitee.io)

ART-Pi SDK repository GitHub main repository: RT-Thread-Studio/sdk-bsp-stm32h750-realthread-artpi (github.com)

Onboard resources:
  • STM32H750XBH6
  • On-board ST-LINK/V2.1
  • USB OTG with Type-C connector
  • SDIO TF Card slot
  • SDIO WIFI:AP6212
  • HDC UART BuleTooth:AP6212
  • RGB888 FPC connector
  • 32-Mbyte SDRAM
  • 16-Mbytes SPI FLASH
  • 8-Mbytes QSPI FLASH
  • D1(blue) for 3.3v power-on
  • Two user LEDs:D2 (blue),D2 (red)
  • Two ST-LINK LEDs: D4(blue),D4 (red)
  • Two push-buttons (user and reset)
Extension ports:
  • 4-way UART(LPUART)
  • 3-way SPI
  • 2-way hardware iic
  • 1 way USB-FS
  • 1 way ETH
  • 1 way SAI
  • 1 channel DCMI
  • 2-way CANFD
  • More than 5 channels of ADC (supports score checking input ADC)
  • More than 15 channels of PWM (supports high-precision timer HRTIM)
Driver support:
  • UART
  • SPI
  • SDMMC
  • CAN
  • QSPI
  • ADC
  • PWM
  • DCMI
  • SAI
  • LTDC
  • USB
  • ETH
  • SDRAM
  • HRTIM
  • I2C Insert image description here       is a long-admired development board, and ART-Pi can be used as a must-have product for learning RT-Thread. According to Lichuang's activities, it is necessary to design a development board based on ART-Pi. I happened to have an idle TFT screen on hand, and the ART-Pi has an RGB interface, but I wanted to make a screen driver based on the IO port simulation of 8080 timing, so I bought a 2.8-inch TFT screen at Lichuang Mall. I have to say that after watching the blue screen for a long time, this black PCB screen is particularly beautiful. With the black PCB board, the B grid is full.

    2. Equipment introduction

          First of all, for the purpose of driving the TFT screen, then add a temperature sensor, MQ2 gas sensor and photoresistor to do an environmental monitoring. This is more suitable for in-car monitoring. The MQ2 gas sensor can monitor a variety of harmful gases. Actual pictures are here       The real thing is as shown in the picture above. The PCB is not too large. It is designed based on the ART-Pi base plate. The pin headers are all Pin to Pin connections because the screen needs to be installed on it, but the photoresistor and MQ2 gas detection module must be external. The only option here is to put half of the screen outside. Let’s see the effect in the picture. It looks good outside. The B boxes are full of O(∩_∩)O as mentioned above, haha~.

    2.1 Main functions

          Currently, non-16 continuous IO ports are used to simulate 8080 timing, and the 2.8-inch TFT screen is driven through the 8080 protocol. This driver transplant is really laborious. The information on the Internet is all 16 consecutive pins, which can be directly operated by bits. Here is the information Open it up for future reference. The functions currently implemented include temperature and humidity monitoring of DHT11, harmful gas detection of MQ2 gas detection module and light monitoring of photoresistor.

    3. Hardware introduction

          The hardware part is actually quite simple. Of course, the protagonist is our Art-Pi. 16 IO ports are randomly selected as the 8080 protocol pins of the display. At that time, I did not check the ART-Pi manual specifically to connect the 35 37 microphone pins. , so these two pins are currently shared with other peripherals, but I have not enabled other peripherals, so there is no impact. In the future, before drawing the board, you must understand the pins clearly before designing.

Insert image description here       In addition to the 8080 bus, the board also has three LED lights, which are used as alarm lights and normal working status lights. I have to say that this violet color SMD LED is really beautiful. In the past, they were all red and green. This time I came into contact with this If you choose a more slutty color, you will have trouble giving gifts to girls in the future O(∩_∩)O haha~. Insert image description here       The interface of the display screen is simple and crude here. Although these IO ports do not support FMC, in order to facilitate labeling, the network label of FMC is still used. This also makes it easier to write the 8080 protocol for control later. Insert image description here       In order to facilitate pin assignment, I specifically checked the schematic diagram of ART-Pi and marked all the IO ports of the 8080 protocol to facilitate transplantation on RT-Thread. Insert image description here       Here is the junior sensor module,

      1. DHT11 is a temperature and humidity sensor with calibrated digital signal output. Its precision humidity is ±5%RH, temperature is ±2℃, measuring range humidity is 5-95%RH, and temperature is 0~+50℃. DHT11 digital temperature and humidity sensor is a temperature and humidity composite sensor with calibrated digital signal output. It applies dedicated digital module acquisition technology and temperature and humidity sensing technology to ensure that the product has extremely high reliability and excellent long-term stability. The sensor includes a resistive humidity sensing element and an NTC temperature measuring element, and is connected to a high-performance 8-bit microcontroller. Therefore, this product has the advantages of excellent quality, ultra-fast response, strong anti-interference ability, and extremely cost-effective. Each DHT11 sensor is calibrated in an extremely accurate humidity calibration chamber. The calibration coefficients are stored in the OTP memory in the form of a program, and these calibration coefficients are called inside the sensor during the processing of the detection signal. The single-wire serial interface makes system integration easy and fast. The ultra-small size and extremely low power consumption make it the best choice for this type of application in harsh applications. The product is a 4-pin single-row pin package and is easy to connect.
      2. The gas-sensitive material used by the MQ-2 gas sensor is tin dioxide (SnO2) with low conductivity in clean air. When there is combustible gas in the environment where the sensor is located, the conductivity of the sensor increases as the concentration of combustible gas in the air increases. A simple circuit can be used to convert changes in conductivity into an output signal corresponding to that gas concentration. The MQ-2 gas sensor can be used for gas leak detection in homes and factories. It is suitable for the detection of liquefied gas, butane, propane, methane, alcohol, hydrogen, smoke, etc. It is also ideal for the detection of natural gas and other flammable vapors. This sensor can detect a variety of flammable gases and is a low-cost sensor suitable for a variety of applications.
      3. Photoresistor is a special resistor made of semiconductor materials such as cadmium sulfide or cadmium selenide. Its working principle is based on the internal photoelectric effect. The stronger the light, the lower the resistance. As the light intensity increases, the resistance decreases rapidly, and the bright resistance can be as small as less than 1KΩ. The photoresistor is very sensitive to light. When there is no light, it is in a high resistance state, and the dark resistance can generally reach 1.5MΩ. The special properties of photoresistor will be widely used with the development of science and technology.

Insert image description here        These three sensors are used here as the main monitoring devices.

4. Software sharing

First, I transplanted the 8080 protocol bus into ART-Pi. Because of the scattered IO ports, bitwise operations cannot be used and I can only use IO ports for operations.

1. First, initialize the GPIO you need to use
void ILI9341_GPIO_Config ()
{
                    /*初始化LCD的控制线*/

        rt_pin_mode(ILI9341_RD_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_WR_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_CS_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_DC_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_BK_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_RST_CLK,PIN_MODE_OUTPUT);

                    /*初始化LCD的数据线*/

        rt_pin_mode(ILI9341_D0_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D1_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D2_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D3_CLK,PIN_MODE_OUTPUT);

        rt_pin_mode(ILI9341_D4_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D5_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D6_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D7_CLK,PIN_MODE_OUTPUT);

        rt_pin_mode(ILI9341_D8_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D9_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D10_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D11_CLK,PIN_MODE_OUTPUT);

        rt_pin_mode(ILI9341_D12_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D13_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D14_CLK,PIN_MODE_OUTPUT);
        rt_pin_mode(ILI9341_D15_CLK,PIN_MODE_OUTPUT);

}
2. In fact, in the 8080 bus, there is a reading process and a writing process, so the output and output mode of the IO port need to be set. The IO port has been defined here, and the data processing is as follows. The variable input by DATAOUT is the data that needs to be sent. The data is directly processed one by one by bitwise AND and bit shifting, and the data is sent out.
void DATAOUT(unsigned int x)
{

    rt_pin_write(ILI9341_D0_CLK,(x>>0&0x0001));
    rt_pin_write(ILI9341_D1_CLK,(x>>1&0x0001));
    rt_pin_write(ILI9341_D2_CLK,(x>>2&0x0001));
    rt_pin_write(ILI9341_D3_CLK,(x>>3&0x0001));

    rt_pin_write(ILI9341_D4_CLK,(x>>4&0x0001));
    rt_pin_write(ILI9341_D5_CLK,(x>>5&0x0001));
    rt_pin_write(ILI9341_D6_CLK,(x>>6&0x0001));
    rt_pin_write(ILI9341_D7_CLK,(x>>7&0x0001));

    rt_pin_write(ILI9341_D8_CLK,(x>>8&0x0001));
    rt_pin_write(ILI9341_D9_CLK,(x>>9&0x0001));
    rt_pin_write(ILI9341_D10_CLK,(x>>10&0x0001));
    rt_pin_write(ILI9341_D11_CLK,(x>>11&0x0001));

    rt_pin_write(ILI9341_D12_CLK,(x>>12&0x0001));
    rt_pin_write(ILI9341_D13_CLK,(x>>13&0x0001));
    rt_pin_write(ILI9341_D14_CLK,(x>>14&0x0001));
    rt_pin_write(ILI9341_D15_CLK,(x>>15&0x0001));

}
3. The input mode is as follows:
uint16_t DATAIN(void)
{
    volatile uint16_t data = 0;

    data |= pin_read(ILI9341_D15_CLK);data <<= 1;
    data |= pin_read(ILI9341_D14_CLK);data <<= 1;
    data |= pin_read(ILI9341_D13_CLK);data <<= 1;
    data |= pin_read(ILI9341_D12_CLK);data <<= 1;
    data |= pin_read(ILI9341_D11_CLK);data <<= 1;
    data |= pin_read(ILI9341_D10_CLK);data <<= 1;
    data |= pin_read(ILI9341_D9_CLK);data <<= 1;
    data |= pin_read(ILI9341_D8_CLK);data <<= 1;
    data |= pin_read(ILI9341_D7_CLK);data <<= 1;
    data |= pin_read(ILI9341_D6_CLK);data <<= 1;
    data |= pin_read(ILI9341_D5_CLK);data <<= 1;
    data |= pin_read(ILI9341_D4_CLK);data <<= 1;
    data |= pin_read(ILI9341_D3_CLK);data <<= 1;
    data |= pin_read(ILI9341_D2_CLK);data <<= 1;
    data |= pin_read(ILI9341_D1_CLK);data <<= 1;
    data |= pin_read(ILI9341_D0_CLK);

    return data;
}
char  pin_read(rt_base_t     pin)
{
    if(rt_pin_read(pin)==0)
    {
        return 0;
    }

    else
        return 1;
}
4. Writing data and writing data functions is not difficult. In addition to controlling the IO ports of several signal bits, you can directly use the send data function written above to send data.
//写数据函数
//可以替代LCD_WR_DATAX宏,拿时间换空间.
//data:寄存器值
void LCD_WR_DATAX(uint16_t data)
{
    rt_pin_write(ILI9341_DC_CLK, PIN_HIGH);//开始片选
        //LCD_RS_SET;
    rt_pin_write(ILI9341_CS_CLK, PIN_LOW);//开始片选
        //LCD_CS_CLR;
    DATAOUT(data);//输出数据
        //DATAOUT(data);
    rt_pin_write(ILI9341_WR_CLK, PIN_LOW);//写入开始
        //LCD_WR_CLR;
    rt_pin_write(ILI9341_WR_CLK, PIN_HIGH);//写入结束
        //LCD_WR_SET;
    rt_pin_write(ILI9341_CS_CLK, PIN_HIGH);//结束片选
        //LCD_CS_SET;
}
5. Read data. The read data function is very troublesome. All IO ports need to be set to input mode here, and since they are not continuous IO ports, it is impossible to directly read the value of the PA register, for example, so only one protocol can be written here. Read the IO ports one by one and then use the above DATAIN function to spell each bit into a 16-bit binary number and convert it to hexadecimal for judgment.
//读LCD数据
//返回值:读到的值
uint16_t LCD_RD_DATA(void)
{
    uint16_t t;
    //设置为上拉输入模式
    rt_pin_mode(ILI9341_D0_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D1_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D2_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D3_CLK,PIN_MODE_INPUT_PULLUP);

    rt_pin_mode(ILI9341_D4_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D5_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D6_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D7_CLK,PIN_MODE_INPUT_PULLUP);

    rt_pin_mode(ILI9341_D8_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D9_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D10_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D11_CLK,PIN_MODE_INPUT_PULLUP);

    rt_pin_mode(ILI9341_D12_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D13_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D14_CLK,PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(ILI9341_D15_CLK,PIN_MODE_INPUT_PULLUP);

    DATAOUT(0X0000);

    rt_pin_write(ILI9341_DC_CLK, PIN_HIGH);
        //LCD_RS_SET;
    rt_pin_write(ILI9341_CS_CLK, PIN_LOW);
        //LCD_CS_CLR;
    rt_pin_write(ILI9341_RD_CLK, PIN_LOW);
    //读取数据(读寄存器时,并不需要读2次)
    //LCD_RD_CLR;

    if(lcddev.id==0X8989)
    {
        delay_us(20);//FOR 8989,延时2us
    }
    t=DATAIN();

    rt_pin_write(ILI9341_RD_CLK, PIN_HIGH);
        //LCD_RD_SET;
    rt_pin_write(ILI9341_CS_CLK, PIN_HIGH);
        //LCD_CS_SET;

    //设置为推挽输出模式
    rt_pin_mode(ILI9341_D0_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D1_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D2_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D3_CLK,PIN_MODE_OUTPUT);

    rt_pin_mode(ILI9341_D4_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D5_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D6_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D7_CLK,PIN_MODE_OUTPUT);

    rt_pin_mode(ILI9341_D8_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D9_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D10_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D11_CLK,PIN_MODE_OUTPUT);

    rt_pin_mode(ILI9341_D12_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D13_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D14_CLK,PIN_MODE_OUTPUT);
    rt_pin_mode(ILI9341_D15_CLK,PIN_MODE_OUTPUT);

    DATAOUT(0XFFFF);

    return t;
}
6. Because the TFT driver chip I use is ILI9341, I made specific modifications to 9341 to complete the screen initialization operation.
void  LCD_Init()
{
    ILI9341_GPIO_Config();

    rt_pin_write(ILI9341_RST_CLK, PIN_HIGH);
    rt_pin_write(ILI9341_RST_CLK, PIN_LOW);
    rt_pin_write(ILI9341_RST_CLK, PIN_HIGH);

    rt_thread_mdelay(50);

    LCD_WriteReg(0x0000,0x0001);
    rt_thread_mdelay(50);
    lcddev.id = LCD_ReadReg(0x0000);
    printf(" LCD ID:%x
",lcddev.id); //打印LCD ID
    if(lcddev.id==0x9325)//9325
    {
        LCD_WriteReg(0x00E5,0x78F0);
        LCD_WriteReg(0x0001,0x0100);
        LCD_WriteReg(0x0002,0x0700);
        LCD_WriteReg(0x0003,0x1030);
        LCD_WriteReg(0x0004,0x0000);
        LCD_WriteReg(0x0008,0x0202);
        LCD_WriteReg(0x0009,0x0000);
        LCD_WriteReg(0x000A,0x0000);
        LCD_WriteReg(0x000C,0x0000);
        LCD_WriteReg(0x000D,0x0000);
        LCD_WriteReg(0x000F,0x0000);
        //power on sequence VGHVGL
        LCD_WriteReg(0x0010,0x0000);
        LCD_WriteReg(0x0011,0x0007);
        LCD_WriteReg(0x0012,0x0000);
        LCD_WriteReg(0x0013,0x0000);
        LCD_WriteReg(0x0007,0x0000);
        //vgh
        LCD_WriteReg(0x0010,0x1690);
        LCD_WriteReg(0x0011,0x0227);
        rt_thread_mdelay(10);
        //vregiout
        LCD_WriteReg(0x0012,0x009D); //0x001b
        rt_thread_mdelay(10);
        //vom amplitude
        LCD_WriteReg(0x0013,0x1900);
        rt_thread_mdelay(10);
        //vom H
        LCD_WriteReg(0x0029,0x0025);
        LCD_WriteReg(0x002B,0x000D);
        //gamma
        LCD_WriteReg(0x0030,0x0007);
        LCD_WriteReg(0x0031,0x0303);
        LCD_WriteReg(0x0032,0x0003);// 0006
        LCD_WriteReg(0x0035,0x0206);
        LCD_WriteReg(0x0036,0x0008);
        LCD_WriteReg(0x0037,0x0406);
        LCD_WriteReg(0x0038,0x0304);//0200
        LCD_WriteReg(0x0039,0x0007);
        LCD_WriteReg(0x003C,0x0602);// 0504
        LCD_WriteReg(0x003D,0x0008);
        //ram
        LCD_WriteReg(0x0050,0x0000);
        LCD_WriteReg(0x0051,0x00EF);
        LCD_WriteReg(0x0052,0x0000);
        LCD_WriteReg(0x0053,0x013F);
        LCD_WriteReg(0x0060,0xA700);
        LCD_WriteReg(0x0061,0x0001);
        LCD_WriteReg(0x006A,0x0000);
        //
        LCD_WriteReg(0x0080,0x0000);
        LCD_WriteReg(0x0081,0x0000);
        LCD_WriteReg(0x0082,0x0000);
        LCD_WriteReg(0x0083,0x0000);
        LCD_WriteReg(0x0084,0x0000);
        LCD_WriteReg(0x0085,0x0000);
        //
        LCD_WriteReg(0x0090,0x0010);
        LCD_WriteReg(0x0092,0x0600);

        LCD_WriteReg(0x0007,0x0133);
        LCD_WriteReg(0x00,0x0022);//
    }
    LCD_Display_Dir(0);         //默认为竖屏
    LCD_DisplayOn();
    rt_pin_write(ILI9341_BK_CLK, PIN_HIGH);
    LCD_Clear(WHITE);
    POINT_COLOR=RED;

}
7. The entire 8080 driver LCD.C file is completed, and nearly 1100 lines of code have been written.
8. Use two ADC modules to read the photoresistor and MQ2 module.
static void Adc_entry(void* paremeter)
{
    rt_adc_device_t adc_dev;
    rt_uint32_t value,vol;
    rt_err_t ret = RT_EOK;

    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
    if (adc_dev == RT_NULL)
    {
        rt_kprintf("adc sample run failed! can't find %s device!
", ADC_DEV_NAME);
    }
    /* 使能设备 */
    ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
    if(ret == RT_EOK)
    {
        rt_kprintf("adc sample run success!  find %s device!
", ADC_DEV_NAME);
    }
    while(1)
    {
        /* 读取采样值 */
        value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
        rt_kprintf("the value is :%d 
", value);
        /* 转换为对应电压值 */
        vol = value * REFER_VOLTAGE / CONVERT_BITS;
        rt_kprintf("the voltage is :%d.%02d 
", vol / 100, vol % 100);

        rt_thread_delay(500);
    }
    /*换算为电压值*/
    txt=vol/100+((vol%100)*0.01);
    /*转换为气体浓度*/
    ppm = pow(11.5428 * 35.904 * txt/(25.5-5.1* txt),0.6549)*10;
9. MQ2 module concentration reading, calculation formula with comments.
#define ADC_DEV_NAME2        "adc1"      /* ADC 设备名称 */
#define ADC_DEV_CHANNEL2     9           /* ADC 通道 */

#define REFER_VOLTAGE       330         /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS        (1 << 16)   /* 转换位数为16位 */

   rt_uint32_t value,vol;
    float txt;
    rt_adc_device_t adc_dev;
    rt_err_t ret = RT_EOK;

    /* 查找设备 */
    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME2);
    if (adc_dev == RT_NULL)
    {
        rt_kprintf("adc sample run failed! can't find %s device!
", ADC_DEV_NAME2);
        return RT_ERROR;
    }

    /* 使能设备 */
    ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL2);
    /* 读取采样值 */
    value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL2);

    /* 转换为对应电压值 */
    vol = value * REFER_VOLTAGE / CONVERT_BITS;
    /*换算为电压值*/
    txt=vol/100+((vol%100)*0.01);
    /*转换为气体浓度*/
    ppm = pow(11.5428 * 35.904 * txt/(25.5-5.1* txt),0.6549)*10;

    //rt_kprintf("the voltage2 is :%d.%02d 
", vol / 100, vol % 100);

    /* 关闭通道 */
    ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL2);

    return ret;
10. The LCD displays Chinese character codes. Since the horizontal screen mode is used, the characters need to be rotated 90 degrees when taking the mold.
void LCD_ShowChinese(uint16_t x,uint16_t y,uint8_t num,uint8_t size,uint8_t mode)
{
    uint8_t temp,t1,t;
    uint16_t y0=y;
    uint16_t colortemp=POINT_COLOR;
    //设置窗口
    num=num-' ';//得到偏移后的值,空格的ascii码是0
    if(!mode) //非叠加方式
    {
        for(t=0;t<size;t++)
        {
           if(size==12)temp=asc2_1206[num][t];  //调用1206字体
           else if(size==16) temp=asc2_1608[num][t];   //调用1608字体
           else if(size==32)  temp=asc2_1616[num][t];      //调用1616汉字字体
           for(t1=0;t1<8;t1++)
           {
               if(temp&0x80)POINT_COLOR=colortemp;
                  else POINT_COLOR=BACK_COLOR;
                  LCD_DrawPoint(x,y);
                  temp<<=1;
                  y++;
                  if(x>=lcddev.width)
                  {
                          POINT_COLOR=colortemp;
                          return;
                  }//超区域了
                if(size==32)
                {
                 if((y-y0)==16)
                 {
                  y=y0;
                  x++;
                  if(x>=lcddev.width){POINT_COLOR=colortemp;return;}//超区域了
                  break;
                 }
                }
                else if((y-y0)==size)
                {
                    y=y0;
                    x++;
                    if(x>=lcddev.width){POINT_COLOR=colortemp;return;}//超区域了
                    break;
                }
           }
        }
    }else//叠加方式
    {
        for(t=0;t<size;t++)
        {
            if(size==12)temp=asc2_1206[num][t];  //调用1206字体
            else if(size==16)temp=asc2_1608[num][t];   //调用1608字体
            else if(size==32)  temp=asc2_1616[num][t];
            for(t1=0;t1<8;t1++)
            {
                if(temp&0x80)LCD_DrawPoint(x,y);
                temp<<=1;
                y++;
                if(x>=lcddev.height){POINT_COLOR=colortemp;return;}//超区域了
                if(size==32)
                {
                    if((y-y0)==16)
                    {
                        y=y0;
                        x++;
                        if(x>=lcddev.width){POINT_COLOR=colortemp;return;}//超区域了
                        break;
                    }
                }
                else if((y-y0)==size)
                {
                    y=y0;
                    x++;
                    if(x>=lcddev.width){POINT_COLOR=colortemp;return;}//超区域了
                    break;
                }
            }
        }
    }
        POINT_COLOR=colortemp;
}

5. Development experience sharing

1. Development considerations

When using RT-Thread real-time operating system for multi-threaded application development, you should pay attention to the following matters:

1. The thread scheduler of RT-Thread is preemptive, which means that it can ensure that the highest priority task in the ready queue can always get the right to use the CPU. When designing tasks, the priority of the tasks must be fully considered.

2. During the running of the hardware interrupt service program, if a high-priority task is ready, the interrupted low-priority task will be suspended, and the high-priority task will obtain the right to use the CPU.

3. Each thread has an independent thread stack, which is used to save context information during thread scheduling. Therefore, when creating a thread and allocating stack space, the size of the stack must be fully considered.

4. In the loop body of the thread, certain conditions should be set to actively give up the use of the CPU when necessary. Especially for high-priority threads, if there is an infinite loop operation in the program and the CPU is not actively given up, usage rights, then this thread will always occupy the CPU, and low-priority threads will never be scheduled for execution.

5. For threads that do not continuously execute in a loop, after the thread execution is completed, the resource recycling is actually carried out in the idle thread. After the thread becomes closed, it does not mean that the resources are recycled immediately.

6. The system idle thread has the lowest priority and is always ready. The idle thread is an infinite loop and will never be suspended, but can be preempted by other high-priority tasks. The idle thread mainly performs the resource recovery work of zombie threads. .

7. Idle threads can also set hook functions to perform power consumption management, watchdog feeding, etc.

8. For threads created through dynamic methods, the size of the system heap memory needs to be set. For threads created through static methods, the thread stack and thread handle are determined when the program is compiled and cannot be dynamically allocated or released.

9. Most threads are continuously executed in a loop and do not need to be deleted. It is generally not recommended to actively delete threads. After the thread finishes running, the system scheduler will automatically add the thread to the zombie queue, and resource recycling will be performed in the idle thread.

2. Development experience

RT-Thread Studio is a very powerful and easy-to-use IDE. When using RT-Thread, you don’t need to transplant it step by step as before. With this software, you can quickly create a project containing RT-Thread.

In addition, RT-Thread Studio supports development board development and can quickly create projects and even replace keil. Moreover, RT-Thread Studio supports more and more development boards and BSps and is updated more and more. Perfect, I look forward to the wonderful debut of domestic operating systems in the future. After feeling the powerful dominance of RT-Thread, you must use ART-Pi to continue to learn more about the RT-Thread operating system.

6. Physical product

The link to the Bilibili demonstration video will be attached at the end. video hereInsert image description hereInsert image description hereInsert image description here

参考设计图片
×
 
 
Search Datasheet?

Supported by EEWorld Datasheet

Forum More
Update:2025-06-19 08:38:52

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
community

Robot
development
community

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号