【正点原子STM32连载】第三十七章 485实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

news2024/11/25 12:42:29

1)实验平台:正点原子stm32f103战舰开发板V4
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html#

第三十七章 485实验

本章我们将向大家介绍如何使用STM32F1的串口实现485通信(半双工)。在本章中,我们将使用STM32F1的串口2来实现两块开发板之间的485通信,并将结果显示在TFTLCD模块上。
本章分为如下几个部分:
37.1 485简介:
37.2 硬件设计
37.3 程序设计
37.4 下载验证

37.1 485简介

485(一般称作RS485/EIA-485)隶属于OSI模型物理层,是串行通讯的一种。电气特性规定为2线,半双工,多点通信的类型。它的电气特性和RS-232大不一样。用缆线两端的电压差值来表示传递信号。RS485仅仅规定了接受端和发送端的电气特性。它没有规定或推荐任何数据协议。
RS485的特点包括:
1,接口电平低,不易损坏芯片。RS485的电气特性:逻辑“1”以两线间的电压差为+(26)V表示;逻辑“0”以两线间的电压差为-(26)V表示。接口信号电平比RS232降低了,不易损坏接口电路的芯片,且该电平与TTL电平兼容,可方便与TTL电路连接。
2,传输速率高。10米时,RS485的数据最高传输速率可达35Mbps,在1200m时,传输速度可达100Kbps。
3,抗干扰能力强。RS485接口是采用平衡驱动器和差分接收器的组合,抗共模干扰能力增强,即抗噪声干扰性好。
4,传输距离远,支持节点多。RS485总线最长可以传输1200m左右,更远的距离则需要中继传输设备支持但这时(速率≤100Kbps)才能稳定传输,一般最大支持32个节点,如果使用特制的485芯片,可以达到128个或者256个节点,最大的可以支持到400个节点。
RS485推荐使用在点对点网络中,比如:线型,总线型网络等,而不能是星型,环型网络。理想情况下RS485需要2个终端匹配电阻,其阻值要求等于传输电缆的特性阻抗(一般为120Ω)。没有特性阻抗的话,当所有的设备都静止或者没有能量的时候就会产生噪声,而且线移需要双端的电压差。没有终接电阻的话,会使得较快速的发送端产生多个数据信号的边缘,导致数据传输出错。485推荐的一主多从连接方式如图37.1.1所示:
在这里插入图片描述

图37.1.1 RS485连接
在上面的连接中,如果需要添加匹配电阻,我们一般在总线的起止端加入,也就是主机和设备4上面各加一个120Ω的匹配电阻。
由于RS485具有传输距离远、传输速度快、支持节点多和抗干扰能力更强等特点,所以RS485有很广泛的应用。实际多设备时收发器有范围为-7V到+12V的共模电压,为了稳定传输,也有使用3线的布线方式,即在原有的A、B两线上多增加一条地线。(4线制只能实现点对点的全双工通讯方式,这种也叫RS422,由于布线的难度和通讯局限,相对使用得比较少)。
TP8485E/SP3485可作为RS485的收发器,该芯片支持3.3V~5.5V供电,最大传输速度可达250Kbps,支持多达256个节点(单位负载为1/8的条件下),并且支持输出短路保护。该芯片的框图如图37.1.2所示:
在这里插入图片描述

图37.1.2 TP8485E/SP3485框图
图中A、B总线接口,用于连接485总线。RO是接收输出端,DI是发送数据收入端,RE是接收使能信号(低电平有效),DE是发送使能信号(高电平有效)。
37.2 硬件设计

  1. 例程功能
    经过前面的学习我们知道实际的RS485仍是串行通讯的一种电平传输方式,那么我们实际通讯时可以使用串口进行实际数据的收发处理,使用485转换芯片将串口信号转换为485的电平信号进行传输,本章,我们只需要配置好串口2,就可以实现正常的485通信了,串口2的配置和串口1基本类似,只是串口2的时钟来自APB1,最大频率为36Mhz。
    本章将实现这样的功能:通过连接两个战舰STM32F103的RS485接口,然后由KEY0控制发送,当按下一个开发板的KEY0的时候,就发送5个数据给另外一个开发板,并在两个开发板上分别显示发送的值和接收到的值。
  2. 硬件资源
    1)LED灯
    LED0 – PB5
    2)USART2,用于实际的485信号串行通讯。
    3)正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
    4)RS485收发芯片TP8485/SP3485
    5)开发板两块(485半双式模式无法自收发,我们需要用两个开发板或者USB转485调试器+串口助手来帮助我们完成测试,大家根据自己的实际条件选择)
  3. 原理图
    根据我们需要实现的程序功能,我们设计电路原理如下:
    在这里插入图片描述

图37.2.2 RS485连接原理设计
从上图可以看出:开发板的串口2和TP8485上的引脚连接到P7端上的端子,但不直接相连,所以测试485功能时我们需要用跳线帽短接P7上的两组排针使之连通。STM32F1的PD7控制RS485的收发模式:
当PD7=0的时候,为接收模式;当PD7=1的时候,为发送模式。
这里需要注意,RS485_RE信号和CH395Q_RST共用PD7,所以对于我们的战舰开发板来说他们也不可以同时使用,只能分时复用。
另外,图中的R19和R22是两个偏置电阻,用来保证总线空闲时,A、B之间的电压差都会大于200mV(逻辑1)。从而避免因总线空闲时因A、B压差不稳定,可能出现的乱码。
最后,我们用2根导线将两个开发板RS485端子的A和A,B和B连接起来。这里注意不要接反了(A接B),接反了会导致通讯异常!!
37.3 程序设计
37.3.1 RS485的HAL库驱动
由于485实际上是串口通讯,我们参照串口实验一节使用类似的HAL库驱动即可,在这里分析一下RS485配置步骤。
RS485配置步骤
1)使能串口和GPIO口时钟
本实验用到USART2串口,使用PA2和PA3作为串口的TX和RX脚,因此需要先使能USART2和GPIOA时钟。参考代码如下:
__HAL_RCC_USART2_CLK_ENABLE(); /* 使能USART2时钟 /
__HAL_RCC_GPIOA_CLK_ENABLE(); /
使能GPIOA时钟 */
2) 串口参数初始化(波特率、字长、奇偶校验等)
HAL库通过调用串口初始化函数HAL_UART_Init完成对串口参数初始化,详见例程源码。
该函数通常会调用:HAL_UART_MspInit函数来完成对串口底层的初始化,包括:串口及GPIO时钟使能、GPIO模式设置、中断设置等。但是本实验避免与USART1冲突,所以把串口底层初始化没有放在HAL_UART_MspInit函数里。
3)GPIO模式设置(速度,上下拉,复用功能等)
GPIO模式设置通过调用HAL_GPIO_Init函数实现,详见本例程源码。
4)开启串口相关中断,配置串口中断优先级
本实验我们使用串口中断来接收数据。我们使用HAL _UART_Receive_IT函数开启串口中断接收,并设置接收buffer及其长度。通过HAL_NVIC_EnableIRQ函数使能串口中断,通过HAL_NVIC_SetPriority函数设置中断优先级。
5)编写中断服务函数
串口2中断服务函数为:USART2_IRQHandler,当发生中断的时候,程序就会执行中断服务函数,在这里就可以对接收到的数据进行处理,详见本例程源码。
6)串口数据接收和发送
最后我们可以通过读写USART_DR寄存器,完成串口数据的接收和发送,HAL库也给我们提供了:HAL_UART_Receive和HAL_UART_Transmit两个函数用于串口数据的接收和发送。
大家可以根据实际情况选择使用哪种方式来收发串口数据。
37.3.2 程序流程图
在这里插入图片描述

图37.3.2.1 RS485实验程序流程图
37.3.3 程序解析

  1. RS485驱动
    这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。RS485驱动相关源码包括两个文件:rs485.c和rs485.h。
    为方便修改,我们在rs485.h中使用宏定义485相关的控制引脚和串口编号,如果需要使用其它的引脚或者串口,修改宏和串口的定义即可,它们在rs485.h中定义,它们列出如下:
/* RS485 引脚 和 串口 定义 */
#define RS485_RE_GPIO_PORT      		GPIOD
#define RS485_RE_GPIO_PIN           	GPIO_PIN_7
#define RS485_RE_GPIO_CLK_ENABLE()	do{ __HAL_RCC_GPIOD_CLK_ENABLE();}while(0) 

#define RS485_TX_GPIO_PORT         	GPIOA
#define RS485_TX_GPIO_PIN           	GPIO_PIN_2
#define RS485_TX_GPIO_CLK_ENABLE() 	do{ __HAL_RCC_GPIOA_CLK_ENABLE();}while(0)

#define RS485_RX_GPIO_PORT          	GPIOA
#define RS485_RX_GPIO_PIN         	GPIO_PIN_3
#define RS485_RX_GPIO_CLK_ENABLE()	do{ __HAL_RCC_GPIOA_CLK_ENABLE();}while(0)

#define RS485_UX                      	USART2
#define RS485_UX_IRQn                	USART2_IRQn
#define RS485_UX_IRQHandler        	USART2_IRQHandler
#define RS485_UX_CLK_ENABLE()    	do{ __HAL_RCC_USART2_CLK_ENABLE();}while(0)

/* 控制RS485_RE脚, 控制RS485发送/接收状态
 * RS485_RE = 0, 进入接收模式
 * RS485_RE = 1, 进入发送模式
*/
#define RS485_RE(x)   do{ x ? \  
HAL_GPIO_WritePin(RS485_RE_GPIO_PORT, RS485_RE_GPIO_PIN,\ GPIO_PIN_SET) : \ 
HAL_GPIO_WritePin(RS485_RE_GPIO_PORT, RS485_RE_GPIO_PIN,\ GPIO_PIN_RESET); \
                            }while(0)
1)rs485_init函数
rs485_inti的配置与串口类似,也需要设置波特率等参数,另外还需要配置收发模式的驱动引脚,我们的程序设计如下:
/**
 * @brief       	RS485初始化函数
 *   @note      	该函数主要是初始化串口
 * @param       	baudrate: 波特率, 根据自己需要设置波特率值
 * @retval      	无
 */
void rs485_init(uint32_t baudrate)
{
    /* IO 及 时钟配置 */
    RS485_RE_GPIO_CLK_ENABLE();		/* 使能 RS485_RE 脚时钟 */
    RS485_TX_GPIO_CLK_ENABLE();		/* 使能 串口TX脚 时钟 */
    RS485_RX_GPIO_CLK_ENABLE();		/* 使能 串口RX脚 时钟 */
    RS485_UX_CLK_ENABLE();      		/* 使能 串口 时钟 */

    GPIO_InitTypeDef gpio_initure;
    gpio_initure.Pin = RS485_TX_GPIO_PIN;
    gpio_initure.Mode = GPIO_MODE_AF_PP;
    gpio_initure.Pull = GPIO_PULLUP;
    gpio_initure.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(RS485_TX_GPIO_PORT, &gpio_initure);	/* 串口TX 脚 模式设置 */

    gpio_initure.Pin = RS485_RX_GPIO_PIN;
    gpio_initure.Mode = GPIO_MODE_AF_INPUT;
    HAL_GPIO_Init(RS485_RX_GPIO_PORT, &gpio_initure);	/* 串口RX脚设置成输入模式 */

    gpio_initure.Pin = RS485_RE_GPIO_PIN;
    gpio_initure.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_initure.Pull = GPIO_PULLUP;
    gpio_initure.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(RS485_RE_GPIO_PORT, &gpio_initure); 	/* RS485_RE 脚 模式设置 */

    /* USART 初始化设置 */
    g_rs458_handler.Instance = RS485_UX;                		/* 选择485对应的串口 */
    g_rs458_handler.Init.BaudRate = baudrate;               	/* 波特率 */
    g_rs458_handler.Init.WordLength = UART_WORDLENGTH_8B;	/* 字长为8位数据格式 */
    g_rs458_handler.Init.StopBits = UART_STOPBITS_1;      	/* 一个停止位 */
    g_rs458_handler.Init.Parity = UART_PARITY_NONE;       	/* 无奇偶校验位 */
    g_rs458_handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;	/* 无硬件流控 */
    g_rs458_handler.Init.Mode = UART_MODE_TX_RX;          	/* 收发模式 */
    HAL_UART_Init(&g_rs458_handler);                        	/* 使能对应的串口 */

    /* 使能接收中断 */
    __HAL_UART_ENABLE_IT(&g_rs458_handler, UART_IT_RXNE); 	/* 开启接收中断 */
    HAL_NVIC_EnableIRQ(RS485_UX_IRQn);                   		/* 使能USART2中断 */
    HAL_NVIC_SetPriority(RS485_UX_IRQn, 3, 3);         /* 抢占优先级3,子优先级3 */

    RS485_RE(0); 											/* 默认为接收模式 */
}

可以看到代码基本跟串口的配置一样,只是多了收发控制引脚的配置。
2)发送函数
发送函数用于输出485信号到485总线上,我的默认的485方式一般空闲时为接收状态,只有发送数据时我们才控制485芯片进入发送状态,发送完成后马上回到空闲接收状态,这样可以保证操作过程中485的数据丢失最小。我们实现的发送函数如下:

/**
 * @brief  		RS485发送len个字节
 * @param  		buf : 发送区首地址
 * @param  		len : 发送字节数(为了和本代码接收匹配,这里不要超过RS485_REC_LEN个字节)
 * @retval  		无
 */
void rs485_send_data(uint8_t *buf, uint8_t len)
{
    RS485_RE(1); 	/* 进入发送模式 */
    HAL_UART_Transmit(&g_rs458_handler, buf, len, 1000);	/* 串口2发送数据 */
    g_RS485_rx_cnt = 0;
    RS485_RE(0); 	/* 进入接收模式 */
}

3)485接收中断函数
RS485的接收就与串口中断一样了,不过要注意空闲时要切换回接收状态,否则会收不到数据。我们定义了一个全局的缓冲区g_RS485_rx_buf进行接收测试,通过串口中断接收数据,编写的接收代码如下:

uint8_t g_RS485_rx_buf[RS485_REC_LEN];	/* 接收缓冲, 最大 RS485_REC_LEN 个字节. */
uint8_t g_RS485_rx_cnt = 0;            	/* 接收到的数据长度 */

void RS485_UX_IRQHandler(void)
{
    uint8_t res;

    if ((__HAL_UART_GET_FLAG(&g_rs458_handler, UART_FLAG_RXNE) != RESET))
    {   /* 接收到数据 */
        HAL_UART_Receive(&g_rs458_handler, &res, 1, 1000);

        if (g_RS485_rx_cnt < RS485_REC_LEN)       	/* 缓冲区未满 */
        {
            g_RS485_rx_buf[g_RS485_rx_cnt] = res;  	/* 记录接收到的值 */
            g_RS485_rx_cnt++;                       		/* 接收数据增加1 */
        }
    }
}
4485查询接收数据函数
	该函数用于查询485总线上接收到的数据,主要实现的逻辑是:一开始进入函数时,先记录下当前接收计数器的值,再来一个延时去判断接收是否结束(即该期间有无接收到数据),假如说接收计数器的值没有改变,就证明接收结束,我们就可以把当前接收缓冲区传递出去。函数实现如下:
void rs485_receive_data(uint8_t *buf, uint8_t *len)
{
    uint8_t rxlen = g_RS485_rx_cnt;
    uint8_t i = 0;
    *len = 0;     	/* 默认为0 */
    delay_ms(10); 	/* 等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束 */

    if (rxlen == g_RS485_rx_cnt && rxlen) /* 接收到了数据,且接收完成了 */
    {
        for (i = 0; i < rxlen; i++)
        {
            buf[i] = g_RS485_rx_buf[i];
        }

        *len = g_RS485_rx_cnt; 	/* 记录本次数据长度 */
        g_RS485_rx_cnt = 0;    	/* 清零 */
    }
}

RS485的代码就讲到这里,基本是串口的知识,大家不明白的配置可以翻看之前串口章节的知识。
2. main.c代码
在main.c中编写如下代码:

int main(void)
{
    uint8_t key;
    uint8_t i = 0, t = 0;
    uint8_t cnt = 0;
    uint8_t rs485buf[5];

    HAL_Init();                               	/* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);    	/* 设置时钟, 72Mhz */
    delay_init(72);                            	/* 延时初始化 */
    usart_init(115200);                       	/* 串口初始化为115200 */
    usmart_dev.init(72);                      	/* 初始化USMART */
    led_init();                                 	/* 初始化LED */
    lcd_init();                                 	/* 初始化LCD */
    key_init();                                 	/* 初始化按键 */
    rs485_init(9600);                          	/* 初始化RS485 */

    lcd_show_string(30,  50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30,  70, 200, 16, 16, "RS485 TEST", RED);
    lcd_show_string(30,  90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "KEY0:Send", RED);	/* 显示提示信息 */

    lcd_show_string(30, 130, 200, 16, 16, "Count:", RED);  		/* 显示当前计数值 */
    lcd_show_string(30, 150, 200, 16, 16, "Send Data:", RED);	/* 提示发送的数据 */
    lcd_show_string(30, 190, 200, 16, 16, "Receive Data:", RED);/*提示收到的数据*/

    while (1)
    {
        key = key_scan(0);

        if (key == KEY0_PRES)   				/* KEY0按下,发送一次数据 */
        {
            for (i = 0; i < 5; i++)
            {
                rs485buf[i] = cnt + i;     	/* 填充发送缓冲区 */
/* 显示数据 */
                lcd_show_xnum(30 + i * 32, 170, rs485buf[i], 3, 16, 0X80, BLUE);    
            }
            rs485_send_data(rs485buf, 5);	/* 发送5个字节 */
        }
        rs485_receive_data(rs485buf, &key);
        if (key)    							/* 接收到有数据 */
        {
            if (key > 5)key = 5;    			/* 最大是5个数据. */

            for (i = 0; i < key; i++)
            {   /* 显示数据 */
                lcd_show_xnum(30 + i * 32, 210, rs485buf[i], 3, 16, 0X80, BLUE);    
            }
        }

        t++;
        delay_ms(10);

        if (t == 20)
        {
            LED0_TOGGLE();  /* LED0闪烁, 提示系统正在运行 */
            t = 0;
            cnt++;
            lcd_show_xnum(30 + 48, 130, cnt, 3, 16, 0X80, BLUE);    /* 显示数据 */
        }
    }
}

我们是通过按键控制数据的发送。在此部分代码中,cnt是一个累加数,一旦KEY0按下,就以这个数位基准连续发送5个数据。当485总线收到数据时候,就将收到的数据直接显示在LCD屏幕上。
37.4 下载验证
在代码编译成功之后,我们通过下载代码到正点原子战舰STM32F103上(注意要2个开发板都下载这个代码),得到如图37.4.1所示:
在这里插入图片描述

图37.4.1 程序运行效果图
伴随DS0的不停闪烁,提示程序在运行。此时,我们按下KEY0就可以在另外一个开发板上面收到这个开发板发送的数据了。如图37.4.2和图37.4.3所示:
在这里插入图片描述

图37.4.2 发送RS485数据的开发板界面
在这里插入图片描述

图37.4.3 接收RS485数据的开发板
图37.4.2来自开发板A,发送了5个数据,图37.4.3来自开发板B,接收到了来自开发板A的5个数据。
本章介绍的485总线时通过串口控制收发的,我们只需要将P7的跳线帽稍作改变(将PA2/PA3连接COM2_RX/COM2_TX),该实验就变成了一个RS232串口通信实验了,通过对接两个开发板的RS232接口,即可得到同样的实验现象,不过RS232不需要使能脚,有兴趣的读者可以实验一下。
另外,利用USMART测试的部分,我们这里就不做介绍了,大家可自行验证下。

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

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

相关文章

【Java.SE】数组的定义与使用

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a;Java.SE&#xff0c;本专栏主要讲解运算符&#xff0c;程序逻辑控制&#xff0c;方法的使用&…

【机器学习】十大算法之一 “随机森林”

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typeblog个…

Error in `taosdump‘: malloc(): memory corruption: 0x0

在使用taostools的taosdump导出数据时&#xff0c;遇到如下问题&#xff1a; 解决步骤如下&#xff1a; 先看导出目录下的内存是否足够&#xff0c;不够的话&#xff0c;换其他目录导出如果在内存充足的情况下&#xff0c;出现上述问题那么可能是taostools版本不对&#xff0…

Agilent8564EC频谱分析仪

安捷伦8564EC频谱分析仪13145876435 8564EC 是安捷伦的 40 GHz 频谱分析仪。频谱分析仪测量已知和未知信号的频谱功率。频谱分析仪收集信息&#xff0c;例如输入信号与其频率相比的幅度。作为频率分析仪&#xff0c;频谱分析仪的主要用途是记录和分析电输入信号以及其他信号的频…

OWASP之CSRF跨站请求伪造

CSRF&#xff08;Cross-site request forgery&#xff09;跨站请求伪造 文章目录 一、CSRF定义二、CSRF危害三、CSRF漏洞构成1.漏洞风险存在2.用户登录受信任网站A&#xff0c;并在本地生成Cookie3.攻击者伪装数据操作请求的恶意链接或者页面4.诱使未登出用户主动访问或登录恶…

新式茶饮头部品牌「古茗茶饮」联手企企通,打造采购数字化新思路

导读 企企通在采购与供应链领域积累了丰富的项目开发经验&#xff0c;是国内一站式采购数字化管理平台领军企业之一&#xff0c;其售前、商务、项目人员都是这个赛道最专业的。该平台的建设可以自动化处理采购链路多个节点重复性任务&#xff0c;帮助我们提高采购效率&#xf…

向日葵× 实在RPA擦出AI的火花,贝锐与实在智能官宣战略合作

6月19日&#xff0c;实在智能&#xff08;Intelligence Indeed&#xff09;与贝锐&#xff08;Oray&#xff09;正式宣布达成战略合作。实在智能作为国内AI准独角兽企业和超级自动化平台提供商&#xff0c;与国内领先的SaaS远程连接解决方案提供商贝锐的实力“牵手”&#xff0…

基于Python的电影票房爬取与可视化系统的设计与实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

2023年blender渲染显卡推荐

Blender是完全免费的、开源的&#xff0c;而且非常灵活。为了让 Blender 运行良好&#xff0c;有必要找到最好的 GPU。对于希望优化其 3D 建模和渲染体验的 Blender 专业人士和爱好者来说&#xff0c;找到最好的 GPU 是当务之急。GPU 不仅在渲染方面起着至关重要的作用&#xf…

电流驱动和电压驱动有什么区别(高精度电流源)

电流驱动和电压驱动是电子电路设计中常用的两种驱动方式。它们有着各自不同的优缺点&#xff0c;选择不同的驱动方式可以在不同的应用场景中获得更好的效果。 电压驱动&#xff08;Voltage Drive&#xff09;是通过控制电路的输出电压来实现对电路的控制。在电路中&#xff0c;…

软考高级系统架构设计师(四) 计算机网络1

目录 概要 TCP/IP TCP可靠传输的实现&#xff0c;依赖如下机制 ​DNS DHCP 网络规划与设计 逻辑网络设计 物理网络设计 层次化网络设计 网络冗余设计 ​网络存储技术 概要 TCP/IP POP3:邮件收取 SMTP:简单邮件传输协议 DNS:域名与IP地址之间是一对应的 DHCP:主要…

排序算法第一辑——插入排序

思维导图&#xff1a; 一&#xff0c;插入排序 插入排序&#xff0c;一种简单排序中的王者。这种排序算法的过程可以想象成是打牌时摸牌按照顺序插入扑克牌的过程。想想你是如何打牌的&#xff1f;在你拿下一个牌插入时你是不是将手里已经有的牌变得有序了才抽下下一个牌来进行…

电影APP项目(Android+Java+MySQL)

目录&#xff1a; 一、系统架构&#xff1a;二、效果图&#xff1a;1.主页&#xff1a;2.榜单页&#xff1a;3.预告片页&#xff1a;4.动态评论页&#xff1a;5.登录页&#xff1a; 三、数据库设计&#xff1a;四、详细设计&#xff1a;1.主页&#xff1a;2.榜单页&#xff1a;…

【Java-SpringBoot+Vue+MySql】Day2-第一个SpringBoot项目应用

目录 一、初步了解SpringBoot 二、创建第一个SpringBoot项目 三、配置MyBatis数据源 四、创建启动类 五、MVC设计模式 六、SpringBoot整合应用 &#xff08;1&#xff09;创建一个实体类 &#xff08;2&#xff09;创建DAO接口 &#xff08;3&#xff09;创建mapper&#…

AutoSAR系列讲解 - AutoSAR标准文档概览

目录 一、文档下载 二、文档结构 三、文档内容 四、各部分介绍 1、Introduction and functional o 目录 一、文档下载 二、文档结构 三、文档内容 四、各部分介绍 1、Introduction and functional overview 2、Acronyms and abbreviations 3、Related documentati…

MySQL面试题--sql优化的经验

表的设计优化&#xff08;参考阿里开发手册《嵩山版》&#xff09; 比如设置合适的数值&#xff08;tinyint int bigint&#xff09;&#xff0c;要根据实际情况选择 比如设置合适的字符串类型&#xff08;char和varchar&#xff09;char定长效率高&#xff0c;varchar可变…

关于智慧消防建设的探究 安科瑞 许敏

【摘要】随着城市化发展步伐的不断加快&#xff0c;智慧城市的建设已经成为城市发展的重要目标&#xff0c;而智慧消防则是其重要组成部分&#xff0c;不容忽视。基于大数据时代背景下&#xff0c;实现智慧消防建设的时候&#xff0c;更加需要以信息化为导向&#xff0c;这样才…

从零开始 Spring Boot 45:FactoryBean

从零开始 Spring Boot 45&#xff1a;FactoryBean 图源&#xff1a;简书 (jianshu.com) 在前文中我介绍过 FactoryBean&#xff0c;本篇文章会更深入的介绍相关内容。 依赖注入 从一个简单示例开始&#xff0c;我们看使用FactoryBean定义的 Spring Bean 如何注入。 假设我们…

mysql数据库备份和恢复和日志管理

数据库备份和恢复和日志管理 一&#xff1a;数据库备份备份和恢复1.备份分类从物理与逻辑的角度&#xff0c;备份可分为从数据库的备份策略角度&#xff0c;备份可分为 2.常见的备份方法3.MySQL完全备份和恢复分类一&#xff1a;物理冷备份与恢复关闭MySQL数据库使用tar命令直接…

DJ5-1 链路层概述

目录 一、链路层的术语 二、链路层的类比 三、链路层提供的服务 四、链路层实现的位置 1、网络适配器 2、网络适配器工作过程 一、链路层的术语 ① 节点 (nodes)&#xff1a;主机和路由器 ② 链路 (links)&#xff1a;沿着通信路径连接相邻节点的通信信道 有线链路 (w…