RASC-based keil electronic clock production (Renesas RA) (11)----read DHT11 temperature and humidity data

overview

This document will create a capacitive touch application example using e2 studio integrated QE ported to keil.

hardware preparation

First, you need to prepare a development board. Here I am preparing a development board with chip model R7FA2E1A72DFL:

insert image description here

insert image description here

video tutorial

https://www.bilibili.com/video/BV1Xu4y117FC/

Keil electronic clock production based on RASC (Renesas RA)----(11) capacitive touch configuration

Add TOUCH driver

Add touch components by clicking New Stack->CapTouch->Touch.
insert image description here

The touch io on the board is P015.
insert image description here

Configure GPIO to touch capacitive mode.

insert image description here

After the configuration is complete, it will be displayed synchronously in the TOUCH component.
insert image description here

e2studio configuration CapTouch

From the menu in e2 studio, select Renesas View > Renesas QE > CapTouch Workflow (QE) to open the main view for configuring capacitive touch.

insert image description here

After opening, you can see the specific configuration process.

insert image description here

In the CapTouch Workflow (QE) pane, you first need to select the capacitive touch item to be configured, as shown below.

insert image description here
insert image description here

Execute "Prepare Configuration" to create a new Touch configuration by using the drop-down menu and selecting Create a new configuration.
insert image description here

Capacitive touch buttons can be added through Button, the specific process is as follows.
1. Select the Button menu item from the right and move the mouse over the canvas.
2. Click the left mouse button to drop the button icon. There are 2 capacitive touch buttons on the development board, two buttons can be added.
3. After the two buttons are added, press the side to select the Button menu to exit the placement.
insert image description here

Double-click the button to configure specific capacitive touch button pins.
insert image description here

After the configuration is complete, you can see that the warning has disappeared, and the button turns green at the same time.

insert image description here

e2studio opens the tuning interface

Click Renesas View -> Renesas QE -> CapTouch Tuning Result, the configuration of the touch interface will be displayed in the main view pane.
insert image description here
insert image description here

e2studio starts CapTouch tuning

To start the automatic tuning process, click the start tuning button.

insert image description here
Need to pay attention to link to the development board.
QE for capacitive touch auto-tuning starts now, please read the tuning dialog windows carefully as they will guide you through the tuning process. A sample screen is shown below.
insert image description here

After going through a few automated steps, you will arrive at the dialog box with the information shown below.
This is the touch sensitivity measurement step of the tuning process. Press normal touch pressure on the sensor shown in the dialog.
insert image description here

As you press, the bar will increase to the right and the touch count will go up numerically. While maintaining the pressure, press any key on the computer keyboard to accept the measurement.
insert image description here

Once done, you will see the picture shown below, which is the detection threshold used by the middleware to determine if a Touch event has occurred.
insert image description here

Click the "Continue the Tuning Process" button in the dialog. This will exit the tuning process and disconnect the debug session on the target.
insert image description here

After the tuning process is complete, the default view presented here will be the tuning results for the sensors in that configuration. This allows the user to quickly see the adjustment results.
insert image description here

Look in the Project Explorer window and you'll see the files added. These files contain the adjustment information needed to enable touch detection.
insert image description here

Output tuning parameter file. Click the "Output Parameter Files" button.
insert image description here

Look in the Project Explorer window and you'll see the files added. These files contain the adjustment information needed to enable touch detection.
insert image description here

e2studio judges whether the capacitive touch is pressed

To implement the application code for the capacitive touch state, click the "Show Sample" button.

insert image description here
A new menu window will open showing the sample code in the text. Click the "Output to a File" button.
insert image description here

Created a new project file describing the sample code. In the Project Explorer window, you will see that the qe_touch_sample.c file has been added.
insert image description here

Copy the QE file to Keil

insert image description here
Right-click the folder, select Add Existing Files to Group, and add the C file just imported.

insert image description here

threshold modification

The touch threshold can be modified as follows, the maximum bit is 65535.
insert image description here

Realization of touch capacitance function

Open qe_touch_sample.c to view the touch capacitor example code.
insert image description here

You can see that the touch component needs to be initialized and opened in the main program.

    /* Open Touch middleware */
    err = RM_TOUCH_Open(g_qe_touch_instance_config01.p_ctrl, g_qe_touch_instance_config01.p_cfg);
    if (FSP_SUCCESS != err)
    {
    
    
        while (true) {
    
    }
    }

insert image description here
Pay attention to bring the header file.

#include "qe_touch_config.h"

insert image description here

Write a similar function for reading.

void qe_touch_sw(void)
{
    
    
    /* for [CONFIG01] configuration */
     err = RM_TOUCH_ScanStart(g_qe_touch_instance_config01.p_ctrl);
     if (FSP_SUCCESS != err)
     {
    
    
         while (true) {
    
    }
     }
     while (0 == g_qe_touch_flag) {
    
    }
     g_qe_touch_flag = 0;
     uint64_t button_status;
     err = RM_TOUCH_DataGet(g_qe_touch_instance_config01.p_ctrl, &button_status, NULL, NULL);
     if (FSP_SUCCESS == err)
     {
    
    
         /* TODO: Add your own code here. */
         if(button_status & (0b1 ) )
             qe_sw=1;
         else
             qe_sw=0;
     }
}

insert image description here
Declare the function.

void qe_touch_sw(void);

insert image description here

At the same time add this function in the main program.
insert image description here

Modify the button function, in timer_smg.c, mainly add the definition of the touch button.

insert image description here

void set_smg_button(void)
{
    
    

     R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, &sw1);
     R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_08, &sw2);
     R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_09_PIN_13, &sw3);
     R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_09_PIN_14, &sw4);

     if(sw1+sw2+sw3+sw4==4&&qe_sw==0)//按键都没按下,清除按键按下计数值
     {
    
    
         sw1_num1=0;
         sw2_num1=0;
         sw3_num1=0;
         sw4_num1=0;
         qe_sw_num1=0;
     }
     else if(sw1==0&&sw2&&sw3&&sw4&&qe_sw==0)//只有SW1按下
     {
    
    
         if(sw1_num1<1001)//按下小于10s,1001是防止变量在1000时候一直切换模式
         sw1_num1++;
         if(sw1_num1%200==0)//模式切换,按下
         {
    
    
             buzzer_num=20;//蜂鸣器叫200ms
             if(smg_mode>2)
                 smg_mode=0;
             else
             smg_mode++;
         }
         if(smg_mode==6)
             smg_mode=0;

     }
     else if(sw2==0&&sw1&&sw3&&sw4&&qe_sw==0)//只有SW2按下
     {
    
    
         if(sw2_num1<30)//300ms 减一次
             sw2_num1++;
         else
         {
    
    
             sw2_num1=0;
             if(smg_mode==1)
             {
    
    
                 if(hour>0)
                     hour--;
                 else
                     hour=23;

             }
             else if(smg_mode==2)
             {
    
    
                 if(min>0)
                     min--;
                 else
                     min=59;
             }
         }
     }
     else if(sw3==0&&sw1&&sw2&&sw4&&qe_sw==0)//只有SW3按下
     {
    
    
         if(sw3_num1<30)//300ms 减一次
             sw3_num1++;
         else
         {
    
    
             sw3_num1=0;
             if(smg_mode==1)
             {
    
    
                 if(hour<23)
                     hour++;
                 else
                     hour=0;

             }
             else if(smg_mode==2)
             {
    
    
                 if(min<59)
                     min++;
                 else
                     min=0;
             }
         }
     }

     else if(sw1&&sw2&&sw3&&sw4&&qe_sw)//只有触摸电容按下
     {
    
    
         if(qe_sw_num1<200)//2000ms 切换一次
             qe_sw_num1++;
         else
         {
    
    
             qe_sw_num1=0;
             if(smg_mode==0)//切换到显示温度
             {
    
    
                 smg_mode=4;

             }
             else if(smg_mode==4)//切换到显示湿度
             {
    
    
                 smg_mode=5;
             }
             //切换为数据保存
             else if(smg_mode==1||smg_mode==2)
             {
    
    
                 smg_mode=3;
             }
             else if(smg_mode==5)//正常显示
              {
    
    
                  smg_mode=0;
              }

         }

     }


}

At the same time, the temperature and humidity display is added in the callback function, and the definition of the touch button is mainly added in timer_smg.c.
insert image description here

void timer0_callback(timer_callback_args_t *p_args)
{
    
    
    /* TODO: add your own code here */
    if (TIMER_EVENT_CYCLE_END == p_args->event)
    {
    
    
        time_mode_num++;
        if(time_mode_num>200)
            time_mode_num=0;


        if(smg_mode==0)
        {
    
    
            if(num_flag==0)
                smg_1(num1);
            else if(num_flag==1)
                smg_2(num2);
            else if(num_flag==2)
                smg_3(num3);
            else if(num_flag==3)
                smg_4(num4);
            else if(num_flag==4)
                smg_maohao_open(1);   //冒号
        }
        else if(smg_mode==1)//修改时间小时
        {
    
    
            if(time_mode_num<100)
            {
    
    
                if(num_flag==0)
                    smg_1(hour/10);
                else if(num_flag==1)
                    smg_2(hour%10);
                else if(num_flag==2)
                    smg_3(min/10);
                else if(num_flag==3)
                    smg_4(min%10);
                else if(num_flag==4)
                    smg_maohao_open(1);   //冒号
            }
            else
            {
    
    
                if(num_flag==0)
                    smg_1_close();
                else if(num_flag==1)
                    smg_2_close();
                else if(num_flag==2)
                    smg_3(min/10);
                else if(num_flag==3)
                    smg_4(min%10);
                else if(num_flag==4)
                    smg_maohao_open(1);   //冒号
            }
        }
        else if(smg_mode==2)//修改时间分钟
        {
    
    
            if(time_mode_num<100)
            {
    
    
                if(num_flag==0)
                    smg_1(hour/10);
                else if(num_flag==1)
                    smg_2(hour%10);
                else if(num_flag==2)
                    smg_3(min/10);
                else if(num_flag==3)
                    smg_4(min%10);
                else if(num_flag==4)
                    smg_maohao_open(1);   //冒号
            }
            else
            {
    
    
                if(num_flag==0)
                    smg_1(hour/10);
                else if(num_flag==1)
                    smg_2(hour%10);
                else if(num_flag==2)
                    smg_3_close();
                else if(num_flag==3)
                    smg_4_close();
                else if(num_flag==4)
                    smg_maohao_open(1);   //冒号
            }
        }
        else if(smg_mode==3)//保存数据
        {
    
    
            set_time.tm_sec=sec;
            set_time.tm_min =min;
            set_time.tm_hour  =hour ;
            R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);
            smg_mode=0;
            flash_flag=1;//保存数据
        }
        else if(smg_mode==4)//显示温度
        {
    
    

                if(num_flag==0)
                    smg_1_p();
                else if(num_flag==1)
                    smg_2(1);
                else if(num_flag==2)
                    smg_3(temp_integer/10);
                else if(num_flag==3)
                    smg_4(temp_integer%10);
                else if(num_flag==4)
                    smg_maohao_open(1);   //冒号
        }
        else if(smg_mode==5)//显示湿度
        {
    
    

                if(num_flag==0)
                    smg_1_p();
                else if(num_flag==1)
                    smg_2(2);
                else if(num_flag==2)
                    smg_3(humdity_integer/10);
                else if(num_flag==3)
                    smg_4(humdity_integer%10);
                else if(num_flag==4)
                    smg_maohao_open(1);   //冒号
        }


        num_flag++;
        if(num_flag==5)//每次刷新一组数码管
            num_flag=0;
    }
}

Variable definitions need to be added.

//温湿度变量定义
extern uint8_t humdity_integer;//湿度整数
extern uint8_t humdity_decimal;//湿度小数
extern uint8_t temp_integer ;//温度整数
extern uint8_t temp_decimal ;//温度小数
extern uint8_t dht11_check ;//校验值

insert image description here

main function

#include "hal_data.h"
#include <stdio.h>
#include "smg.h"
#include "timer_smg.h"
#include "flash_smg.h"
#include "dht11.h"
#include "qe_touch_config.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER

void qe_touch_sw(void);

//温湿度变量定义
uint8_t humdity_integer;//湿度整数
uint8_t humdity_decimal;//湿度小数
uint8_t temp_integer ;//温度整数
uint8_t temp_decimal ;//温度小数
uint8_t dht11_check ;//校验值

//数码管变量
uint8_t num1=1,num2=4,num3=6,num4=8;//4个数码管显示的数值
uint8_t num_flag=0;//4个数码管和冒号轮流显示,一轮刷新五次


//RTC变量
/* rtc_time_t is an alias for the C Standard time.h struct 'tm' */
rtc_time_t set_time =
{
    
    
    .tm_sec  = 50,      /* 秒,范围从 0 到 59 */
    .tm_min  = 59,      /* 分,范围从 0 到 59 */
    .tm_hour = 23,      /* 小时,范围从 0 到 23*/
    .tm_mday = 29,       /* 一月中的第几天,范围从 0 到 30*/
    .tm_mon  = 11,      /* 月份,范围从 0 到 11*/
    .tm_year = 123,     /* 自 1900 起的年数,2023为123*/
    .tm_wday = 6,       /* 一周中的第几天,范围从 0 到 6*/
//    .tm_yday=0,         /* 一年中的第几天,范围从 0 到 365*/
//    .tm_isdst=0;        /* 夏令时*/
};


//RTC闹钟变量
rtc_alarm_time_t set_alarm_time=
{
    
    
     .time.tm_sec  = 58,      /* 秒,范围从 0 到 59 */
     .time.tm_min  = 59,      /* 分,范围从 0 到 59 */
     .time.tm_hour = 23,      /* 小时,范围从 0 到 23*/
     .time.tm_mday = 29,       /* 一月中的第几天,范围从 1 到 31*/
     .time.tm_mon  = 11,      /* 月份,范围从 0 到 11*/
     .time.tm_year = 123,     /* 自 1900 起的年数,2023为123*/
     .time.tm_wday = 6,       /* 一周中的第几天,范围从 0 到 6*/

     .sec_match        =  1,//每次秒到达设置的进行报警
     .min_match        =  0,
     .hour_match       =  0,
     .mday_match       =  0,
     .mon_match        =  0,
     .year_match       =  0,
     .dayofweek_match  =  0,
    };

bsp_io_level_t sw1;//按键SW1状态
bsp_io_level_t sw2;//按键SW2状态
bsp_io_level_t sw3;//按键SW3状态
bsp_io_level_t sw4;//按键SW4状态
bsp_io_level_t qe_sw;//触摸电容状态

int sw1_num1=0;//按键SW1计数值,去抖和长按短按判断
int sw2_num1=0;//按键SW2计数值,去抖和长按短按判断
int sw3_num1=0;//按键SW3计数值,去抖和长按短按判断
int sw4_num1=0;//按键SW4计数值,去抖和长按短按判断
int qe_sw_num1=0;//触摸按键计数值,去抖和长按短按判断
void qe_touch_sw(void);

//数码管显示状态,0正常显示,1修改小时,2修改分钟,3保存修改数据,4温度,5湿度
int smg_mode=0;
int sec=0,min=0,hour=0;//保存时间数据
uint16_t time_mode_num=0;//定时器刷新时间,实现闪烁效果

volatile uint8_t g_src_uint8[4]={
    
    0x00,0x00,0x00,0x00};//时间保存在该数组里面
volatile uint8_t  g_src_uint8_length=4;
uint8_t flash_flag=0;//保存时间数据,一半在每过一分钟或者按键修改时间


//RTC回调函数
volatile bool rtc_flag = 0;//RTC延时1s标志位
volatile bool rtc_alarm_flag = 0;//RTC闹钟
/* Callback function */
void rtc_callback(rtc_callback_args_t *p_args)
{
    
    
    /* TODO: add your own code here */
    if(p_args->event == RTC_EVENT_PERIODIC_IRQ)
        rtc_flag=1;
    else if(p_args->event == RTC_EVENT_ALARM_IRQ)
        rtc_alarm_flag=1;
}


fsp_err_t err = FSP_SUCCESS;
volatile bool uart_send_complete_flag = false;
void user_uart_callback (uart_callback_args_t * p_args)
{
    
    
    if(p_args->event == UART_EVENT_TX_COMPLETE)
    {
    
    
        uart_send_complete_flag = true;
    }
}

#ifdef __GNUC__                                 //串口重定向
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
    
    
        err = R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
        if(FSP_SUCCESS != err) __BKPT();
        while(uart_send_complete_flag == false){
    
    }
        uart_send_complete_flag = false;
        return ch;
}

int _write(int fd,char *pBuffer,int size)
{
    
    
    for(int i=0;i<size;i++)
    {
    
    
        __io_putchar(*pBuffer++);
    }
    return size;
}





/*******************************************************************************************************************//**
 * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
 * is called by main() when no RTOS is used.
 **********************************************************************************************************************/
void hal_entry(void)
{
    
    
    /* TODO: add your own code here */
    /**********************DHT11初始化***************************************/
        R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_03_PIN_01, BSP_IO_LEVEL_HIGH);
        R_BSP_SoftwareDelay(1000U, BSP_DELAY_UNITS_MILLISECONDS);

    /* Open the transfer instance with initial configuration. */
       err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
       assert(FSP_SUCCESS == err);
/**********************数码管测试***************************************/
//              ceshi_smg();
/**********************定时器开启***************************************/
    /* Initializes the module. */
    err = R_GPT_Open(&g_timer0_ctrl, &g_timer0_cfg);
    /* Handle any errors. This function should be defined by the user. */
    assert(FSP_SUCCESS == err);
    /* Start the timer. */
    (void) R_GPT_Start(&g_timer0_ctrl);

/**********************data flash***************************************/
    flash_result_t blank_check_result;
    /* Open the flash lp instance. */
    err = R_FLASH_LP_Open(&g_flash0_ctrl, &g_flash0_cfg);
    assert(FSP_SUCCESS == err);

    //       WriteFlashTest(4,g_src_uint8 ,FLASH_DF_BLOCK_0);

    PrintFlashTest(FLASH_DF_BLOCK_0);


    set_time.tm_sec=0;//时间数据 秒
    set_time.tm_min=min;//时间数据 分钟
    hour=set_time.tm_hour=hour;//时间数据 小时



/**********************RTC开启***************************************/
    /* Initialize the RTC module*/
    err = R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg);
    /* Handle any errors. This function should be defined by the user. */
    assert(FSP_SUCCESS == err);

    /* Set the RTC clock source. Can be skipped if "Set Source Clock in Open" property is enabled. */
    R_RTC_ClockSourceSet(&g_rtc0_ctrl);

/* R_RTC_CalendarTimeSet must be called at least once to start the RTC */
    R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);
    /* Set the periodic interrupt rate to 1 second */
    R_RTC_PeriodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);

           R_RTC_CalendarAlarmSet(&g_rtc0_ctrl, &set_alarm_time);
           uint8_t rtc_second= 0;      //秒
           uint8_t rtc_minute =0;      //分
           uint8_t rtc_hour =0;         //时
           uint8_t rtc_day =0;          //日
           uint8_t rtc_month =0;      //月
           uint16_t rtc_year =0;        //年
           uint8_t rtc_week =0;        //周
           rtc_time_t get_time;


           sec=set_time.tm_sec;//时间数据 秒
            min=set_time.tm_min;//时间数据 分钟
            hour=set_time.tm_hour;//时间数据 小时

            /* Open Touch middleware */
            err = RM_TOUCH_Open(g_qe_touch_instance_config01.p_ctrl, g_qe_touch_instance_config01.p_cfg);
            if (FSP_SUCCESS != err)
            {
    
    
                while (true) {
    
    }
            }


       while(1)
       {
    
    
           if(flash_flag)//按键修改完毕数据后进行保存
           {
    
    
               g_src_uint8[0]=hour;
               g_src_uint8[1]=min;
               WriteFlashTest(4,g_src_uint8 ,FLASH_DF_BLOCK_0);
               flash_flag=0;
           }


           if(rtc_flag)
           {
    
    
               R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &get_time);//获取RTC计数时间
               rtc_flag=0;
               rtc_second=get_time.tm_sec;//秒
               rtc_minute=get_time.tm_min;//分
               rtc_hour=get_time.tm_hour;//时
               rtc_day=get_time.tm_mday;//日
               rtc_month=get_time.tm_mon;//月
               rtc_year=get_time.tm_year; //年
               rtc_week=get_time.tm_wday;//周
               printf(" %d y %d m %d d %d h %d m %d s %d w\n",rtc_year+1900,rtc_month,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);

                //时间显示
               num1=rtc_hour/10;
               num2=rtc_hour%10;

               num3=rtc_minute/10;
               num4=rtc_minute%10;
               if(rtc_second==0&&smg_mode==0)//这个时候刷新变量
               {
    
    
                   sec=rtc_second;//时间数据 秒
                   min=rtc_minute;//时间数据 分钟
                   hour=rtc_hour;//时间数据 小时

                   g_src_uint8[0]=hour;
                   g_src_uint8[1]=min;
                   WriteFlashTest(4,g_src_uint8 ,FLASH_DF_BLOCK_0);


               }
               if(rtc_second%5==0)//5S读一次
               {
    
    
                   DHT11_Read();
                   printf("hum=%d temp=%d\n",humdity_integer,temp_integer);

               }

           }
           if(rtc_alarm_flag)
           {
    
    
               rtc_alarm_flag=0;
               printf("/************************Alarm Clock********************************/\n");
           }
           qe_touch_sw();
           set_smg_button();
           R_BSP_SoftwareDelay(10U, BSP_DELAY_UNITS_MILLISECONDS);
       }

#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}


void qe_touch_sw(void)
{
    
    
        /* for [CONFIG01] configuration */
        err = RM_TOUCH_ScanStart(g_qe_touch_instance_config01.p_ctrl);
        if (FSP_SUCCESS != err)
        {
    
    
            while (true) {
    
    }
        }
        while (0 == g_qe_touch_flag) {
    
    }
        g_qe_touch_flag = 0;
        uint64_t button_status;
        err = RM_TOUCH_DataGet(g_qe_touch_instance_config01.p_ctrl, &button_status, NULL, NULL);
        if (FSP_SUCCESS == err)
        {
    
    
            /* TODO: Add your own code here. */
            if(button_status & (0b1 ) )
                qe_sw=1;
            else
                qe_sw=0;
        }

}


Guess you like

Origin blog.csdn.net/qq_24312945/article/details/132135750