当前位置: 首页 > news >正文

STM32单片机——串口通信(轮询+中断)

STM32单片机——串口通信(轮询+中断)

  • 串口通信相关概念
  • HAL库解析及CubeMX工程配置与程序设计
    • 常用函数介绍
    • CubeMX工程配置
    • HAL库程序设计(轮询+中断)
      • 轮询数据收发
      • 中断收发数据
  • 固件库程序设计及实现
    • 固件库配置流程
    • 结构体配置及初始化程序
    • 串口发送自定义函数封装
    • 中断服务函数(数据接收)
    • 串口常用函数汇总

串口通信相关概念

  • 参考博文:STM32通信——串口通信概念详解

HAL库解析及CubeMX工程配置与程序设计

常用函数介绍

  • 串口发送/接收函数

    HAL_UART_Transmit();	//串口发送数据,轮询发送
    HAL_UART_Receive();		//串口接收数据,轮询发送
    HAL_UART_Transmit_IT();	//串口中断模式发送
    HAL_UART_Receive_IT();	//串中断模式接收
    

    函数原型参数解析:
    以阻塞的方式发送指定字节的数据

    HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
    
    参数解析
    UART_HandleTypeDef huartUART_HandleTypeDef 结构体类型指针变量
    uint8_t * pData指向要发送的数据地址
    uint16_t Size要发送的数据大小,以字节为单位
    uint32_t Timeout设置的超时时间,以ms单位

    以中断的方式接收指定字节的数据

    HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart,
    uint8_t *pData, uint16_t Size)
    

    此函数执行完后将清除中断,需要再次调用以重新开启中断

    参数解析
    UART_HandleTypeDef huartUART_HandleTypeDef 结构体类型指针变量
    uint8_t * pData指向接收数据缓冲区
    uint16_t Size要发送的数据大小,以字节为单位
  • 串口中断回调函数

    HAL_UART_IRQHandler(UART_HandleTypeDef*huart);		//串中断处理函数
    HAL_UART_TxCpltCallback(UART_HandleTypeDef*huart);	//发送中断回调函数
    HAL_UART_RxCpltCallback(UART_HandleTypeDef*huart);	//接收中断回调函数
    

CubeMX工程配置

  • 时钟配置
    1. 采用外部高速晶振
    2. 时钟树配置
  • 配置串口通信
    1. 配置异步通信模式
    2. 串口波特率及参数配置
    3. 打开串口中断(使用中断收发才需配置,轮询可不配置)

HAL库程序设计(轮询+中断)

轮询数据收发

  • 1. 轮询发送
    HAL_UART_Transmit(&huart1,(unsigned char *)"hello world\r\n", strlen("hello world\r\n"),100);
    
  • 2. printf重定向
    int fputc(int ch, FILE *f)
    {unsigned char temp[1]={ch};HAL_UART_Transmit(&huart1,temp,1,0xffff);return ch;
    }
    
  • 3. 轮询接收
    unsigned char  uart1_buf[20] = {0};		//接收数据缓冲区while(1)
    {HAL_UART_Receive(&huart1, uart1_buf, 19, 100);HAL_UART_Transmit(&huart1, uart1_buf, strlen(uart1_buf), 100);if(strstr(uart1_buf,"open") != NULL)HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);else if( strstr(uart1_buf,"close") != NULL )HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);memset(uart1_buf, 0, strlen(uart1_buf));	
    }
    

中断收发数据

  • 1. 中断发送
    //usart.c 函数封装
    void SendString(UART_HandleTypeDef *huart, char *String)
    {HAL_UART_Transmit_IT(huart,(uint8_t *)String,strlen(String));
    }
    //main.c 函数调用
    SendString(&huart1,"haha\r\n");
    
  • 2. 中断接收
    //串口中断接收变量定义
    unsigned char UART1_RX_Buffer[256];	//串口接收数组
    unsigned char UART1_RX_index = 0;	//接收下标计数器	
    unsigned char UART1_RX_flag  = 0;	//接收下标计数器	//开启接收中断,一次接收1个字符
    HAL_UART_Receive_IT(&huart1, (uint8_t *)&RX_ch, 1);//中断服务函数
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {unsigned char RX_ch = '\0';			//接收中断缓冲if(huart->Instance == USART1){if(UART1_RX_index >= 255)  //溢出判断{UART1_RX_index = 0;memset(UART1_RX_Buffer,0x00,sizeof(UART1_RX_Buffer));}else			//正常接收数据,并放入数组{UART1_RX_Buffer[UART1_RX_index++] = RX_ch;   //接收数据转存if((UART1_RX_Buffer[UART1_RX_index-1] == 0x0A)&&(UART1_RX_Buffer[UART1_RX_index-2] == 0x0D)) //判断结束位{HAL_UART_Transmit(&huart1, (uint8_t *)&UART1_RX_Buffer, UART1_RX_index,0xFFFF); //将收到的信息发送出去UART1_RX_index = 0;memset(UART1_RX_Buffer,0x00,sizeof(UART1_RX_Buffer)); //清空数组}}//命令执行语句 对于复杂执行语句立flag, 在main函数中执行if(strstr((const char *)UART1_RX_Buffer,"open") != NULL)HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);else if( strstr((const char *)UART1_RX_Buffer,"close") != NULL )HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);HAL_UART_Receive_IT(&huart1, (uint8_t *)&RX_ch, 1);   //再开启接收中断	}
    }
    

固件库程序设计及实现

固件库配置流程

  • 1.配置时钟:GPIO的时钟,串口的时钟,引脚复用的时钟
  • 2.配置GPIO的结构体
  • 3.配置串口的结构体
  • 4.NVIC中断配置
  • 5.数据发送及中断服务函数

结构体配置及初始化程序

  • 使能时钟

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	//使能USART1时钟
    
  • 使能GPIO口

    GPIO_InitTypeDef GPIO_InitStructure;
    //USART1_TX   GPIOA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 			//PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;		//复用推挽输出//USART1_RX	  GPIOA.10初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;			//PA10
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
    
  • 串口参数配置

    USART_InitTypeDef USART_InitStructure;//USART 初始化设置
    USART_InitStructure.USART_BaudRate = bound;												//串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;		//字长为8位数据格式
    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_Rx | USART_Mode_Tx;	//收发模式
    USART_Init(USART1, &USART_InitStructure); 						//初始化串口1USART_Cmd(USART1, ENABLE);                   					//使能串口1 
    
  • NVIC中断配置

    NVIC_InitTypeDef NVIC_InitStructure;//Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);	//开启串口接受中断
    
  • 串口1初始化程序

    void Usart1_Init(u32 bound)
    {//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟//USART1_TX   GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX	  GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式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_Rx | USART_Mode_Tx;	//收发模式USART_Init(USART1, &USART_InitStructure); 			//初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);	//开启串口接受中断USART_Cmd(USART1, ENABLE);                    	//使能串口1 
    }
    

串口发送自定义函数封装

  • printf重定向

    int fgetc(FILE *f)
    {while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)==RESET);return (int)USART_ReceiveData(USART1);
    }
    
  • 串口写字节函数

    /** 功能:串口写字节函数* * 参数1:USARTx :串口号* * 参数2:Data   :需写入的字节*/
    void USART_Send_Byte(USART_TypeDef* USARTx, uint16_t Data)
    {USART_SendData(USARTx, Data);while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE)==RESET);
    }
    
  • 串口发送字符串函数

    /*
    *	函数名称:	Usart_SendString
    *	
    *	函数功能:	串口数据发送
    *	
    *	入口参数:	USARTx:串口组
    *	
    *				str:要发送的数据
    *	
    *				len:数据长度
    */
    void Usart_SendString(USART_TypeDef *USARTx, unsigned char *str, unsigned short len)
    {unsigned short count = 0;for(; count < len; count++){USART_SendData(USARTx, *str++);									//发送数据while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);		//等待发送完成}
    }
    
  • 串口格式化打印

    /*
    *	函数名称:	UsartPrintf
    *
    *	函数功能:	格式化打印
    *
    *	入口参数:	USARTx:串口组
    *				fmt:不定长参	
    */
    #include <stdarg.h>
    void UsartPrintf(USART_TypeDef *USARTx, char *fmt,...)
    {unsigned char UsartPrintfBuf[296];va_list ap;unsigned char *pStr = UsartPrintfBuf;va_start(ap, fmt);vsnprintf((char *)UsartPrintfBuf, sizeof(UsartPrintfBuf), fmt, ap);							//格式化va_end(ap);while(*pStr != 0){USART_SendData(USARTx, *pStr++);while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);}
    }
    

中断服务函数(数据接收)

//串口接收变量定义
unsigned char usart1_buffer[128] = {'\0'};	//接收缓存
unsigned char usart1_index = 0;				//中断下标索引
unsigned char usart1_flag = 0;				//中断标志位//串口中断服务函数
void USART1_IRQHandler(void)
{uint16_t ch;			//串口接收字节缓冲if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //串口收到数据{if(usart1_index == 127)												//下标溢出{	usart1_index = 0;memset(usart1_buffer,0x00,sizeof(usart1_buffer));}ch = USART_ReceiveData(USART1);								//串口接收1个字节usart1_buffer[usart1_index++] = ch;						//数据存入接收数组if((usart1_buffer[usart1_index-1] == 0x0A)&&(usart1_buffer[usart1_index-2] == 0x0D)) //判断结束位{Usart_SendString(USART1,usart1_buffer,usart1_index);usart1_index = 0;//执行命令语句 对于复杂执行语句立flag, 在main函数中执行if(strstr((const char *)usart1_buffer,"open") != NULL)	//检测到open信号LED1 = 0;if(strstr((const char *)usart1_buffer,"close") != NULL)LED1 = 1;memset(usart1_buffer,0x00,sizeof(usart1_buffer)); 		//清空数组}USART_ClearFlag(USART1, USART_FLAG_RXNE);								//清除中断标志}
}

串口常用函数汇总

初始化函数:
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
串口使能函数:
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
中断配置函数:
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
串口发送函数:
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
串口接收读取函数:
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
获取响应的串口表示位:
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
中断状态位获取:
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);

相关文章:

STM32单片机——串口通信(轮询+中断)

STM32单片机——串口通信&#xff08;轮询中断&#xff09; 串口通信相关概念HAL库解析及CubeMX工程配置与程序设计常用函数介绍CubeMX工程配置HAL库程序设计&#xff08;轮询中断&#xff09;轮询数据收发中断收发数据 固件库程序设计及实现固件库配置流程结构体配置及初始化程…...

Python if语句的嵌套应用

视频版教程 Python3零基础7天入门实战视频教程 有时候业务上有多维度复杂条件判断&#xff0c;我们需要用到if语句的嵌套来实现。 举例&#xff1a;我们在一些游戏网站活动充值的时候&#xff0c;冲100送 20 冲200送50 但是vip用户的话&#xff0c;冲100送 30 冲200送70 代码…...

C++中带默认值的函数参数

C中带默认值的函数参数 如果一直将 Pi 声明为常量&#xff0c;没有给用户提供修改它的机会。然而&#xff0c;用户可能希望其精度更高或更低。如何编写一个函数&#xff0c;在用户没有提供的情况下&#xff0c;将 Pi 设置为默认值呢&#xff1f; 为解决这种问题&#xff0c;一…...

记录一次部署Hugo主题lotusdocs到Github Pages实践

引言 随着开源项目的越来越复杂&#xff0c;项目文档的重要性日渐突出。一个好的项目要有一个清晰明了的文档来帮助大家使用。最近一直有在找寻一个简洁明了的文档主题来放置项目的各种相关文档。最终找到这次的主角&#xff1a;Lotus Docs 基于Hugo的主题。Lotus Docs的样子&…...

stm32---基本定时器(TIM6,TIM7)

STM32F1的定时器非常多&#xff0c;由两个基本定时器&#xff08;TIM6&#xff0c;TIM7&#xff09;、4个通用定时器&#xff08;TIM2-TIM5&#xff09;和两个高级定时器&#xff08;TIM&#xff11;&#xff0c;TIM&#xff18;&#xff09;组成。基本定时器的功能最为简单&am…...

HTML网页设计

HTML网页设计 HTML网页设计1、常用的单标签2、常用的双标签3、列表标签4、超链接标签5、图像和动画标签6、Html5中音频的插入7、定时刷新或跳转8、表格9、HTML表单标签与表单设计 HTML网页设计 属性值一般用" "括起来&#xff0c;且必须使用英文双引号 <head>…...

阶段性总结:跨时钟域同步处理

对时序图与Verilog语言之间的转化的认识&#xff1a; 首先明确工程要实现一个什么功能&#xff1b;用到的硬件实现一个什么功能。 要很明确这个硬件的工作时序&#xff0c;即&#xff1a;用什么样的信号&#xff0c;什么变化规则的信号去驱动这个硬件。 然后对工程进行模块划…...

[交互]接口与路由问题

[交互]接口与路由问题 场景描述问题分析解决方案 这是在实战开发过程中遇到的一个问题&#xff0c;所以导致产生了服务端如何区分浏览器请求的是前端路由还是 api 接口的问题&#xff1f;&#xff1f; 场景描述 这是一个前后端分离开发的项目&#xff0c;因此前端一般都会使用…...

linux 6中4T磁盘识别并分区格式化挂接

存储端划分4T的LUN后&#xff0c;主机端操作如下 1、主机识别&#xff0c;本例中hba卡的端口是host11和host12 [rootdb1 ~]# echo "- - -" > /sys/class/scsi_host/host11/scan [rootdb1 ~]# echo "- - -" > /sys/class/scsi_host/host12/scan …...

【Unity】ShaderGraph应用(浮动气泡)

【Unity】ShaderGraph应用(浮动气泡) 实现效果 一、实现的方法 1.使用节点介绍 Position&#xff1a;获取模型的顶点坐标 Simple Noise:简单的噪声&#xff0c;用于计算顶点抖动 Fresnel Effect&#xff1a;菲涅耳效应&#xff0c;用于实现气泡效果 计算用节点 Add&…...

Android EditText setTranslationY导致输入法覆盖问题

平台 RK3288 Android 8.1 显示: 1920x1080 160 dpi 概述 碰到一个问题&#xff1a; 弹出的输入法会覆盖文本输入框。 原因&#xff1a;输入框使用了setTranslationY() 位置偏移后&#xff0c; 输入法无法正确获取焦点的位置。 分析 先上图: 初始布局 调用etTranslation…...

MySQL 导出和导入数据

文章目录 一&#xff0c;导出数据&#xff08;一&#xff09;使用SELECT ... INTO OUTFILE语句导出数据&#xff08;二&#xff09;使用mysqldump工具导出数据&#xff08;三&#xff09;使用SELECT ... INTO DUMPFILE语句导出数据 二&#xff0c;导入数据&#xff08;一&#…...

ubuntu22.04 设置网卡开机自启

配置文件路径 在Ubuntu中&#xff0c;网络配置文件通常位于/etc/netplan/目录下&#xff0c;其文件名以.yaml为后缀。Netplan是Ubuntu 17.10及更高版本中默认的网络配置工具&#xff0c;用于配置网络接口、IP地址、网关、DNS服务器等。 我们可以看到配置文件为 01-network-ma…...

持续部署:提高敏捷加速软件交付(内含教程)

在当今快节奏的数字化环境中&#xff0c;企业不断寻求更快地交付软件、增强客户体验并在竞争中保持领先的方法。持续部署&#xff08;Continuous Deployment, CD&#xff09;已成为一种改变游戏规则的方法&#xff0c;使企业能够简化软件交付、提高敏捷性并缩短上市时间。持续部…...

Spark_Spark内存模型管理

工作中经常用到Spark内存调参&#xff0c;之前还没对这块记录&#xff0c;这次记录一下。 环境参数 spark 内存模型中会涉及到多个配置&#xff0c;这些配置由一些环境参数及其配置值有关&#xff0c;为防止后面理解混乱&#xff0c;现在这里列举出来&#xff0c;如果忘记了&a…...

C++之operator=与operator==用法区别(二百一十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

【漏洞复现】WordPress插件wp-file-manager任意文件上传漏洞(CVE-2020-25213)

文章目录 前言声明一、简介二、插件介绍三、漏洞概述四、影响范围五、漏洞分析六、环境搭建七、漏洞复现手工验证file_Manager_Rce.pyfile_manager_upload.py八、修复建议前言 WordPress插件WPFileManager中存在一个严重的安全漏洞,攻击者可以在安装了此插件的任何WordPress网…...

基于安卓Java试题库在线考试系统uniapp 微信小程序

本文首先分析了题库app应用程序的需求&#xff0c;从系统开发环境、系统目标、设计流程、功能设计等几个方面对系统进行了系统设计。开发出本题库app&#xff0c;主要实现了学生、教师、测试卷、试题、考试等。总体设计主要包括系统功能设计、该系统里充分综合应用Mysql数据库、…...

Java入坑之语法糖

一、for和for-each 1.1for和for-each概念 for 循环是一种常用的循环结构&#xff0c;它可以通过一个变量&#xff08;通常是 i&#xff09;来控制循环的次数和范围。for 循环的语法格式如下&#xff1a; for (初始化; 布尔表达式; 更新) {//代码语句 }for-each 循环是 Java …...

VUE响应式

响应式 :::tip 提示 我们了解过响应式可以同步更新数据和视图&#xff0c;但是其工作原理我们最好也要了解一下。这样当你使用时遇到一些常见的错误&#xff0c;也能够快速定位是什么问题导致的。 了解响应式原理之前&#xff0c;你必须要先去了解 ES5 的 Object.defineProper…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...