STM32+ESP8266+QT客户端上位机显示DHT11温湿度与点灯

news2024/11/15 13:40:52

目录

1、简介

2、硬件连接

3、上位机源码

3.1 widget.h

3.2 widget.c 

3.3 显示图

 4、下位机源码

4.1 cubemax配置

 4.2 keil源码


1、简介

本文使用STM32F103C8T6单片机使用单片机通过ESP8266WIFI模块与QT设计的上位机进行通讯,ESP8266设置AP模式。实现DHT11传感器温湿度的显示与远程控制LED小灯的亮灭。

2、硬件连接

PB9---DHT11(5V)

PA9----RX

PA10---TX

ESP8266(3.3V)

PB0----LED(高电平有效)

3、上位机源码

3.1 widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
namespace Ui {
class Widget;
}
#pragma pack(1)
struct QT_info
{
    unsigned char Head[2];
    uint8_t DHT11_BUF[2];//用于存放DHT11数据
};
#pragma pack()
class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

    //QTcpServer *tcpserver;//声明一个QTcpserver的对象,用于监听
    QTcpSocket *tcpsocket;//创建服务器的套接字,用于与客户端进行通信

private slots:
    void on_open_Button_clicked();

    void on_close_Button_clicked();

    void on_send_Button_clicked();

    void connected_Slot();

    void readyRead_Slot();

    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

3.2 widget.c 

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //tcpserver = new QTcpServer(this);
    tcpsocket = new QTcpSocket(this);
}

Widget::~Widget()
{
    delete ui;
}

//client端的连接服务器按钮
void Widget::on_open_Button_clicked()
{
     // 根据输入的ip和port连接指定的服务器
//    tcpsocket->connectToHost(ui->IP_line->text(),ui->port_line->text().toUShort());
    tcpsocket->connectToHost("192.168.4.1",333);
    connect(tcpsocket,SIGNAL(connected()),this,SLOT(connected_Slot()));
    if(tcpsocket->waitForConnected(1000) == true){

    tcpsocket->write("Q");
    }

}

void Widget::connected_Slot()
{
    connect(tcpsocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
}

void Widget::readyRead_Slot()
{
    QByteArray mytemp = tcpsocket->readAll();
    //ui->rece_TextEdit->appendPlainText(tcpsocket->readAll());
    if(!mytemp.isEmpty()){
    ui->rece_T_Edit->clear();
    ui->rece_S_Edit->clear();
    struct QT_info* info_RX = (struct QT_info*)mytemp.data(); // unsigned char *
    if(info_RX->Head[0]==0x55 && info_RX->Head[1]==0xFF) {
        QString T = QString::asprintf("%.2d",info_RX->DHT11_BUF[1]);
        QString S = QString::asprintf("%2d",info_RX->DHT11_BUF[0]);
        ui->rece_T_Edit->insertPlainText(T);
        ui->rece_S_Edit->insertPlainText(S);
    }
    mytemp.clear();
    }
}

void Widget::on_close_Button_clicked()
{
    tcpsocket->write("B");
    tcpsocket->close();
    ui->rece_T_Edit->clear();
    ui->rece_S_Edit->clear();

} 

void Widget::on_send_Button_clicked()
{
//    tcpsocket->write(ui->send_line->text().toLocal8Bit().data());
   tcpsocket->write("Q");
}

void Widget::on_pushButton_clicked()
{
    tcpsocket->write("B");
}

3.3 显示图

 4、下位机源码

4.1 cubemax配置

 GPIO配置。

 串口配置,中断打开。

 4.2 keil部分源码

func

#include "func.h"

struct QT_info QT_info_TX;
extern char buf;
uint16_t len;

void CSH(void)
{
	len = sizeof(QT_info_TX);
  DHT11_Init();//传感器芯片初始化
  DHT11_ReadData(QT_info_TX.DHT11_BUF);//读出DHT11传感器数据(参数是存放数据的数组指针)
	HAL_Delay(200);
	//1 工作在路由模式
	printf("AT+CWMODE=2\r\n");
	HAL_Delay(200);
	
  //2 使能多链接
	printf("AT+CIPMUX=1\r\n");
	HAL_Delay(200);
	
	//3 建立TCPServer port = 333
  printf("AT+CIPSERVER=1\r\n");
	HAL_Delay(200);
	
	LED_OFF;
	QT_info_TX.Head[0]=0x55;
  QT_info_TX.Head[1]=0xFF;
	
}
void oled_ui(void)
{ 
	DHT11_ReadData(QT_info_TX.DHT11_BUF);//读出DHT11传感器数据(参数是存放数据的数组指针)
	HAL_Delay(100);
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&buf, 1);		
	//发送数据
	printf("AT+CIPSEND=0,%d\r\n",len);
	HAL_Delay(200);
	
	HAL_UART_Transmit(&huart1,(uint8_t *)&QT_info_TX,sizeof(QT_info_TX),10);
}
#include "main.h"
#include "dht11.h"
#include "usart.h"
#include "string.h"


void CSH(void);
void alarm(void);
void oled_ui(void);
void Qt_UART_RxCallBack(unsigned char *Data,unsigned int Len);


__packed struct QT_info
{
	unsigned char Head[2];
	
	uint8_t DHT11_BUF[2];//用于存放DHT11数据
	
};

main

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
char buf;
#include "func.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart)//涓插彛涓柇鍥炶皟鍑芥暟
{
	if(huart1.Instance == USART1)
	{
		if(buf == 'Q')
		{
			 LED_ON;
      HAL_UART_Receive_IT(&huart1, (uint8_t *)&buf, 1);
		}
		else if(buf == 'B')
		{
			 LED_OFF;
      HAL_UART_Receive_IT(&huart1, (uint8_t *)&buf, 1);
		}
		HAL_UART_Receive_IT(&huart1, (uint8_t *)&buf, 1);
	}   
}
     
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_I2C1_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
	CSH();
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {	
		oled_ui();
		
//	printf("1\r\n");
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

dht11

/*
 * dht11.c
 *
 *  Created on: Oct 21, 2021
 *      Author: Administrator
 */

/*
//杜洋工作室出品
//洋桃系列开发板应用程序
//关注微信公众号:洋桃电子
//洋桃开发板资料下载 www.DoYoung.net/YT
//即可免费看所有教学视频,下载技术资料,技术疑难提问
//更多内容尽在 杜洋工作室主页 www.doyoung.net
*/

/*
《修改日志》
1-201708202309 创建。


*/



#include "dht11.h"
#include "main.h"

void DHT11_IO_OUT (void){ //端口变为输出
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = DHT11_DA_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void DHT11_IO_IN (void){ //端口变为输入
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = DHT11_DA_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void DHT11_RST (void){ //DHT11端口复位,发出起始信号(IO发送)
	DHT11_IO_OUT();
	HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_RESET);
	HAL_Delay(20); //拉低至少18ms
	HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_SET);
	delay_us(30); //主机拉高20~40us
}

uint8_t Dht11_Check(void){ //等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收)
	uint8_t retry=0;
    DHT11_IO_IN();//IO到输入状态
    while (HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11会拉低40~80us
        retry++;
        delay_us(1);
    }
    if(retry>=100)return 1; else retry=0;
    while (!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11拉低后会再次拉高40~80us
        retry++;
        delay_us(1);
    }
    if(retry>=100)return 1;
    return 0;
}

uint8_t Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0
	uint8_t retry=0;
    while(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变为低电平
        retry++;
        delay_us(1);
    }
    retry=0;
    while(!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变高电平
        retry++;
        delay_us(1);
    }
    delay_us(40);//等待40us	//用于判断高低电平,即数据1或0
    if(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin))return 1; else return 0;
}

uint8_t Dht11_ReadByte(void){  //从DHT11读取一个字节  返回值:读到的数据
	uint8_t i,dat;
    dat=0;
    for (i=0;i<8;i++){
        dat<<=1;
        dat|=Dht11_ReadBit();
    }
    return dat;
}

uint8_t DHT11_Init (void){	//DHT11初始化
	DHT11_RST();//DHT11端口复位,发出起始信号
	return Dht11_Check(); //等待DHT11回应
}

uint8_t DHT11_ReadData(uint8_t *h){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
	uint8_t buf[5];
	uint8_t i;
    DHT11_RST();//DHT11端口复位,发出起始信号
    if(Dht11_Check()==0){ //等待DHT11回应
        for(i=0;i<5;i++){//读取5位数据
            buf[i]=Dht11_ReadByte(); //读出数据
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){	//数据校验
            *h=buf[0]; //将湿度值放入指针1
			h++;
            *h=buf[2]; //将温度值放入指针2
        }
    }else return 1;
    return 0;
}

//===============================================us延时函数
void delay_us(uint32_t us)//主频72M
{
    uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
    while (delay--)
	{
		;
	}
}
/*********************************************************************************************
 * 杜洋工作室 www.DoYoung.net
 * 洋桃电子 www.DoYoung.net/YT
*********************************************************************************************/
#ifndef __DHT11_H
#define __DHT11_H

#include "stm32f1xx_hal.h"


void DHT11_IO_OUT (void);
void DHT11_IO_IN (void);
void DHT11_RST (void);
uint8_t Dht11_Check(void);
uint8_t Dht11_ReadBit(void);
uint8_t Dht11_ReadByte(void);
uint8_t DHT11_Init (void);
uint8_t DHT11_ReadData(uint8_t *h);
void delay_us(uint32_t us);
#endif

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/440618.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

跨越DDD从理论到工程落地的鸿沟

DDD作为一种优秀的设计思想&#xff0c;的确为复杂业务治理带来了曙光。然而因为DDD本身难以掌握&#xff0c;很容易造成DDD从理论到工程落地之间出现巨大的鸿沟。就像电影里面的桥段&#xff0c;只谈DDD理论姿势很优美&#xff0c;一旦工程落地就跪了…所以DDD的项目&#xff…

Android实战-RecyclerView+Glide刷新列表的若干bug

文章目录 前言一. RecyclerView中使用Glide出现加载图片闪烁1.1 提出问题1.2 查看源码1.3 ViewTarget和SimpleTarget 二. CustomTarget和CustomViewTarget2.1 onResourceCleared和onLoadCleared2.2 onLoadStarted和onResourceLoading 结束 前言 最近在项目中使用RecyclerViewG…

Java——合并两个排序的链表

题目链接 牛客在线oj题——合并两个排序的链表 题目描述 输入两个递增的链表&#xff0c;单个链表的长度为n&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 数据范围&#xff1a; 0≤n≤1000&#xff0c;−1000≤节点值≤1000 要求&#xff1a;空间复杂…

物联网定位技术|实验报告|实验二 多边定位算法、DV-HOP算法

在WSN定位中常常采用三边定位算法&#xff0c;试画图推导三边定位的计算公式&#xff0c;并表示为矩阵形式。 目录 1. 实验目标 2. 实验要求 3. 算法介绍 3.1基本内容介绍 3.2迭代多边定位算法 3.3 DV-HOP算法 4. 算法实现 4.1迭代多边定位算法 第一步&#xff1a;将数据读入内…

STM32HAL库USART外设配置流程及库函数讲解

HAL库中USART外设配置流程及库函数讲解 一说到串口通信&#xff0c;及必须说一下aRS-232/485协议。232协议标准物理接口就是我们常用的DB9串口线 RS-232电平&#xff1a; 逻辑1&#xff1a;-15~-3 逻辑0&#xff1a; 3~15 COMS电平&#xff1a; 逻辑1&#xff1a;3.3 逻辑0&a…

文件操作【下篇】

文章目录 &#x1f5c3;️5.文件的随机读写&#x1f4c1;5.1. fseek&#x1f4c1;5.2. ftell&#x1f4c1;5.3. rewind &#x1f5c3;️6.文本文件和二进制文件&#x1f5c3;️7.文件读取结束的判定&#x1f4c1;7.1. 被错误使用的 feof &#x1f5c3;️8.文件缓冲区 &#x1f…

如何使用YOLOv8推荐的Roboflow来制作训练自己的数据集

YOLOv8是Ultralytics开发的YOLO目标检测和图像分割模型的最新版本&#xff0c;相较于之前的版本&#xff0c;YOLOv8可以更快速有效地识别和定位图像中的物体&#xff0c;以及更准确地分类它们。 YOLOv8需要大量的训练数据来实现最佳性能。为了让YOLOv8能够有效地识别自己的应用…

【UE】保存游戏的demo

效果 注意左上角的打印信息&#xff0c;每当我按下k键&#xff0c;值就加1。当我关闭后重进游戏&#xff0c;按下k键&#xff0c;值是从上次退出游戏的值开始累加的。 步骤 1.新建蓝图&#xff0c;父类为“SaveGame” 命名为“MySaveGame”并打开 新建一个整型变量&#xff0c…

ODOO业财一体贸易行业ERP全面管理系统(核心流程简介)

前言&#xff1a; 贸易行业的两大管理难点在&#xff1a; 1.订单的跟踪效率&#xff1a;订单从报价、寄样、采购材料、委外加工、质检、入库、出库、收款&#xff0c;跟踪环节多&#xff0c;信息分散&#xff0c;跟单员难以把握订单执行进度&#xff0c;因此也导致延期交货等…

户外电源强制国标发布或加速行业洗牌 未来产品将往大容量及轻量化发展

一、户外电源行业概述 户外电源是一种内置锂离子电池的低碳绿色小型储能设备&#xff0c;又称“大号充电宝”、“便携式储能”。是电化学储能的分支&#xff0c;优在“便捷”&#xff0c;具有多次循环充放电、适配广泛、安全便捷的特点&#xff0c;在户外各场景中应用广泛受到…

Ubuntu安装k8s的Dashboard

介绍 Dashboard 是基于网页的 Kubernetes 用户界面。您可以使用 Dashboard 将容器应用部署到Kubernetes 集群中&#xff0c;也可以对容器应用排错&#xff0c;还能管理集群本身及其附属资源。您可以使用Dashboard 获取运行在集群中的应用的概览信息&#xff0c;也可以创建或者…

从Allegro进行反标

从Allegro进行反标 目的反标流程常见问题 目的 通过反标&#xff0c;可以将Allegro中交换的管脚或重新编排的位号&#xff0c;一键更新到原理图中。 反标流程 从Capture输出最新网表文件&#xff1a; Capture Menu -> Tools -> Creat Netlist将最终的PCB设计文件放在…

Java:MybatisPlus--条件构造器

1、条件构造器类别 ①wrapper&#xff1a;抽象类&#xff0c;条件类的顶层&#xff0c;提供了一些获取和判断相关的方法。 ②AbstractWrapper&#xff1a;抽象类&#xff0c;Wrapper的子类&#xff0c;提供了所有的条件相关方法。 ③AbstractLambdaWrapper&#xff1a;抽象类…

对矩阵规模序列<5,10,3,12,5,50,6>,求矩阵链最优括号化方案

对矩阵规模序列<5,10,3,12,5,50,6>,求矩阵链最优括号化方案 理解符号的含义 n6 矩阵A1A2A3A4A5A6 本质是找一个最优的子结构 1.重要的递推公式 2.关键是求最小的m[i,j]就是乘积次数最少的。 k 的位置只有 j − i 种可能 3.下面是详细的解题的方案 根据矩阵链乘法问题&am…

网络工程师经常搞混的路由策略和策略路由,两者到底有啥区别?

当涉及到网络路由时&#xff0c;两个术语经常被混淆&#xff1a;策略路由和路由策略。虽然这些术语听起来很相似&#xff0c;但它们实际上有着不同的含义和用途。在本文中&#xff0c;我们将详细介绍这两个术语的区别和应用。 一、路由策略 路由策略是指一组规则&#xff0c;用…

算法套路九——二叉树广度优先遍历(层序遍历)

算法套路九——二叉树广度优先遍历&#xff08;层序遍历&#xff09; 算法示例LeetCode102. 二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 法一&#xff1a;双数组…

二极管初识

二极管初识 二极管的主要参数如下&#xff1a; 一般的二极管可以在正向或反向偏置条件下工作。 当二极管正向偏置时&#xff0c;需要经过一定的电压降&#xff08;硅为0.7V&#xff0c;锗为0.3V&#xff09;&#xff0c;才能让电流开始流动。此后&#xff0c;二极管上的电压…

【Vue】学习笔记-绑定样式/条件样式

绑定样式/条件样式 绑定样式条件渲染 绑定样式 class样式 写法 :class"xxx" xxx可以是字符串&#xff0c;对象&#xff0c;数组 字符串写法适用于&#xff1a;类名不确定&#xff0c;要动态获取。 对象写法适用于&#xff1a;要绑定多个样式&#xff0c;个数不确定&…

如何给ClickHouse表生成随机真实测试数据

学习ClickHouse数据库&#xff0c;通常需要下载官网一些示例数据。我们也可以通过内置函数generateRandom快速生成测试数据&#xff0c;从而测试学习一些特性的性能及底层原理。 函数语法 generateRandom函数基于给定schema生成随机数据&#xff0c;用于填充测试表。不是所有类…

【SSM】SpringMVC(三:SpringMVC拦截器)

文章目录 1. 登录案例2. 拦截器2.1 应用2.2 拦截器的执行原理2.3 拦截器执行的时机2.4 拦截器的实现方法2.5 拦截器的实现步骤2.6 开发拦截器 1. 登录案例 【login.jsp】 <%--Created by IntelliJ IDEA.User: BeyongDate: 2023/4/17Time: 11:43To change this template use…