I.MX6ull UART

news2024/11/18 13:48:13

 一 简介

UART 全称叫做串行接口,通常也叫做 COM 接口,串行接口指的是数据一个一个的顺序传输,通信线路简单。使用两条线即可实现双向通信,一条用于发送,一条用于接收。串口通信距离远,但是速度相对会低,串口是一种很常用的工业接口。I.MX6U 自带的 UART 外设就是 串口的一种,UART 全称是 Universal Asynchronous Receiver/Trasmitter,也就是异步串行收发器。 既然有异步串行收发器,那肯定也有同步串行收发器,除 了有 UART 外,还有 另外一 个叫做 USART 的东西 。USART 的 全称是 Universal Synchronous/Asynchronous Receiver/Transmitter,也就是同步/异步串行收发器。相比 UART 多了 一个同步的功能,在硬件上体现出来的就是多了一条时钟线。一般 USART 是可以作为 UART

6U UART      

1 I.MX6U 一共 有 8 个 UART,其主要特性如下:

①、兼容 TIA/EIA-232F 标准,速度最高可到 5Mbit/S。

②、支持串行 IR 接口,兼容 IrDA,最高可到 115.2Kbit/s。

③、支持 9 位或者多节点模式(RS-485)。

④、1 或 2 位停止位。

⑤、可编程的奇偶校验(奇校验和偶校验)。

⑥、自动波特率检测(最高支持 115.2Kbit/S)。 I.MX6U 的 UART 功能很多,但是我们本章就只用到其最基本的串口功能,关于 UART 其 它功能的介绍请参考《I.MX6ULL 参考手册》第 3561 页的“Chapter 55 Universal Asynchronous Receiver/Transmitter(UART)”章节。

二 结构原理图

2.1  时钟源

参考IMX6ULL芯片手册《Chapter 18: Clock Controller Module (CCM)》,
根据IMX6ULL的时钟树,设置CSCDR1寄存器就可以给UART提供总时钟,如下图:

下图是CSCDR1(CCM Serial Clock Divider Register 1)的位说明,对于UART,我们选择时钟源位80M:

CCM_SDCDR1->UART_CLK_SEL  = 0,  1分频  ~3F 

见I.MX6ull 时钟系统

 2.2  内部结构

UART 一般的接口电平有 TTL (TTL是 Time To Live的缩写,是生存时间值的意思)  RS-232,一般开发板上都有 TXD 和 RXD 这样的引脚, 这些引脚低电平表示逻辑 0,高电平表示逻辑 1,这个就是 TTL 电平。RS-232 采用差分线,-3~- 15V 表示逻辑 1,+3~+15V 表示逻辑 0。一般图 21.1.1.2 中的接口就是 TTL 电平

图 21.1.1.2 中的模块就是 USB 转 TTL模块,TTL 接口部分有 VCC、GND、RXD、TXD、

RTS 和 CTS。RTS 和 CTS 基本用不到,使用的时候通过杜邦线和其他模块的 TTL 接口相连即 可。 RS-232 电平需要 DB9 接口,I.MX6U-ALPHA 开发板上的 COM3(UART3)口就是 RS-232 接 口的,如图 21.1.1.3 所示:

 

由于现在的电脑都没有 DB9 接口了,取而代之的是 USB 接口,所以就催生出了很多 USB

转串口 TTL 芯片,比如 CH340、PL2303 等。通过这些芯片就可以实现串口 TTL 转 USB。I.MX6UALPHA 开发板就使用 CH340 芯片来完成 UART1 和电脑之间的连接,只需要一条USB 线即可, 对于 V2.4 版以前的底板,如图 21.1.1.4 所示。

2.3 工作原理

        UART 作为串口的一种,其工作原理也是将数据一位一位的进行传输,发送和接收各用一 条线,因此通过 UART 接口与外界相连最少只需要三条线:TXD(发送)、RXD(接收)和 GND(地 线)。图 21.1.1.1 就是 UART 的通信格式:

2.3.1 各部分意义如下:

空闲位:数据线在空闲状态的时候为逻辑“1”状态,也就是高电平,表示没有数据线空闲, 没有数据传输。

起始位:当要传输数据的时候先传输一个逻辑“0”,也就是将数据线拉低,表示开始数据 传输。

数据位:数据位就是实际要传输的数据,数据位数可选择 5~8 位,我们一般都是按照字节 传输数据的,一个字节 8 位,因此数据位通常是 8 位的。低位在前,先传输,高位最后传输。

奇偶校验位:这是对数据中“1”的位数进行奇偶校验用的,可以不使用奇偶校验功能。

停止位:数据传输完成标志位,停止位的位数可以选择 1 位、1.5 位或 2 位高电平,一般都 选择 1 位停止位。

波特率:波特率就是 UART 数据传输的速率,也就是每秒传输的数据位数,一般选择 9600、

19200、115200 等。

          

2.3.2 串口模块内部结构

串口模块共有两个时钟输入 Peripheral Clock 和 Module Clock。

  • Peripheral Clock

外部时钟。这个时钟主要用于读、写接收和发送的数据,例如读接收FIFO、写发送FIFO。 这个时钟与波特率设置无关,如果没有特殊需求我们将这个时钟保持默认即可,在初始代码中并没有特意设置这个时钟。

  • Module Clock

模块时钟,它既可用于接收、发送数据也用于设置波特率,这个时钟决定了串口最高支持的波特率。Module Clock 时钟来自根时钟 UART_CLK_ROOT。

通过搜索可以找到UART1时钟使能的控制位。CCM_CCGR5 时钟树默认频率80M

2.4 重要寄存器

UARTx_UCR1  UARTx_UCR2   UARTx_UCR3  ,UARTx_USR2, CCM_CCGR5(main 函数一开始使能了所以外设时钟) 

2.4.1 控制寄存器 UARTx_UCRx

1 UARTx_UCR1 

  • ADBR(bit14):自动波特率检测使能位,为 0 的时候关闭自动波特率检测,为 1 的时候使 能自动波特率检测。
  • UARTEN(bit0):UART 使能位,为 0 的时候关闭 UART,为 1 的时候使能 UART。

2 UARTx_UCR2

  • IRTS(bit14):为 0 的时候使用 RTS 引脚功能,为 1 的时候忽略 RTS 引脚。
  • PREN(bit8):奇偶校验使能位,为 0 的时候关闭奇偶校验,为 1 的时候使能奇偶校验。 PROE(bit7):奇偶校验模式选择位,开启奇偶校验以后此位如果为 0 的话就使用偶校 验,此位为 1 的话就使能奇校验。
  • STOP(bit6):停止位数量,为 0 的话 1 位停止位,为 1 的话 2 位停止位。
  • WS(bit5):数据位长度,为 0 的时候选择 7 位数据位,为 1 的时候选择 8 位数据位。
  • TXEN(bit2):发送使能位,为 0 的时候关闭 UART 的发送功能,为 1 的时候打开 UART
  • 的发送功能。
  • RXEN(bit1):接收使能位,为 0 的时候关闭 UART 的接收功能,为 1 的时候打开 UART
  • 的接收功能。
  • SRST(bit0):软件复位,为 0 的是时候软件复位 UART,为 1 的时候表示复位完成。复位 完成以后此位会自动置 1,表示复位完成。此位只能写 0,写 1 会被忽略掉。

3  UARTx_UCR3

本章实验就用到了寄存器 UARTx_UCR3 中的位 RXDMUXSEL(bit2),这个位应该始终为 1, 这个在《I.MX6ULL 参考手册》第 3624 页有说明。

 红外输入混合模式

2.4.2、状态寄存器 UARTx_USR2

  • TXDC(bit3):发送完成标志位,为 1 的时候表明发送缓冲(TxFIFO)和移位寄存器为空,也 就是发送完成,向 TxFIFO 写入数据此位就会自动清零。 RDR(bit0):数据接收标志位,为 1 的时候表明至少接收到一个数据,从寄存器
  • UARTx_URXD 读取数据接收到的数据以后此位会自动清零。

2.4.3 分频寄存器  UARTx_UFCR 、 UARTx_UBIR 和 UARTx_UBMR

  UART 的波特率 

通过这三个寄存器可以设置 UART 的波特率,波特率的计算公式如下:

Ref Freq:经过分频以后进入 UART 的最终时钟频率。 UBMR:寄存器 UARTx_UBMR 中的值。 UBIR:寄存器 UARTx_UBIR 中的值。 通过 UARTx_UFCR 的 RFDIV 位、UARTx_UBMR 和 UARTx_UBIR 这三者的配合即可得 到我们想要的波特率。比如现在要设置 UART 波特率为 115200,那么可以设置 RFDIV 为

5(0b101),也就是 1 分频,因此 Ref Freq=80MHz。设置 UBIR=71,UBMR=3124,根据上面的 公式可以得到:

实际使用时直接调用对应方法即可不必过于关心推导过程

2.4.4 UARTx_URXD , UARTx_UTXD 

最后来看一下寄存器 UARTx_URXD 和 UARTx_UTXD,这两个寄存器分别为 UART 的接 收和发送数据寄存器,这两个寄存器的低八位为接收到的和要发送的数据。读取寄存器

UARTx_URXD 即可获取到接收到的数据,如果要通过 UART 发送数据,直接将数据写入到寄 存器 UARTx_UTXD 即可。

三 使用实验

通过 UART1读写并显示输出

3.1 配置步骤

  • UART1 的配置步骤如下:

  • 1、设置 UART1 的时钟源

    设置 UART 的时钟源为 pll3_80m,设置寄存器 CCM_CSCDR1 的 UART_CLK_SEL 位为 0

    即可。

  • 2、初始化 UART1

    初始化 UART1 所使用 IO,设置 UART1 的寄存器 UART1_UCR1~UART1_UCR

  • 3,设置内 容包括波特率,奇偶校验、停止位、数据位等等。

  • 4、使能 UART1

    UART1 初始化完成以后就可以使能 UART1 了,设置寄存器 UART1_UCR1 的位 UARTEN

    为 1。

    5、编写 UART1 数据收发函数

    编写两个函数用于 UART1 的数据收发操作。

3.2 代码 

bsp_uart.h

#ifndef _BSP_UART_H
#define _BSP_UART_H
#include "imx6ul.h"
/***************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名	: 	 bsp_led.c
作者	   : 左忠凯
版本	   : V1.0
描述	   : 串口驱动文件头文件。
其他	   : 无
论坛 	   : www.wtmembed.com
日志	   : 初版V1.0 2019/1/15 左忠凯创建
***************************************************************/

/* 函数声明 */
void uart_init(void);
void uart_io_init(void);
void uart_disable(UART_Type *base);
void uart_enable(UART_Type *base);
void uart_softreset(UART_Type *base);
void uart_setbaudrate(UART_Type *base, unsigned int baudrate, unsigned int srcclock_hz);
void putc(unsigned char c);
void puts(char *str);
unsigned char getc(void);
void raise(int sig_nr);


#endif

bsp_uart.c

/***************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名	: 	 bsp_led.c
作者	   : 左忠凯
版本	   : V1.0
描述	   : 串口驱动文件。
其他	   : 无
论坛 	   : www.wtmembed.com
日志	   : 初版V1.0 2019/1/15 左忠凯创建
***************************************************************/
#include "bsp_uart.h"

/*
 * @description : 初始化串口1,波特率为115200
 * @param		: 无
 * @return		: 无
 */
void uart_init(void)
{
	/* 1、初始化串口IO 			*/
	uart_io_init();

	/* 2、初始化UART1  			*/
	uart_disable(UART1);	/* 先关闭UART1 		*/
	uart_softreset(UART1);	/* 软件复位UART1 		*/

	UART1->
UCR1 = 0;		/* 先清除UCR1寄存器 */
	
	/*
     * 设置UART的UCR1寄存器,关闭自动波特率
     * bit14: 0 关闭自动波特率检测,我们自己设置波特率
	 */
	UART1->UCR1 &= ~(1<<14);
	
	/*
     * 设置UART的UCR2寄存器,设置内容包括字长,停止位,校验模式,关闭RTS硬件流控
     * bit14: 1 忽略RTS引脚
	 * bit8: 0 关闭奇偶校验
     * bit6: 0 1位停止位
 	 * bit5: 1 8位数据位
 	 * bit2: 1 打开发送
 	 * bit1: 1 打开接收
	 */
	UART1->UCR2 |= (1<<14) | (1<<5) | (1<<2) | (1<<1);

	/*
     * UART1的UCR3寄存器
     * bit2: 1 必须设置为1!参考IMX6ULL参考手册3624页
	 */
	UART1->UCR3 |= 1<<2; 
	
	/*
	 * 设置波特率
	 * 波特率计算公式:Baud Rate = Ref Freq / (16 * (UBMR + 1)/(UBIR+1)) 
	 * 如果要设置波特率为115200,那么可以使用如下参数:
	 * Ref Freq = 80M 也就是寄存器UFCR的bit9:7=101, 表示1分频
	 * UBMR = 3124
 	 * UBIR =  71
 	 * 因此波特率= 80000000/(16 * (3124+1)/(71+1))=80000000/(16 * 3125/72) = (80000000*72) / (16*3125) = 115200
	 */
	UART1->UFCR = 5<<7; //ref freq等于ipg_clk/1=80Mhz
	UART1->UBIR = 71;
	UART1->UBMR = 3124;

#if 0
	 uart_setbaudrate(UART1, 115200, 80000000); /* 设置波特率 */
#endif

	/* 使能串口 */
	uart_enable(UART1);
}

/*
 * @description : 初始化串口1所使用的IO引脚
 * @param		: 无
 * @return		: 无
 */
void uart_io_init(void)
{
	/* 1、初始化IO复用 
     * UART1_RXD -> UART1_TX_DATA
     * UART1_TXD -> UART1_RX_DATA
	 */
	IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX,0);	/* 复用为UART1_TX */
	IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX,0);	/* 复用为UART1_RX */

	/* 2、配置UART1_TX_DATA、UART1_RX_DATA的IO属性 
 	*bit 16:0 HYS关闭
 	*bit [15:14]: 00 默认100K下拉
 	*bit [13]: 0 keeper功能
 	*bit [12]: 1 pull/keeper使能
 	*bit [11]: 0 关闭开路输出
 	*bit [7:6]: 10 速度100Mhz
 	*bit [5:3]: 110 驱动能力R0/6
 	*bit [0]: 0 低转换率
 	*/
	IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX,0x10B0);
	IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX,0x10B0);
}

/*
 * @description 		: 波特率计算公式,
 *    			  	  	  可以用此函数计算出指定串口对应的UFCR,
 * 				          UBIR和UBMR这三个寄存器的值
 * @param - base		: 要计算的串口。
 * @param - baudrate	: 要使用的波特率。
 * @param - srcclock_hz	:串口时钟源频率,单位Hz
 * @return		: 无
 */
void uart_setbaudrate(UART_Type *base, unsigned int baudrate, unsigned int srcclock_hz)
{
    uint32_t numerator = 0u;		//分子
    uint32_t denominator = 0U;		//分母
    uint32_t divisor = 0U;
    uint32_t refFreqDiv = 0U;
    uint32_t divider = 1U;
    uint64_t baudDiff = 0U;
    uint64_t tempNumerator = 0U;
    uint32_t tempDenominator = 0u;

    /* get the approximately maximum divisor */
    numerator = srcclock_hz;
    denominator = baudrate << 4;
    divisor = 1;

    while (denominator != 0)
    {
        divisor = denominator;
        denominator = numerator % denominator;
        numerator = divisor;
    }

    numerator = srcclock_hz / divisor;
    denominator = (baudrate << 4) / divisor;

    /* numerator ranges from 1 ~ 7 * 64k */
    /* denominator ranges from 1 ~ 64k */
    if ((numerator > (UART_UBIR_INC_MASK * 7)) || (denominator > UART_UBIR_INC_MASK))
    {
        uint32_t m = (numerator - 1) / (UART_UBIR_INC_MASK * 7) + 1;
        uint32_t n = (denominator - 1) / UART_UBIR_INC_MASK + 1;
        uint32_t max = m > n ? m : n;
        numerator /= max;
        denominator /= max;
        if (0 == numerator)
        {
            numerator = 1;
        }
        if (0 == denominator)
        {
            denominator = 1;
        }
    }
    divider = (numerator - 1) / UART_UBIR_INC_MASK + 1;

    switch (divider)
    {
        case 1:
            refFreqDiv = 0x05;
            break;
        case 2:
            refFreqDiv = 0x04;
            break;
        case 3:
            refFreqDiv = 0x03;
            break;
        case 4:
            refFreqDiv = 0x02;
            break;
        case 5:
            refFreqDiv = 0x01;
            break;
        case 6:
            refFreqDiv = 0x00;
            break;
        case 7:
            refFreqDiv = 0x06;
            break;
        default:
            refFreqDiv = 0x05;
            break;
    }
    /* Compare the difference between baudRate_Bps and calculated baud rate.
     * Baud Rate = Ref Freq / (16 * (UBMR + 1)/(UBIR+1)).
     * baudDiff = (srcClock_Hz/divider)/( 16 * ((numerator / divider)/ denominator).
     */
    tempNumerator = srcclock_hz;
    tempDenominator = (numerator << 4);
    divisor = 1;
    /* get the approximately maximum divisor */
    while (tempDenominator != 0)
    {
        divisor = tempDenominator;
        tempDenominator = tempNumerator % tempDenominator;
        tempNumerator = divisor;
    }
    tempNumerator = srcclock_hz / divisor;
    tempDenominator = (numerator << 4) / divisor;
    baudDiff = (tempNumerator * denominator) / tempDenominator;
    baudDiff = (baudDiff >= baudrate) ? (baudDiff - baudrate) : (baudrate - baudDiff);

    if (baudDiff < (baudrate / 100) * 3)
    {
        base->UFCR &= ~UART_UFCR_RFDIV_MASK;
        base->UFCR |= UART_UFCR_RFDIV(refFreqDiv);
        base->UBIR = UART_UBIR_INC(denominator - 1); //要先写UBIR寄存器,然后在写UBMR寄存器,3592页 
        base->UBMR = UART_UBMR_MOD(numerator / divider - 1);
    }
}

/*
 * @description : 关闭指定的UART
 * @param - base: 要关闭的UART
 * @return		: 无
 */
void uart_disable(UART_Type *base)
{
	base->UCR1 &= ~(1<<0);	
}

/*
 * @description : 打开指定的UART
 * @param - base: 要打开的UART
 * @return		: 无
 */
void uart_enable(UART_Type *base)
{
	base->UCR1 |= (1<<0);	
}

/*
 * @description : 复位指定的UART
 * @param - base: 要复位的UART
 * @return		: 无
 */
void uart_softreset(UART_Type *base)
{
	base->UCR2 &= ~(1<<0); 			/* UCR2的bit0为0,复位UART  	  	*/
	while((base->UCR2 & 0x1) == 0); /* 等待复位完成 					*/
}

/*
 * @description : 发送一个字符
 * @param - c	: 要发送的字符
 * @return		: 无
 */
void putc(unsigned char c)
{
	while(((UART1->USR2 >> 3) &0X01) == 0);/* 等待上一次发送完成 */
	UART1->UTXD = c & 0XFF; 				/* 发送数据 */
}

/*
 * @description : 发送一个字符串
 * @param - str	: 要发送的字符串
 * @return		: 无
 */
void puts(char *str)
{
	char *p = str;

	while(*p)
		putc(*p++);
}

/*
 * @description : 接收一个字符
 * @param 		: 无
 * @return		: 接收到的字符
 */
unsigned char getc(void)
{
	while((UART1->USR2 & 0x1) == 0);/* 等待接收完成 */
	return UART1->URXD;				/* 返回接收到的数据 */
}

/*
 * @description : 防止编译器报错
 * @param 		: 无
 * @return		: 无
 */
void raise(int sig_nr) 
{

}


main.c

 
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_led.h"
#include "bsp_beep.h"
#include "bsp_key.h"
#include "bsp_int.h"
#include "bsp_uart.h"
 
/*
 * @description	: main函数
 * @param 		: 无
 * @return 		: 无
 */
int main(void)
{
	unsigned char a=0;
	unsigned char state = OFF;
 
	int_init(); 				/* 初始化中断(一定要最先调用!) */
	imx6u_clkinit();			/* 初始化系统时钟 			*/
	delay_init();				/* 初始化延时 			*/
	clk_enable();				/* 使能所有的时钟 			*/
	led_init();					/* 初始化led 			*/
	beep_init();				/* 初始化beep	 		*/
	uart_init();				/* 初始化串口,波特率115200 */
 
	while(1)				
	{	
		puts("请输入1个字符:");
		a=getc();
		putc(a);	//回显功能
		puts("\r\n");
 
		//显示输入的字符
		puts("您输入的字符为:");
		putc(a);
		puts("\r\n\r\n");
		
		state = !state;
		led_switch(LED0,state);
	}
	return 0;
}

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

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

相关文章

Self-Attention 自注意力机制

输出形式 李宏毅讲到&#xff1a; 模型的输入是只有一种形式——词向量但是输出的形式却是不唯一的&#xff0c;主要有以下三种&#xff1a; 每一个向量对应一个输出(多对多&#xff0c;且一一对应) 每个序列只有一个输出(多对一) 一个序列对应一个序列(多对多&#xff0c;长…

MySQL 索引的10 个核心要点

文章目录 &#x1f349;1. 索引底层采用什么数据结构&#xff1f;为什么不用hash&#x1f349;2. B树与B树区别&#xff1f;为何用B树&#xff1f;&#x1f349;3. 自增主键理解&#xff1f;&#x1f349;4. 为什么自增主键不连续&#x1f349;5. Innodb为什么推荐用自增ID&…

代码随想录第59天

1.下一个更大元素II 有两种方法&#xff1a; 1.把两个一样的数组拼起来&#xff1a; // 版本一 class Solution { public:vector<int> nextGreaterElements(vector<int>& nums) {// 拼接一个新的numsvector<int> nums1(nums.begin(), nums.end());nu…

Chapter7: SpringBoot与数据访问

尚硅谷SpringBoot顶尖教程 1. JDBC 1.1 依赖及配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency><groupId>mysql</groupId…

《Reinforcement Learning: An Introduction》第4章笔记

Chapter 4 Dynamic Programming 动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09;是一类在给定完备环境模型的MDP后用来计算最优策略的算法。动态规划算法在强化学习中因为&#xff1a;1. 假设有一个完美的环境模型&#xff1b;2. 极大的计算代价 实际用处…

树莓派4B连接不了产品开的热点

目的 关于树莓派连接不了产品开的5G热点&#xff0c; 当时还是一头雾水。 参考这篇博客 把思路方向转向了频率&#xff0c; 信道&#xff0c; 通过给的产品A相关规格说明wifi 5.18GHz, 信道36。 于是乎我两款产品A、产品B为例。 树莓派是能连接产品B开的热点&#xff08;5.74…

【Unity SRP】实现基础的Temporal AA(未完)

写在前面 【技术美术图形部分】简述主流及新的抗锯齿技术&#xff0c;花了点时间盘点了一些主流AA技术&#xff0c;再在SRP下的URP管线中实现一下目前游戏用得比较多的TAA。参考Unity的TAA&#xff08;比较容易懂&#xff09;以及sienaiwun的实现思路&#xff0c;也参考了很多…

OpenCV转换HDR图像与源码分析

我们常见的图像位深一般是8bit&#xff0c;颜色范围[0, 255]&#xff0c;称为标准动态范围SDR(Standard Dynamic Range)。SDR的颜色值有限&#xff0c;如果要图像色彩更鲜艳&#xff0c;那么就需要10bit&#xff0c;甚至12bit&#xff0c;称为高动态范围HDR(High Dynamic Range…

Docker部署ES集群、kibana、RabbitMq和chrome安装elasticsearch-head插件

文章目录 [toc] 1.安装ES集群和kibana1.1安装ES集群1.1.1 准备挂载目录1.1.2 准备配置文件1.1.3 启动命令1.1.3.0 启动前设置系统环境变量1.1.3.1 Windows10环境启动命令1.1.3.2 Linux环境启动命令 1.2安装kibana1.2.1 准备挂载目录1.2.2 准备配置文件1.2.3 启动命令1.2.3.1 Wi…

Spring IOC基于XML和注解管理Bean(一)

Spring IOC基于XML和注解管理Bean&#xff08;二&#xff09; 文章目录 1、IoC容器1.1、控制反转&#xff08;IoC&#xff09;1.2、依赖注入1.3、IoC容器在Spring的实现 2、基于XML管理Bean2.1、搭建模块spring-first2.2、实验一&#xff1a;获取bean①方式一&#xff1a;根据i…

过滤器和拦截器实现

说明&#xff1a;当用户未经登录&#xff0c;直接访问后台网址时&#xff0c;为了避免可以直接访问后台内容&#xff0c;就需要使用过滤器或拦截器将此类请求在服务器响应数据之前做核对&#xff0c;如果未登录&#xff0c;则驳回请求&#xff0c;返回登录页面&#xff0c;如果…

PyQt5桌面应用开发(20):界面设计结果自动测试(一)

本文目录 PyQt5桌面应用系列PyQt5的测试驱动开发&#xff08;Test-Driven Development&#xff0c;TDD&#xff09;QTestUI动作函数信号测试 最平凡的例子unittest框架总结 PyQt5桌面应用系列 PyQt5桌面应用开发&#xff08;1&#xff09;&#xff1a;需求分析 PyQt5桌面应用开…

【Apache Pinot】简单聊聊前面没讲的 Deep Store 和 Cluster

背景 前面3篇文章讲解了 Pinot 用的最多的几个组件&#xff0c;现在就聊最后剩下的两个&#xff0c;一个是 Cluster&#xff0c;另外一个就是 Deep Store。 Cluster 其实 Cluster 比较简单&#xff0c;就是一个概念的集合&#xff0c;他说有 Server&#xff0c;Broker 和 Co…

代码随想录算法训练营第五十六天 | 力扣 583. 两个字符串的删除操作, 72. 编辑距离

583. 两个字符串的删除操作 题目 583. 两个字符串的删除操作 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 解析 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义 …

学会这个Python库,做接口测试不是手拿把掐吗?

我们在做接口测试时&#xff0c;大多数返回的都是json属性&#xff0c;我们需要通过接口返回的json提取出来对应的值&#xff0c;然后进行做断言或者提取想要的值供下一个接口进行使用。 但是如果返回的json数据嵌套了很多层&#xff0c;通过查找需要的词&#xff0c;就很不方便…

三、Typora软件的介绍及安装

1、Typora软件的介绍 (1)Typora时一款Markdown编辑器和阅读器。 (2)Typora使用起来十分简洁&#xff0c;十分方便&#xff0c;可用于记录日常的笔记等。 (3)Markdown 是一种轻量级标记语言&#xff0c;它允许人们使用易读易写的纯文本格式编写文档。 2、Typora软件的安装 …

都说未来AI测试辅助自动化测试,难道手工测试真的要被淘汰了吗?

目录 前言 AI测试的迷思 第一个问题&#xff1a;AI辅助测试真的能用吗&#xff1f; 第二个问题&#xff1a;AI辅助测试已经发展到什么程度了&#xff1f; 第三个问题&#xff1a;哪些软件系统能用AI辅助测试&#xff1f; 总结 总结&#xff1a; 前言 近年来&#xff0c;…

FPGA实现简易的自动售货机模型

文章目录 前言一、系统设计1、模块框图2、状态机框图3、RTL视图 二、源码1.蜂鸣器驱动模块2.按键消抖模块3、PWM模块4、sale_goods模块(状态机部分)5、数码管驱动模块6、Sales(顶层模块) 三、效果四、总结五、参考资料 前言 环境&#xff1a; 1、Quartus18.1 2、vscode 3、板子…

华为OD机试 JavaScript 实现【简单密码】【牛客练习题 HJ21】,附详细解题思路

一、题目描述 现在有一种密码变换算法。 九键手机键盘上的数字与字母的对应&#xff1a; 1--1&#xff0c; abc--2, def--3, ghi--4, jkl--5, mno--6, pqrs--7, tuv--8 wxyz--9, 0--0&#xff0c;把密码中出现的小写字母都变成九键键盘对应的数字&#xff0c;如&#xff1a;a …

Python实现面向对象版学员管理系统

如有错误&#xff0c;敬请谅解&#xff01; 此文章仅为本人学习笔记&#xff0c;仅供参考&#xff0c;如有冒犯&#xff0c;请联系作者删除&#xff01;&#xff01; 1.1需求分析 1.1.1使用面向对象编程思想完成学员管理系统的开发&#xff0c;具体如下&#xff1a; 系统要求…