单片机05__串口USART通信__按键控制向上位机传输字符串

串口USART通信

通用UART介绍

1.通信的概念

        计算机与外界进行信息交换的过程称之为通信。

        在通信的过程中,通信双方都需要遵守的规则称之为通信协议。

        硬件协议:将数据以什么样的方式传输过去

        软件协议:将数据以什么样的顺序传输过去

2.常用的通信方式  

并行通信---LCD屏

        所传输的数据的各个二进制位数据都是同时发送或接收

        优点:通信速度快。

        缺点:由于有多少位的二进制数据,就需要多少根数据线,所以说通信成本比较高。

        一般适合在近距离场所使用。

串行通信----串口

        所传输的数据的各个二进制位数据按照顺序一位一位的发送或者接收

        优点:串行通信一般只需要1-2根数据线,所以说通信成本比较低。

        缺点:通信速度比较慢。

        一般适合在远距离场所使用。

3.串行通信种类 

①异步通信   

        异步通信概念:

        异步通信:指收发双方使用的时钟源(提供时钟脉冲)不同,不受到同一根时钟线的控制,在通信时不要求基本频率相等。

        异步通信数据格式:

        在异步通信的过程:数据或字符都是逐帧传输

        异步传输的数据帧为:起始位+数据位+校验位+结束位

        数据传输的方式为:先发低位(LSB),再发高位(MSB),从起始位到结束位构成了完整的一帧。 

起始位:使用1个位的低电平“0”来表示数据通信的开始。  

数据位:串行通信所需要传输的数据,数据位长度为5-8位(常用的是8位--1byte)

奇偶校验位:校验位在串行通信中是可选项,用于检验传输的数据是否正确,检验方法为:“奇校验”和“偶校验”。

停止位数据缓存区使用高电平“1”来表示数据通信的结束,停止位长度为:0.5位、1位、1.5位、2位、2.5位停止位数越大,传输的速度越慢。

        奇校验:“数据位”加上“校验位”后,使得传输的数据中“1”的个数为奇数个。

        偶校验:“数据位”加上“校验位”后,使得传输的数据中“1”的个数为偶数个。

例如:

数据位

校验位

1010 0011

奇校验:1

偶校验:0

0100 0000

奇校验:0

偶校验:1

②同步通信

        同步通信概念:

                通信双方受到同一根时钟源(时钟线的控制,其时钟频率相等。

        同步通信数据帧格式:

        同步通信发送的数据开始是以“同步字符”来表示的(一般约定为1-2个字节),当接收方接收到同步字符后就表示接受下来收到的数据为需要发送的数据流数据的位数不确定

4.串行通信的数据传输速度  

        串行通信数据的传输速度称为波特率(也叫比特率),是指一秒钟内所传输的数据(二进制)位数,英文简称BPS

例:假设数据传输的速率为120个字符每秒,每个字符有1个起始位,8个数据位以及1个停止位构成,其串行波特率是多少???   

        每个字符的位数:1+8+1= 10  

        每秒传输的位数:120*10/s = 1200 BPS

5.串行通信工作方式

        ①单工制式:只有一根数据线,数据在甲机和乙机之间只允许单方向传输

        ②半双工:只有一根数据线,数据在甲机和乙机之间允许双方向的传输,但是在同一时刻只允许数据的发送或者接收

        ③全双工:有两根数据线,数据在甲机和乙机之间允许双方向的传输,并且可以同时在同一时刻进行数据的发送或者接收。

6.串口数据发送的格式      

串口发送数字、字母、英文符号按照ASCII表的数值发送。

串口发送中文汉字,中文符号是按照“GB2312”简体中文编码表的数值发送。

USART模块介绍STM3240x

1.USART模块概述

        STM32F40X芯片的USART模块是通用同步/异步收发器能够灵活地与外部设备进行全双工数据交换,此芯片一共有6个独立的USART模块(编号为USART1-6)。

        可以实现同步/异步通信的是USART1、2、3、6,只能实现异步通信的是UART45

        同步串口可以是异步串口,但是异步串口不能是同步串口。

        全双工:有两根数据线:TX RX   串口最远传输距离:15米左右

        串口连接:交叉相连

        USART:  TX  RX  SCLK--时钟线-------同步串口

        UART:   TX  RX               ------异步串口

        只有串口连接方式是交叉相连  :TX---RX   RX----TX

2.USART模块框图

①串口发送数据的过程

        1)在MCU内定义需要发送的数据(内核发送数据)

        2)MCU将需要发送的数据通过数据总线写入到“发送数据寄存器(数据寄存器)”

/****************以下部分由硬件自动完成(无需配置)************************/

        3)当“发送数据寄存器”被写入后,将数据并行发送到“发送移位寄存器”,并且由硬件自动产生一个“发送数据寄存器”为空的标志。

        4)“发送移位寄存器”根据已经设置好的波特率时钟脉冲,把数据按照顺序一位一位的发送到数据发送管脚(TX)。

        当“发送移位寄存器”为空并且“发送数据寄存器”也为空的时候,由硬件自动产生一个“传输完成”的标志。

        5)数据在串口发送管脚发送数据,数据通过USB转串口芯片(电平转换芯片)后,由USB数据线传输到电脑上位机上。

②串口接收数据的过程

        1)电脑上位机通过USB线发送数据,数据通过USB转串口芯片发送到串口接收数据管脚(RX)

        2)接收管脚根据已经设置好的波特率时钟脉冲,一位一位的把数据传输到“接收移位寄存器”中。被动接收:没有“满”标志,满时自动传输

        3)当“接收移位寄存器”接收完数据之后,并行把数据传输到“接收数据寄存器”中,并且会由硬件自动产生一个“接收数据寄存器”为满的标志。

/***************以上部分由硬件自动完成(无需配置)************************/

        4)CPU通过数据总线读出“接收数据寄存器”的内容。

3. USART模块特征

  1. 可以支持波特率的时钟配为16倍过采样或或者8倍过采样来对不同时钟速度之间的误差容忍。
  2. 支持小数位波特率发生器。
  3. 可以根据实际情况配置数据位长度为8位(如果不使用奇偶校验位,则数据位为8位,如果使用奇偶校验位,则数据位为7位),或者数据位长度为9位(包含了校验位)。
  4. 停止位支持可以配置为1位或2位。
  5. 支持DMA数据高速传输。
  6. 发送器和接收器具有单独使能位USTAR单独开启时钟。
  7. USART模块有3个状态标志:接收缓冲区已满、发送缓冲区为空、传输完成。
  8. USART模块不仅可以发送奇偶校验位,也可以对接收到的数据进行奇偶校验。
  9. USART模块具有4个错误检测标志:

    溢出错误(原来的数据没有被读出,又来了新的数据,则产生溢出错误。溢出错误状态时,“接收数据寄存器”保留原来旧的数值,丢弃新的数值)、

     噪声错误(干扰错误)、

     帧错误(数据帧格式错误)、

     奇偶校验错误

10.USART模块的中断源:

     CTS变化(硬件流发送变化)、

     LIN停止符号检测(LIN数据传输完成)、

     发送数据寄存器为空、

     发送完成、

     接收数据寄存器为满,接收到线路空闲(USART线路在忙碌状态转换为空闲的时刻)、

     溢出错误、

     帧错误、

     噪声错误、

     奇偶校验错误。

     只要发生上面的状态中的其中一条(前提是开启了中断),都会产生一个USART中断。

11.多处理器通信,如果地址不匹配,则进入静默模式。

12.从静默模式唤醒(通过线路空闲检测或地址标记检测)。

USART模块配置STM3240x

1.STM3240x外设功能管脚复用GPIO配置

STM32F40x外设功能管脚复用概念

        STM32F40X芯片所有的片内外设(芯片以内内核以外)模块的功能管脚都是使用GPIO端口的复用功能,并且每个IO端口都会对应多个复用功能管脚。

STM32F40x外设功能管脚复用

STM32F40x外设管脚复用相应寄存器

GPIO复用功能低位寄存器 (GPIOx_AFR[0]) (x = A..I)

        寄存器作用:设置STM32F40X芯片GPIOx组端口0-7对应的外设模块复用功能,每4位控制一个IO口。把对应的“复用功能编码”写入相对应的位,则设置对应端口为复用功能。

GPIO 复用功能高位寄存器 (GPIOx_AFR[1]) (x = A..I)

        寄存器作用:设置STM32F40X芯片GPIOx组端口8-15对应的外设模块复用功能,每4位控制一个IO口。把对应的“复用功能编码”写入相对应的位,则设置对应端口为复用功能。

STM32F40x外设管脚复用步骤

例如:

        1)需要使用的复用端口是否满足复用的前提条件。

        2)配置端口模式寄存器,配置为复用功能。

        3)根据具体的端口管脚选择对应的复用功能寄存器 0-7使用低位寄存器 8-15使用高位寄存器。

        4)选择对应的“复用功能编码”配置复用功能寄存器。

RCC->AHB1ENR |= 1<<0; //开启A口时钟

//PA9

GPIOA->MODER &= ~(3<<9*2);

GPIOA->MODER |= 2<<9*2; //配置复用功能

GPIOA->AFR[1] |= 7<<(9-8)*4; //配置为串口功能

//PA10

GPIOA->MODER &= ~(3<<10*2);

GPIOA->MODER |= 2<<10*2; //配置复用功能

GPIOA->AFR[1] |= 7<<(10-8)*4; //配置为串口功能

2.STM3240x芯片USART模块相关寄存器

状态寄存器 (USART_SR)

        寄存器作用:检测串口模块的具体功能的当前状态(数据是否接收/发送完成,寄存器是否为空),如果发生了对应的状态,硬件会自动置1,并且可以用来申请中断。

数据寄存器 (USART_DR)

        寄存器作用:存放串口需要发送和接收的数据,数据寄存器包含了“接收数据寄存器”和“发送数据寄存器”,两个寄存器共用同一个寄存器地址以及空间

注:当CPU往数据寄存器写数据的时候,数据寄存器就是“发送数据寄存器”,当CPU对数据寄存器进行读操作的时候,数据寄存器就是“接收数据寄存器”。

波特率寄存器 (USART_BRR)   

        波特率:USART模块的指定波特率时钟大小(115200/9600等)-----已知

        fck:USART模块挂载的时钟总线频率(HZ)--------已知   1MHZ = 10^6HZ

        OVER8USART模块采样滤波的选择,采用16倍过采样,则为数字“0”,采用8倍过采样,则为数字“1”

        USARTDIV:存放USART模块波特率寄存器的计算值。

注:USARTDIV计算值不能直接放入波特率寄存器中,而是分别计算出整数部分和小数部分,分别写入到寄存器里面。

假设设置的波特率为115200,16倍过采样,使用的事USART1,挂载在APB2上时钟频率为72MHZ

Float USARTDIV ;

int ZHENG,XIAO;

USARTDIV = 72000000.0/(8*(2-0)*115200);  //39.0625

ZHENG = (int)USARTDIV;//39  0010 0111

XIAO = (USARTDIV - ZHENG)*16;   //0001

USAT1->BRR = ZHENG<<4 | XIAO;  // 0010 0111  0001

控制寄存器 1 (USART_CR1)

        寄存器作用:设置串口模块对应的工作模式以及相关参数

控制寄存器 2 (USART_CR2)

        寄存器作用:设置串口模块对应的工作模式以及相关参数

控制寄存器 3 (USART_CR3)

        寄存器作用:设置串口模块对应的工作模式以及相关参数

USART模块编程思路

①找到USART模块对应的GPIO端口 -----CH340----PA9  PA10

        1)先开对应的IO口时钟

        2)设置端口功能:复用功能

        3)通过复用功能寄存器选择具体的复用功能

                     GPIO时钟

                           ​​​​​​​        串口USART时钟

GPIO寄存器配置

②USART模块初始化

        1)使能USART对应的时钟

        2)设置相关的工作参数---控制寄存器: 发送接收开启、数据位数、是否需要校验、停止位等。

        3)如果需要中断,则开启对应中断位

USART1配置

③设置USART模块波特率

        1)先设置采样参数:16倍过采样还是8倍过采样

        2)根据波特率计算公式计算出波特率的计算数值

        3)将波特率计算值分成小数和整数部分写入到波特率寄存器中

④使能串口

⑤USART模块发送数据

         1)先检测“发送数据寄存器是否为空”或“传输完成”

         2)把需要发送的数据写入到数据寄存器

⑥USART模块接收数据

         1)轮询判断“接收数据寄存器为满”

         2)读取数据寄存器中的内容

“usart.c”

/*************************
函数功能:串口USART1初始化
硬件接口:
PA9 --- USART1_TX --- 复用功能
PA10--- USART1_RX --- 复用功能
GPIOA --- AHB1 168MHZ
USART1 --- APB2 84MHZ
**************************/

void USART1_Init(uint32_t brr)
{
	float USARTDIV;	//波特率寄存器存放值
	uint32_t fck = 84000000.0;	//USART1挂载在APB2的频率84MHZ
	uint16_t integer,decimal;	//波特率寄存器存放值的整数/小数
	RCC->AHB1ENR |= 1<<0;	//开启A口时钟
	
/*①*/
	//PA9
	GPIOA->MODER &= ~(3<<9*2);	
	GPIOA->MODER |= 2<<9*2;	//配置复用功能
	GPIOA->AFR[1] |= 7<<(9-8)*4;	//配置为串口功能
	//PA10
	GPIOA->MODER &= ~(3<<10*2);
	GPIOA->MODER |= 2<<10*2;	//配置复用功能
	GPIOA->AFR[1] |= 7<<(10-8)*4;	//配置为串口功能
/*②*/	
	//USART
	RCC->APB2ENR |= 1<<4; //开启USART1时钟
	USART1->CR1 &= ~(1<<15);	//串口配置16倍过采样
	USART1->CR1 &= ~(1<<12);	//配置8位数据
	
	USART1->CR2 &= ~(3<<12);	//1位停止位
/*③*/
	//波特率
	USARTDIV = fck/(8*(2 - 0)*brr);
	integer = USARTDIV;	//整数部分
	decimal = (USARTDIV - integer)*16;	//小数部分
	USART1->BRR = integer<<4 | decimal;	//数据放入波特率寄存器 
	
	
/*④*/
	USART1->CR1 |= 1<<3;	//使能发送器
	USART1->CR1 |= 1<<2;	//使能接收器
	USART1->CR1 |= 1<<13;	//使能串口
	
	
}

“main.c”

USART1_Init(115200);
	
	while(1)
	{
		while(!(USART1->SR & 1<<6))
		{
			//轮询检测接收数据寄存器标志位是否已满
		}
		USART1->DR = cha;	//读出接收数据寄存器内容
		
		while(!(USART1->SR & 1<<5))	
		{
			//轮询检测发送数据寄存器标志位
		}
		cha = USART1->DR;	//发送
			
	}

改写printf函数

目标:使用printf函数,通过串口USART1向上位机发送信息。

例如:printf("hello world\r\n");

int a=10;

  printf("a = %d\r\n",a);

/********************************
函数功能:修改printf底层代码
注意:不可更改!
魔术棒Target---Use MicroLIB
*********************************/
int fputc(int data,FILE* file)
{
	while(!(USART1->SR & 1<<6))
	{}
	USART1->DR = data;	//清标志位&&发送数据
	return data;	
}

按键控制向上位机传输字符串示例

“usart.c”

#include "usart.h"
#include "stdio.h"
/*************************
函数功能:串口USART1初始化
硬件接口:
PA9 --- USART1_TX --- 复用功能
PA10--- USART1_RX --- 复用功能
GPIOA --- AHB1 168MHZ
USART1 --- APB2 84MHZ
**************************/

void USART1_Init(uint32_t brr)
{
	float USARTDIV;	//波特率寄存器存放值
	uint32_t fck = 84000000.0;	//USART1挂载在APB2的频率84MHZ
	uint16_t integer,decimal;	//波特率寄存器存放值的整数/小数
	RCC->AHB1ENR |= 1<<0;	//开启A口时钟
	
	//PA9
	GPIOA->MODER &= ~(3<<9*2);	
	GPIOA->MODER |= 2<<9*2;	//配置复用功能
	GPIOA->AFR[1] |= 7<<(9-8)*4;	//配置为串口功能
	//PA10
	GPIOA->MODER &= ~(3<<10*2);
	GPIOA->MODER |= 2<<10*2;	//配置复用功能
	GPIOA->AFR[1] |= 7<<(10-8)*4;	//配置为串口功能
	
	//USART
	RCC->APB2ENR |= 1<<4; //开启USART1时钟
	USART1->CR1 &= ~(1<<15);	//串口配置16倍过采样
	USART1->CR1 &= ~(1<<12);	//配置8位数据
	
	USART1->CR2 &= ~(3<<12);	//1位停止位
	
	//波特率
	USARTDIV = fck/(8*(2 - 0)*brr);
	integer = USARTDIV;	//整数部分
	decimal = (USARTDIV - integer)*16;	//小数部分
	USART1->BRR = integer<<4 | decimal;	//数据放入波特率寄存器 
	
	
	
	USART1->CR1 |= 1<<3;	//使能发送器
	USART1->CR1 |= 1<<2;	//使能接收器
	USART1->CR1 |= 1<<13;	//使能串口
	
	
}

/********************************
函数功能:修改printf底层代码
注意:不可更改!
魔术棒Target---Use MicroLIB
*********************************/
int fputc(int data,FILE* file)
{
	while(!(USART1->SR & 1<<6))
	{}
	USART1->DR = data;	//清标志位&&发送数据
	return data;	
}


/************************************
函数功能:串口USART1传输字符串
函数参数:str:字符串
*************************************/
void Prin_Str(uint8_t *str)
{
	uint8_t ch;
	uint32_t i = 0;
	while(str[i] != '\0')
	{
		ch = str[i];
		while(!(USART1->SR & 1<<6))
		{}
		USART1->DR = ch;
		i++;
	}
}

“KEY.c”

#include "KEY.h"
#include "delay.h"
/*****************************************
函数功能:按键初始化
函数接口:KEY1--PA0--浮空/下拉输入
******************************************/
void KEY_Init(void)
{
	RCC->AHB1ENR |= 1<<0;	//按键PA0时钟使能
	
	GPIOA->MODER &= ~(3<<0*2);	//清零&&输入模式
	GPIOA->PUPDR &= ~(3<<0*2);	//清零&&浮空
	GPIOA->PUPDR |= 2<<0*2;	//下拉
}
/*****************************************
函数功能:按键消抖
函数接口:KEY1--PA0--浮空/下拉输出
返回参数:返回0:没有按下,返回1:按键按下
******************************************/
uint8_t KEY_Scan(void)
	{	static uint8_t flag =0;	//0:按键未按下,1:按键已按下
	if((flag ==0) && (GPIOA->IDR & 1<<0))	//判断按键是否按下,IDR第0位为1时按下
	{
		flag = 1;
		delay(500);
		if(GPIOA->IDR & 1<<0)
		{
			return 1;
		}
	}
	else if((flag==1)&& !(GPIOA->IDR & 1<<0))	//松手检测
	{
		flag = 0;	//按键松手
	}
	return 0;
}

#if 0
uint8_t KEY_Scan2(void)
{
	static uint8_t flag = 0;
	if((flag == 0)&&(GPIOA->IDR & 1<<0 || GPIOA->IDR & 1<<1))
	{
		delay(1000);
		if(GPIOA->IDR & 1<<0)
		{
			return 1;
		}
		if(GPIOA->IDR & 1<<1)
		{
			return 2;
		}
	}
	else if((flag == 1) && (!(GPIOA->IDR & 1<<0) || !(GPIOA->IDR & 1<<1)))
	{
		flag = 0;
	}
	return 0;
}

uint8_t KEY_Scan3(void)
{
	static uint8_t flag = 0;
	if((flag == 0)&&(KEY1==1 || KEY2 == 1))
	{
		delay(1000);
		if(KEY1==1)
		{
			return 1;
		}
		if(KEY2==1)
		{
			return 2;
		}
	}
	else if((flag == 1) && (KEY1==0 || KEY2==0))
	{
		flag = 0;
	}
	return 0;
}

#endif

“main.c”

#include "stm32f4xx.h"                  // Device header
#include "LED.h"
#include "KEY.h"
#include "delay.h"
#include "time.h"
#include "usart.h"
#include "stdio.h"

#define STR "qwertyuiop"	//串口1传输字符串

int main(void)
{
	uint8_t key;
	LED_Init();
	KEY_Init();
	USART1_Init(115200);
	printf("按下KEY1发送数据:\r\n");
	while(1)
	{	
		key = KEY_Scan();
		if(key == 1)
		{
			Prin_Str(STR);
			LED5 = !LED5;
			printf("按下KEY1发送数据:\r\n");
		}
		
	}	
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

042 继承

代码实现 首先定义Person类&#xff08;人类&#xff09; /*** 人的基础特征** author Admin*/ public class Person {/*** 姓名*/String name;/*** 生日*/Date birthday;/*** 手机号码*/String tel;/*** 身份证号码*/String idCode;public Person() {}public Person(String …

BlackberryQ10 是可以安装 Android 4.3 应用的,Web UserAgent 版本信息

BlackberryQ10 是可以安装 Android 4.3 应用的 最近淘了个 Q10 手机&#xff0c;非常稀罕它&#xff0c;拿着手感一流。这么好的东西&#xff0c;就想给它装点东西&#xff0c;但目前所有的应用都已经抛弃这个安卓版本了。 一、开发环境介绍 BlackBerry Q10 的 安卓版本是 4.…

Spring Boot对接RocketMQ示例

部署服务 参考RocketMq入门介绍 示例 引入maven依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.2</version></dependency>完整依赖如下&am…

栈和队列笔试题

答案&#xff1a;&#xff08;1&#xff09;seqn[tail]data; tail(tail1)%SEQLEN; &#xff08;2&#xff09;data seqn[head]; head (head1)%SEQLEN; &#xff08;3&#xff09;head tail; &#xff08;4&#xff09;(tail1)%SEQLEN head; (5) while(head!tail) head (h…

PHP WebSocket:技术解析与实用指南

本文旨在帮助初学者掌握在PHP中使用WebSocket的关键概念和技术。我们将深入讨论从建立连接、绑定到监听等各方面的操作&#xff0c;并提供易于理解和实践的指导。 一、socket协议的简介 WebSocket是什么&#xff0c;有什么优点 WebSocket是一个持久化的协议&#xff0c;这是…

基于相位的运动放大:如何检测和放大难以察觉的运动(01/2)

基于相位的运动放大&#xff1a;如何检测和放大难以察觉的运动 目录 一、说明二、结果的峰值三、金字塔背景3.1 可操纵金字塔3.2 亚倍频程复数可控金字塔 四、基本方针4.1 1D 问题陈述4.2 一维方法4.3 实际实施说明 五、放大倍率的限制5.1 空间支持的影响5.2 频带的影响 六、推…

【Oracle】玩转Oracle数据库(五):PL/SQL编程

前言 嗨&#xff0c;各位数据库达人&#xff01;准备好迎接数据库编程的新挑战了吗&#xff1f;今天我们要探索的是Oracle数据库中的神秘魔法——PL/SQL编程&#xff01;&#x1f52e;&#x1f4bb; 在这篇博文【Oracle】玩转Oracle数据库&#xff08;五&#xff09;&#xff1…

2.25基础会计学

资本公积是指由股东投入、但不能构成“股本”或“实收资本”的资金部分。 盈余公积是指公司按照规定从净利润中提取的各种积累资金。 所以区别在于盈余公积来自净利润。 借贷其实就是钱从哪来和到哪去的问题&#xff0c;来源是贷&#xff0c;流向是借。比如购入9w原材料&…

【监控】grafana图表使用快速上手

目录 1.前言 2.连接 3.图表 4.job和path 5.总结 1.前言 上一篇文章中&#xff0c;我们使用spring actuatorPrometheusgrafana实现了对一个spring boot应用的可视化监控。 【监控】Spring BootPrometheusGrafana实现可视化监控-CSDN博客 其中对grafana只是打开了一下&am…

YApi-pro docker安装在centos7上

之前安装失败了&#xff0c;只好在docker中装了。 准备环境 1.docker安装 centos7 docker 安装-CSDN博客 2.mongodb数据库docker安装 创建mongo容器目录 mkdir /data/mongo -p docker pull mongo:4.2.21 创建一个yapi网络插件 docker network create yapi …

音频声波的主观感受

一、响度 声压是“客观”的&#xff0c;响度是“主观”的。 响度又称音量。人耳感受到的声音强弱&#xff0c;它是人对声音大小的一个主观感觉量。响度的大小决定于声音接收处的波幅&#xff0c;就同一声源来说&#xff0c;波幅传播的愈远&#xff0c;响度愈小…

python jupyter notebook打开页面方便使用

如果没安装jupyter, 请安装&#xff1a; pip install jupyter notebook 运行jupyter notebook jupyter-notebook

【Redis】搞懂过期删除策略和内存淘汰策略

1、过期删除策略 1.1、介绍 Redis 是可以对 key 设置过期时间的&#xff0c;因此需要有相应的机制将已过期的键值对删除&#xff0c;而做这个工作的就是过期键值删除策略。 每当我们对一个 key 设置了过期时间时&#xff0c;Redis 会把该 key 带上过期时间存储到一个过期字典…

如何做到三天内完成智能直流伺服电机系统开发?

适应EtherCAT/CANopen协议三相伺服电机直流伺服电机直线伺服音圈电机 如何开发高性能直流伺服电机驱动控制器&#xff1f; 需要熟悉高性能单片机&#xff08;至少是ARM或DSP水平的&#xff09;&#xff0c;需要掌握空间磁场矢量控制FOC&#xff0c;需要掌握运动轨迹算法……此…

Vue监听器(上)之组合式watch

1. 定义监听器 //要监视的属性被改变时触发 watch(要监视的属性, (更改后的心值, 更改前的旧值) > {具体操作}, );//监视对象为getter的时候 //表达式内任意响应式属性被改变时触发 watch(() > return表达式, (表达式的新值, 表达式的旧值) > {具体操作} );//数组中任…

四六级成绩爬取代码原创

在六级成绩刚发布时&#xff0c;只需要通过学生姓名和身份证号便可以查询到成绩 据此&#xff0c;我们可以利用selenium框架对学生的成绩进行爬取 首先我们要建立一个excel表格&#xff0c;里面放三列&#xff08;多几列也无所谓&#xff09;&#xff0c;第一列列名取为学生姓…

在openEuler中通过KVM可视化安装华为FusionCompute的VRM节点

一、说明 本文是华为FusionCompute云平台配置的延续&#xff0c;是在CNA&#xff08;ComputingNode Agent&#xff0c;计算节点代理&#xff09;主机安装配置完成后&#xff0c;详细安装VRM&#xff08;Virtual Resource Manager&#xff0c;虚拟资源管理器&#xff09;节点的…

基于Clion+stm32cubemx+rt-thread os进行环境搭建

前言 RT-Thread文档中心Clion开发STM32的环境搭建,请参考之前的文章本次使用的芯片为STM32F407VET6,其他芯片相似.项目创建 使用STM32CubeMx快速生成项目工程,此步骤的话可以参考官方文档 基础配置如下

AtCoder ABC341 A-D题解

比赛链接:ABC341 Problem A: 先签个到。 #include <bits/stdc.h> using namespace std; int main() {int n;cin>>n;for(int i0;i<n;i)cout<<"10"<<endl;cout<<"1"<<endl;return 0; } Problem B: 继续签。 #i…

在 where子句中使用子查询(二)

目录 ANY ANY &#xff1a;功能上与 IN 是没有任何区别的 >ANY &#xff1a;比子查询返回的最小值要大 ALL >AL &#xff1a;比子查询返回的最大值要大 EXISTS() 判断 NOT EXISTS Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209…