- 串口通信

news2024/12/25 2:06:23

USART串口通信

目录

USART串口通信

回顾

USART串口通信

1、通信分类与作用

2、串口通信的相关参数(重点)

3、位协议层 -- RS232协议

4、STM32F103 中的串口外设

5、调试串口编程

-- (1)串口初始化:时钟、IO、外设

-- (2)串口发送

-- (3)串口接收

-- 补充

-- 应用

6、中断

usart.c完整代码


回顾

定时器的构成:
计数器:计数
时钟:为计数器提供计数频率
重装栽植:计数的最大值
-- 计数器从 0 开始计数(向上计数),一直到计数值等于重装载值,计数值会自动清零。

阻塞:程序里使用了延时函数
实现非阻塞的目的:提高 cpu 利用率 每个任务之间互不干扰

-- 基础阶段应该掌握的知识:

  • 单片机的运行流程(从上往下,顺序执行)
  • 单片机的基本知识(GPIO 中断)
  • 代码:代码的基本编写(代码框架)

  • 从这章开始真正进入单片机的开发阶段。

-- 开发阶段:

  • 首先要掌握的就是开发方法(或者是开发的流程)。

  • 代码会偏向应用函数。

  • 相同类型的模块(通信方式(接口)相同的模块),开发是一致的

通信方式(其实就是接口是一致的,学习单片机其实就是学习它的各种接口),如IO,TIM,USART,I2C,SPI,ADC,DAC,PWM等。

USART串口通信

  • 今天先学习串口类设备如何进行开发

1、通信分类与作用

有线: 485 232 can
无线:WiFi 蓝牙 zigbee 4G
-- 这些通信都用来用作设备与设备之间的通信

SPI IIC USART -- 单片机和模块之间的通信


  • 这章讲的usart 特点:串行 异步 全双工

  • 特点的含义

串行:串行数据传输时,数据是一一位地在通信线上传输的 

alt text

并行:并行通信传输中有多个数据位,同时在两个设备之间传输。 

alt text

异步:发送端和接收端没有相同的时钟线。
-- 因为双方工作不在相同的频率,传输的数据会丢失,所以在异步通信时双方要规定波特率
Tip:波特率(bps)实际就是数据传输的速度

同步:发送端和接收端有相同的时钟线。- 两个设备要工作的相同的频率下

单工:一个设备只能发送或是接收 收音机
半双工:同一时间内,只能发送或是接收 对讲机
全双工:同一时间内,能发送也能接收


2、串口通信的相关参数(重点)

-- 串口类设备
如何识别该设备是串口类设备?
-- 从物理硬件接口(物理层)来看(一定要有下面图这几根线(引脚接口)TX,RX,GND),有这些引脚就是串口类设备) 

alt text

 -- 怎么接线也要注意一下

  • 怎么确保对方收到了数据?

-- 为了保证通信,双方都会存在通信协议
保证通信(通信流程、通信协议)
双方设备通信 A 和 B,设备 A 向设备 B 传输 1 字节内容。
1、 设备 A 如何确认设备 B 是否收到了信息?
设备 B 向设备 A 发送应答信号。
2、 设备 B 如何确认收到的数据是正确的?
校验
-- 在串口通信中,没有操作1,波特率在某种程度上解决了操作1的问题,但没有很好的解决。
-- 对于串口通信,保证了操作2,-- 用RS232协议

3、位协议层 -- RS232协议

  • 协议:数据传输格式

  • 数据传输将数据分成了4部分,分别为起始位,数据位,奇偶校验位,停止位

RS232协议将数据分为1个起始位,8个数据位,1个奇偶校验位,1个停止位: 1 8 0 1

校验位:奇偶校验 CRC校验
奇校验:数据位+奇偶检验位 里面的1奇数个
偶校验:数据位+奇偶检验位 里面的1偶数个
01010101 1 如果是奇校验,在后面补个1
01010101 0 如果是偶校验,在后面补个0

  • 设备 A 向设备 B 发送 8000 位数据 双方通信波特率 9600, 问:数据传输完毕,花费多长时间?

串口一次发送 8 位数据,需要发送 1000 次, 串口发送一次数据花费 10/9600s
(10/9600)*1000 = 100/96 S = 25/24s

4、STM32F103 中的串口外设

  • STM32F103ZET6:一共有 5 个 USART1 USART2 USART3 UART4 UART5
  • 单片机它可以同时驱动 5 个串口设备

alt text

5、调试串口编程

  • 通信双方 单片机和ch340

alt text

  • 串口通信编程:串口初始化,串口发送,串口接收
-- (1)串口初始化:时钟、IO、外设
  • 先看数据手册中该外设在哪条线上 

    alt text

  • 看原理图知道串口连接的引脚 

    alt text

  • 然后配置相应的时钟(A端口的时钟和USART1的时钟(外设自身也有时钟))

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);			//看数据手册在哪条线上 - APB2
  • 配置IO
//IO PA9/PA10
	GPIO_InitTypeDef GPIO_InitStructure = {0};						//定义结构体变量,并且将结构体变量赋初值
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 						//引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//速度
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//PA9 复用推挽
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 							//引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;		//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);
  • 配置外设(配置串口)

-- 使用固件库使用手册 

alt text

-- 串口初始化函数原型 

alt text

-- 找到例子,复制到工程中(在例子的基础上更改) 

alt text

    USART_InitTypeDef USART_InitStructure = {0};
	USART_InitStructure.USART_BaudRate = 9600;   					 			//波特率  常用的是4800 9600  115200
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	//数据位长度
	USART_InitStructure.USART_StopBits = USART_StopBits_1;			//停止位长度
	USART_InitStructure.USART_Parity = USART_Parity_No;				//奇偶校验(这里写不使用)
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制失能(不使用硬件流控制)
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//模式
	USART_Init(USART1, &USART_InitStructure);
	
	USART_Cmd(USART1,ENABLE);//开启串口    //使能或者失能 USART 外设(一般外设都要写这个)
-- (2)串口发送

-- 在固件库使用手册中找到相应函数 

alt text

-- 如果只写发送数据的语句,那么怎么知道上次的数据是否已经发送完了,如果上次的数据没有发送完的情况下,再次发送数据的话,就会覆盖上次的数据,所以需要判断上次的数据是否发送完成。

-- 判断数据是否发送完成 -- 采用状态寄存器 

alt text

-- 发送数据空标志位为1,表示数据发送完成,反之标志位为0,上一次的数据还没有发送完成,所以需要等待,直到标志位为1,表示数据发送完成,再发送数据。 

alt text

//发送
void usart1_tx(uint8_t data)//参数就是要发送的数据
{
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE )== RESET){}
		//上次的数据发送完成,为空表示上个数据已经发送完成
		//等待的时候是还没有发送,一旦发送完成,就变成1了
	USART_SendData(USART1, data);
}
-- (3)串口接收

alt text

-- 接收数据寄存器非空标志位为1,表示数据接收完成,反之标志位为0,上一次的数据还没有接收完成,所以需要等待,直到标志位为1,表示数据接收完成,再接收数据。

alt text

//接收

uint8_t usart1_rx(void)
{
	while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE )== RESET){} 			//接收数据寄存器非空标志位
	uint8_t RxData = USART_ReceiveData(USART1);
	return RxData;
}
-- 补充
  • 将printf输出的数据直接输出到串口上,将它写在usart.c中,然后在usart.h中声明。这样就可以直接使用printf函数了。
int fputc(int a,FILE *p)//重定向函数
{
	usart1_tx(a);
	return a;
}
-- 应用
  • main.c
int main()
{
	usart_init();
	
	uint8_t str[] = "123456789";
	
	uint8_t len = strlen((char *)str);
	
	for(uint8_t i=0;i<len;i++)
		usart1_tx(str[i]);
	//usart1_tx(0x1);
	
	uint8_t data = usart1_rx();//可以协助我们调试代码,接收到了,m
	printf("data:%d\r\n",data);//这里的换行是\r\n					//这里是发送到串口。可以根据是否发送到串口来判断程序是否正常执行
    }

-- 这里的printf可以用来调试程序,前面已经将printf重定向到串口了,所以可以直接使用printf函数,将数据发送到串口上。在想知道一个模块是否执行时,就可以写一个printf,看是否发送数据来看是否执行这个模块。


  • 使用串口助手向单片机发送数据,控制led状态。例如:发送“1111”,4个led灯全亮;发送“1010”,13灯亮,24灯灭;发送“0000”,4个led灯全灭。(90%)
int main()
{
	led_init();
	
	uint8_t str[] = "123456789";
	
	uint8_t len = strlen((char *)str);
	
	for(uint8_t i=0;i<len;i++)
		usart1_tx(str[i]);

	
	while(1)
	{
		uint8_t data[20]={0};
		for(uint8_t i=0;i<4;i++)
		data[i] = usart1_rx();
		if(!strcmp(data,"1111"))
		{
			LED1(1);LED2(1);LED3(1);LED4(1);
		}else if(!strcmp(data,"1010")){
			LED1(1);LED2(0);LED3(1);LED4(0);
		}else if(!strcmp(data,"0000")){
			LED1(0);LED2(0);LED3(0);LED4(0);
		}
		printf("data:%s\r\n",data);//这里的换行是\r\n					//这里是发送到串口。可以根据是否发送到串口来判断程序是否正常执行
    }
}
	
  • 注意这里的换行符必须是\r\n

alt text

alt text


6、中断

-- 因为接收函数中写了,如果读不到数据们将会阻塞等待,会影响后面的程序 

alt text

alt text

  • 所以要采用中断的方式来接收数据,那么初始化函数就要加上中断的初始化

既要初始化中断,还要使能中断源

使能中断源,先从函数库中找相应的函数

alt text

 

alt text

复制例子,并更改

  • usart.c
	//使能中断源			//串口有10个,用哪一个就要开哪一个中断源
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	//中断
	NVIC_InitTypeDef NVIC_InitStructure = {0}; 
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能(使能哪个中断通道,就要写哪个(必须写)中断服务函数)
	NVIC_Init(&NVIC_InitStructure);

  • 中断服务函数的内容

1、判断中断是否发生 

alt text

 2、处理中断 3、清理中断 

alt text

uint8_t usart1_buff[10] = {0};//这些参数还要再usart.h中声明
uint8_t usart1_len = 0;

void USART1_IRQHandler(void)//串口收到1字节数据,中断就会被触发一次
{
	//判断接收中断是否发生
	if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		//处理中断:保存数据
		usart1_buff[usart1_len++] = USART_ReceiveData(USART1);
		usart1_len %= 10;//对10求余,他就一直会小于10
		//清理终端
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
	}
}
  • main.c
if(usart1_len == 4)//如果接收到的数据为4位时
	{
		if(usart1_buff[0] == '0')
			LED1(0);
		else if(usart1_buff[0] == '1')
			LED1(1);
		
		if(usart1_buff[1] == '0')
			LED2(0);
		else if(usart1_buff[1] == '1')
			LED2(1);
		
		if(usart1_buff[2] == '0')
			LED3(0);
		else if(usart1_buff[2] == '1')
			LED3(1);
		
		if(usart1_buff[3] == '0')
			LED4(0);
		else if(usart1_buff[3] == '1')
			LED4(1);
	
		memset(usart1_buff,0,10);//数据处理完毕之后,将这次数据全部清0
		usart1_len = 0;
	}
  • 注:数据处理完毕后,记得清理。

usart.c完整代码

#include "usart.h"

void usart_init(void)
{
	//时钟 A端口  USART1(外设自身也有时钟)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);			//看数据手册在哪条线上 - APB2
	
	//IO PA9/PA10
	GPIO_InitTypeDef GPIO_InitStructure = {0};						//定义结构体变量,并且将结构体变量赋初值
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 						//引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//速度
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//PA9 复用推挽
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 							//引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;		//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure = {0};
	USART_InitStructure.USART_BaudRate = 9600;   					 			//波特率  常用的是4800 9600  115200
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	//数据位长度
	USART_InitStructure.USART_StopBits = USART_StopBits_1;			//停止位长度
	USART_InitStructure.USART_Parity = USART_Parity_No;				//奇偶校验(这里写不使用)
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制失能(不使用硬件流控制)
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//模式
	USART_Init(USART1, &USART_InitStructure);
	
	USART_Cmd(USART1,ENABLE);//开启串口    //使能或者失能 USART 外设(一般外设都要写这个)
	
	
	//使能中断源			//串口有10个,用哪一个就要开哪一个中断源
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	//中断
	NVIC_InitTypeDef NVIC_InitStructure = {0}; 
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能(使能哪个中断通道,就要写哪个(必须写)中断服务函数)
	NVIC_Init(&NVIC_InitStructure);
	
}



//应用函数

//发送
void usart1_tx(uint8_t data)//参数就是要发送的数据
{
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE )== RESET){}
		//上次的数据发送完成,为空表示上个数据已经发送完成
		//等待的时候是还没有发送,一旦发送完成,就变成1了
	USART_SendData(USART1, data);
}

//接收

uint8_t usart1_rx(void)
{
	while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){} 			//接收数据寄存器非空标志位
	uint8_t RxData = USART_ReceiveData(USART1);
	return RxData;
}

int fputc(int a,FILE *p)//重定向函数
{
	usart1_tx(a);
	return a;
}

uint8_t usart1_buff[10] = {0};
uint8_t usart1_len = 0;

void USART1_IRQHandler(void)//串口收到1字节数据,中断就会被触发一次
{
	//判断接收中断是否发生
	if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		//处理中断:保存数据
		usart1_buff[usart1_len++] = USART_ReceiveData(USART1);
		usart1_len %= 10;//对10求余,他就一直会小于10
		//清理终端
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
	}
}

  • usart.h
#ifndef _USART_H_
#define _USART_H_

#include "stdio.h"
#include "STM32f10x.h"

void usart_init(void);
void usart1_tx(uint8_t data);
uint8_t usart1_rx(void);

int fputc(int a,FILE *p);

extern uint8_t usart1_buff[10];
extern uint8_t usart1_len;


#endif
s

```s

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

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

相关文章

【Git入门】使用 Git 进行项目管理:Word Count 程序开发与托管

在软件开发过程中&#xff0c;版本控制工具是不可或缺的。Git 作为一款强大的分布式版本控制工具&#xff0c;为开发者提供了高效的代码管理和协作方式。本博客将介绍如何下载安装 Git 版本管理工具&#xff0c;并使用 Git 和 GitHub 平台进行一个名为 Word Count 的项目开发与…

【鸿蒙HarmonyOS NEXT】数据存储之关系型数据库RDS

【鸿蒙HarmonyOS NEXT】数据存储之关系型数据库RDS 一、环境说明二、关系型数据库RDS介绍三、示例代码加以说明四、小结 一、环境说明 DevEco Studio 版本&#xff1a; API版本&#xff1a;以12为主 二、关系型数据库RDS介绍 1. RDS关系型数据库简介&#xff1a; 关系型数…

VMware提供虚拟硬盘并使得Oracle Linux集群共享块设备并绑定raw设备。

一、Vmware操作 nodeA : 1、创建SCSI控制器:类型为物理。 添加新磁盘。 类型为独立-持久。 nodeB: 新增磁盘,但是选择node A刚才创建的磁盘。 类型:独立-持久。 二、OS层操作 两台都要做绑定。 详细步骤 1. 创建 raw 设备节点 首先,确保 /dev/raw 目录存在。如果不…

5分钟精通Excel在go中的使用

一些简单操作可以在官方文档中找到&#xff0c;应该足够无经验的朋友们入门 介绍 - 《Excelize v2.2 中文文档》 - 书栈网 BookStack 这里贴一个中文版的链接&#xff08;以excelize库为例&#xff0c;相对其他库来说&#xff0c;体验很不错&#xff09;&#xff0c;不过要注…

沉浸式艺术创作:FLUX.1模型下的Java开发者体验之旅

文章目录 1 FLUX.1革命2 应用落地3 部署ComfyUI4 部署FLUX.15 导入工作流6 新的挑战 1 FLUX.1革命 FLUX.1&#xff1a;图像生成的新纪元 在人工智能的图像生成领域&#xff0c;FLUX.1模型的出现标志着一个新的时代。 由黑森林实验室&#xff08;Black Forest Labs&#xff0…

Android 车载应用开发指南 - CarService 详解(下)

车载应用正在改变人们的出行体验。从导航到娱乐、从安全到信息服务&#xff0c;车载应用的开发已成为汽车智能化发展的重要组成部分。而对于开发者来说&#xff0c;如何将自己的应用程序无缝集成到车载系统中&#xff0c;利用汽车的硬件和服务能力&#xff0c;是一个极具挑战性…

数据报文解析

数据报文解析 报文介绍 如下图所示&#xff0c;每一层把上传的协议包当作数据部分&#xff0c;加上自己的协议头部&#xff0c;组成自己的协议包。 一般说法&#xff1a;默认以太网协议包&#xff08;网络层从IP头部开始计算&#xff09;最大传输单元&#xff08;MTU&#x…

记一次sql查询优化

记一次sql查询优化 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 今天测试环境发现一个问题&#xff0c;就是测试同事在测试的时候&#xff0c;发现cpu一直居高不下&#xff0c;然…

CNN网络训练WISDM数据集:模型仿真及可视化分析

卷积神经网络&#xff08;CNN&#xff09;因其强大的特征提取能力和深度学习架构而备受推崇&#xff0c;CNN在处理图像数据时展现出的卓越性能&#xff0c;使其成为解决各种视觉识别任务的首选工具。WISDM数据集是一个广泛用于运动估计研究的基准数据集&#xff0c;它包含了多个…

EmguCV学习笔记 VB.Net 11.9 姿势识别 OpenPose

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

AMEYA360代理:兆易创新GD32A7系列全新一代车规级MCU介绍

兆易创新GigaDevice(股票代码 603986)今日宣布&#xff0c;重磅推出全新一代车规级MCU GD32A7系列。与上一代采用Arm Cortex-M4/M33的产品相比&#xff0c;GD32A7系列搭载了超高性能Arm Cortex-M7内核&#xff0c;提供GD32A71x/GD32A72x/GD32A74x等多款型号供用户选择。该系列产…

git 生成和查看密钥

项目场景&#xff1a; 在前端项目开发中&#xff0c;经常会用到git。一般的小公司很少去设置git令牌或者密钥&#xff1b;而在一些大公司&#xff0c;会用到这个。今天主要整理下git如何生成和查看密钥。 密钥 1、生成密钥 cat ~/.ssh/id_rsa.pub 2、查看密钥 ssh-keygen…

电容笔最建议买哪一款?2024百元价位性价比首选榜单,速速码住!

现在电容笔已经成为我们日常学习、工作和创作中不可或缺的辅助工具。无论是记笔记、做习题&#xff0c;还是进行绘画、设计&#xff0c;电容笔都发挥着关键作用。然而&#xff0c;市场上的电容笔品牌和款式繁多&#xff0c;价格也从几十元到上千元不等&#xff0c;这让消费者在…

OSError: [Errno 16] Device or resource busy: ‘.nfs*‘报错解决办法

目录 1 项目场景&问题描述&#xff1a;2 原因分析&#xff1a;2.1 问题背景&#xff1a; 3 解决方案&#xff1a;3.1 创建存放临时文件的目录3.2 使用该目录3.2.1 设置环境变量 TMPDIR3.2.2 运行时设置&#xff08;推荐&#xff09;3.2.3 代码中设置 4 总结 1 项目场景&…

Redis 键值对数据库学习

目录 一、介绍 二、安装以及连接 三、设置连接密码 四、连接报错 五、redis 操作字符串以及过期时间 六、 redis 列表操作 七、redis 集合操作 八、hash 哈希操作 九、redis 发布和订阅操作 十、RDB和AOF的两种数据持久化机制 十一、 其他机器连接redis 十二、 pyt…

【Linux】解锁文件描述符奥秘,高效缓存区的实战技巧

fd和缓冲区 1. 文件描述符fd1.1. 概念与本质1.2. 打开文件的管理1.3. 一切皆文件的理解1.4. 分配规则1.5. 重定向的本质1.5.1. dup2 2. FILE中的缓冲区2.1. 概念2.2. 存在的原因2.3. 类型(刷新方案)2.4. 存放的位置2.4.1. 代码证明、现象解释 2.5. 模拟C标准库中的方法 1. 文件…

LiveGBS流媒体平台GB/T28181功能-支持电子放大拉框放大直播视频拉框放大录像视频流拉框放大电子放大

LiveGBS流媒体平台GB/T28181功能-支持电子放大拉框放大直播视频拉框放大录像视频流拉框放大电子放大 1、直播播放2、录像播放3、搭建GB28181视频直播平台 1、直播播放 国标设备-》查看通道-》播放 &#xff0c;左键单击可以拉取矩形框&#xff0c;放大选中的范围&#xff0c;释…

IPD如何解决产品开发的典型问题

IPD&#xff08;Integrated Product Development&#xff0c;集成产品开发&#xff09;是一种领先的、成熟的产品开发的管理思想和管理模式。它是根据大量成功的产品开发管理实践总结出来的&#xff0c;并被大量实践证明的高效的产品开发模式。从汉捷咨询二十多年来为五百多家企…

如何通过代理使用 Squid: 综合指南

文章目录 一、简介二、什么是 Squid?三、为什么在代理服务器中使用 Squid&#xff1f;四、设置代理五、使用代理设置 Squid5.1. 第一步5.2. 第二步5.3. 第三步 六、在网络搜索中使用代理&#xff1a;实用代码示例6.1. 使用代理的 cURL6.2. 使用代理的 Python 请求 七、结论 一…

嘉立创EDA-- 线宽、过孔和电流大小对比图

导线宽度和电流大小如何来考虑 1 电流大小需要考虑问题 1、允许的温升&#xff1a;如果能够允许的铜线升高的温度越高&#xff0c;那么允许通过的电流自然也就越高 2、走线的线宽&#xff1a;线越宽 &#xff0c;导线横截面积越大&#xff0c;电阻越小&#xff0c;发热越小&a…