【嵌入式】HC32F07X CAN通讯配置和使用配置不同缓冲器以连续发送
一 背景说明
使用小华(华大)的MCU HC32F07X实现 CAN 通讯配置和使用
二 原理分析
【1】CAN原理说明(参考文章《CAN通信详解》):
CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种能够实现分布式实时控制的串行通信网络。
(i)CAN通信形式:CAN 使用称为 CANH / CANL 的通信线路执行传输和接收。电位差较小的电信号称为隐性信号,其逻辑值为1。电位差较大的电信号称为显性信号,其逻辑值0。如果通信总线上发生显性和隐性冲突,则显性优先。总线空闲时保持隐性。
(ii)CAN数据格式:CAN的数据定义了有5种帧类型:
(ii)CAN数据帧:数据帧一般由 7 个段构成,即:
(1) 帧起始。表示数据帧开始的段。
(2) 仲裁段。表示该帧优先级的段。
(3) 控制段。表示数据的字节数及保留位的段。
(4) 数据段。数据的内容,一帧可发送 0~8 个字节的数据。
(5) CRC 段。检查帧的传输错误的段。
(6) ACK 段。表示确认正常接收的段。
(7) 帧结束。表示数据帧结束的段
图中 D 表示显性电平, R 表示隐形电平。
更多具体内容不再赘述,可以参考上面的文章链接或者自行搜索。
【2】HC32F07X的CAN外设:
芯片CAN外设的主要特性:
■ 完全支持 CAN2.0A/CAN2.0B 协议。
■ 向上兼容 CAN-FD 协议。
■ 支持最高通信波特率 1Mbit/s
■ 支持 1~1/256 的波特率预分频, 灵活配置波特率。
■ 10 个接收缓冲器
- FIFO 方式
- 错误或者不被接收的数据不会覆盖存储的消息
■ 1 个高优先主发送缓冲器 PTB
■ 4 个副发送缓冲器 STB
- FIFO 方式
- 优先级仲裁方式
■ 8 组独立的筛选器
- 支持 11 位标准 ID 和 29 位扩展 ID
- 可编程 ID CODE 位以及 MASK 位
■ PTB/STB 均支持支持单次发送模式
■ 支持静默模式
■ 支持回环模式
■ 支持捕捉传输的错误种类以及定位仲裁失败位置
■ 可编程的错误警告值
■ 支持 ISO11898-4 规定时间触发 CAN 以及接收时间戳
系统框图如下:
更多详细的内容可以参考HC32F07X芯片的DATASHEET。
三 CAN通讯硬件设计
以下推荐了两个CAN收发的硬件电路,可以将外部的 CANH/CANL 差分信号,转换为 CAN_TX/CAN_RX 信号用以内部MCU处理。一个是官方提供的,一个是开发板提供的,都可以正常使用。
注意CAN通信需要5V,用以给收发器供电。
【1】推荐电路1:
参考官方的硬件设计指南《AN_HC32L072_HC32L073_HC32F072系列硬件开发指南_Rev1.1》,里面对于CAN通信收发的硬件电路有如下推荐电路,其中使用了NXP的 TJA1042 作为收发器:
【2】推荐电路2:
使用的周立功开发板中也引出了CAN功能,其中使用了NXP的TJA1051T作为收发器:
四 CAN通讯软件配置
选用引脚 PD00(CAN_RX)、PD01(CAN_TX)、PC12(CAN_STB)实现CAN通信功能,使用时钟频率为48MHz(官方例程使用的是外部8M晶振),CAN通讯波特率为1M,标准帧ID号为1。
【1】系统时钟配置:
static void App_SysClkInit(void)
{stc_sysctrl_clk_cfg_t stcCfg;stc_sysctrl_pll_cfg_t stcPLLCfg;Sysctrl_SetPeripheralGate(SysctrlPeripheralFlash, TRUE); ///< 使能FLASH模块的外设时钟Flash_WaitCycle(FlashWaitCycle1);Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz); ///< PLL使用RCH作为时钟源,因此需要先设置RCHstcPLLCfg.enInFreq = SysctrlPllInFreq4_6MHz; ///< RCH 4MHzstcPLLCfg.enOutFreq = SysctrlPllOutFreq36_48MHz; ///< PLL 输出48MHzstcPLLCfg.enPllClkSrc = SysctrlPllRch; ///< 输入时钟源选择RCHstcPLLCfg.enPllMul = SysctrlPllMul12; ///< 4MHz x 12 = 48MHzSysctrl_SetPLLFreq(&stcPLLCfg);///< 选择PLL作为HCLK时钟源;stcCfg.enClkSrc = SysctrlClkPLL;///< HCLK SYSCLK/2stcCfg.enHClkDiv = SysctrlHclkDiv1;///< PCLK 为HCLK/8stcCfg.enPClkDiv = SysctrlPclkDiv1;///< 系统时钟初始化Sysctrl_ClkInit(&stcCfg);
}
【2】CAN初始化GPIO:
//CAN通信引脚定义
#define CAN_RX_PORT (GpioPortD)
#define CAN_RX_PIN (GpioPin0)
#define CAN_TX_PORT (GpioPortD)
#define CAN_TX_PIN (GpioPin1)
#define CAN_STB_PORT (GpioPortC)
#define CAN_STB_PIN (GpioPin12)#define APB1_CLK 48000000 //CAN 的输入时钟
#define CAN_BAUD 1000000 //CAN 的波特率/**************************************************************************
* 函数名称: COM_Init
* 功能描述: CAN通信初始化GPIO
**************************************************************************/
void COM_Init(void)
{stc_gpio_cfg_t stcGpioCfg;Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);stcGpioCfg.enDir = GpioDirIn; ///< 端口方向配置->输入stcGpioCfg.enDrv = GpioDrvL; ///< 端口驱动能力配置->高驱动能力stcGpioCfg.enPu = GpioPuDisable; ///< 端口上下拉配置->无stcGpioCfg.enPd = GpioPdDisable;stcGpioCfg.enOD = GpioOdDisable; ///< 端口开漏输出配置->开漏输出关闭stcGpioCfg.enCtrlMode = GpioAHB; ///< 端口输入/输出值寄存器总线控制模式配置->AHBGpio_Init(CAN_RX_PORT, CAN_RX_PIN, &stcGpioCfg);stcGpioCfg.enDir = GpioDirOut;Gpio_Init(CAN_TX_PORT, CAN_TX_PIN, &stcGpioCfg);Gpio_Init(CAN_STB_PORT, CAN_STB_PIN, &stcGpioCfg);///<CAN RX\TX复用功能配置Gpio_SetAfMode(CAN_RX_PORT, CAN_RX_PIN, GpioAf1);Gpio_SetAfMode(CAN_TX_PORT, CAN_TX_PIN, GpioAf1);///<STB 低-PHY有效Gpio_ClrIO(CAN_STB_PORT, CAN_STB_PIN);
}
【3】CAN波特率自适应配置接口:
/**************************************************************************
* 函数名称: COM_BaudCfg
* 功能描述: CAN通信波特率自动配置
* 其他说明: 48MHz主频,1M波特率计算得到:SJW=2, PRESC=1-1, SEG_2=15, SEG_1=30若输入500K波特率,PRESC为2-1; 输入250K波特率,PRESC为4-1
**************************************************************************/
void COM_BaudCfg(stc_can_init_config_t *p_stcCanInitCfg, uint32_t src_clk, uint32_t baud)
{uint32_t i,value = baud,record = 1;uint32_t remain = 0,sum_prescaler = 0;while(( baud == 0 )||( src_clk == 0 ));sum_prescaler = src_clk / baud;for ( i = 73; i > 3; i-- ) {remain = sum_prescaler - ((sum_prescaler / i)*i);if( remain == 0 ) {record = i;break;} else {if (remain < value) {value = remain;record = i;}}}/* 设置重新同步跳跃宽度为2个时间单位 */p_stcCanInitCfg->stcCanBt.SJW = 2;p_stcCanInitCfg->stcCanBt.PRESC = (sum_prescaler/record) - 1;p_stcCanInitCfg->stcCanBt.SEG_2 = (record - 3) / 3;p_stcCanInitCfg->stcCanBt.SEG_1 = (record - 3) - p_stcCanInitCfg->stcCanBt.SEG_2;
}
【注】:CAN波特率的计算和配置,也可以使用CAN波特率计算器工具来计算得到(下载地址:CAN波特率计算器下载):
【4】CAN初始化配置(其中,波特率配置为1M,滤波器配置标准帧ID为1):
/**************************************************************************
* 函数名称: COM_Cfg
* 功能描述: CAN通信初始化配置
**************************************************************************/
void COM_Cfg(void)
{stc_can_init_config_t stcCanInitCfg;stc_can_filter_t stcFilter;Sysctrl_SetPeripheralGate(SysctrlPeripheralCan, TRUE);///<CAN 波特率配置COM_BaudCfg(&stcCanInitCfg, APB1_CLK, CAN_BAUD); //48MHz主频,1M波特率stcCanInitCfg.stcWarningLimit.CanErrorWarningLimitVal = 16-1;stcCanInitCfg.stcWarningLimit.CanWarningLimitVal = 10;stcCanInitCfg.enCanRxBufAll = CanRxNormal;stcCanInitCfg.enCanRxBufMode = CanRxBufNotStored;stcCanInitCfg.enCanSTBMode = CanSTBFifoMode;CAN_Init(&stcCanInitCfg);///<CAN 滤波器配置stcFilter.enAcfFormat = CanAllFrames;stcFilter.enFilterSel = CanFilterSel1;stcFilter.u32CODE = 0x00000001;stcFilter.u32MASK = 0x1FFFFFFF;CAN_FilterConfig(&stcFilter, TRUE);CAN_IrqCmd(CanRxIrqEn, TRUE);EnableNvic(CAN_IRQn, IrqLevel0, TRUE);
}
【5】CAN中断服务子程序(用于CAN接收):
stc_can_rxframe_t stcRxFrame;
stc_can_txframe_t stcTxFrame;
uint8_t u8RxFlag = FALSE;/**************************************************************************
* 函数名称: Can_IRQHandler
* 功能描述: CAN中断服务函数
**************************************************************************/
void Can_IRQHandler(void)
{if(TRUE == CAN_IrqFlgGet(CanRxIrqFlg)){CAN_IrqFlgClr(CanRxIrqFlg);CAN_IrqCmd(CanRxIrqEn, FALSE);CAN_Receive(&stcRxFrame);u8RxFlag = TRUE;}
}
【6】CAN发送接口(用于CAN发送):
/**************************************************************************
* 函数名称: COM_Tx
* 功能描述: CAN通信发送测试
**************************************************************************/
void COM_Tx(void)
{//中断接收,循环发送uint8_t u8Idx = 0;if(TRUE == u8RxFlag){u8RxFlag = FALSE;if(1 == stcRxFrame.Cst.Control_f.RTR){return;}//<<Can TxstcTxFrame.StdID = stcRxFrame.StdID;stcTxFrame.Control_f.DLC = stcRxFrame.Cst.Control_f.DLC;stcTxFrame.Control_f.IDE = stcRxFrame.Cst.Control_f.IDE;stcTxFrame.Control_f.RTR = stcRxFrame.Cst.Control_f.RTR;for(u8Idx=0; u8Idx<stcRxFrame.Cst.Control_f.DLC; u8Idx++){stcTxFrame.Data[u8Idx] = stcRxFrame.Data[u8Idx];}CAN_SetFrame(&stcTxFrame);CAN_TransmitCmd(CanPTBTxCmd);CAN_IrqCmd(CanRxIrqEn, TRUE);}
}
【7】主函数调用:
int32_t main(void)
{//系统时钟App_SysClkInit();//通信模块COM_Init();COM_Cfg();while(1){//通信COM_Tx();delay1ms(10);}
}
五 CAN通讯测试1(中断接收,Echo发送单帧)
进行CAN测试的方法很多,如果没有USB-CAN通信转换工具/CAN协议分析工具,可以增加CAN外部回环或者内部回环的配置,配合Log串口输出或者仿真器Debug进行测试。我这边使用了USB-CAN通信转换工具(CAN-II)/CAN协议分析工具(CANTest)直接进行收发测试:
【1】选择 CANTest 中的对应设备 USBCAN2:
【2】匹配软件中的波特率为1M,确定并启动CAN:
【3】修改帧ID为1,点击发送,可以看到上位机发送数据到测试板,经由测试板返回相同长度及内容的数据:
以上配置及测试成功。
六 CAN通讯测试2(中断接收,发送多帧)
【1】发送多帧背景说明:
实际应用中,往往需要收到一组请求之后,发送多组数据。尝试直接在 COM_Tx 函数中紧跟着第一帧数据发送之后再发一帧,有了如下操作:
实测上述连续发送的方法是错误的,因为时间间隔太短,前一组通过主缓冲器(PTB)发送的数据还没有完成就又收到新的发送命令,导致后发送的命令失败。
【2】同一个缓冲器连续发送多帧,中间加延时的方法:
使用同一个主缓冲器(PTB)发送,中间增加1ms延时等待上一帧发送结束(在我的系统上实测这个延迟的时间要大于500us,其他环境不绝对):
/**************************************************************************
* 函数名称: COM_Tx
* 功能描述: CAN通信发送测试
* 其他说明:
**************************************************************************/
void COM_Tx(void)
{uint8_t u8Idx = 0;if(TRUE == u8RxFlag){u8RxFlag = FALSE;if(1 == stcRxFrame.Cst.Control_f.RTR){return;}//<<主缓冲器Can Tx第一帧stcTxFrame.StdID = 0;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.TBUF32_2[0] = 0;stcTxFrame.TBUF32_2[1] = 1;CAN_SetFrame(&stcTxFrame);CAN_TransmitCmd(CanPTBTxCmd); //PTB发送命令delay1ms(1); //若使用单一缓冲器,连续发送失败,需要中间加延时等待上一帧发送结束(实测大于500us)stcTxFrame.StdID = 1;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.TBUF32_2[0] = 2;stcTxFrame.TBUF32_2[1] = 3;CAN_SetFrame(&stcTxFrame);CAN_TransmitCmd(CanPTBTxCmd); //PTB发送命令CAN_IrqCmd(CanRxIrqEn, TRUE);}
}
测试结果如下:
【3】使用不同缓冲器发送多帧的方法:
除了上述同一个缓冲器加延时以实现连续发送多帧数据之外,还可以依赖MCU CAN外设提供的另外几组缓冲器实现连续发送多帧数据的目的(更可靠)。
由芯片说明书可以看到,主缓冲器(PTB)只能缓冲一帧数据。而另外的副缓冲器(STB)可以缓冲4帧数据。实现代码如下(收到信号之后,一次发送5帧数据,其中第一帧挂载主缓冲器PTB上,其他四帧挂载副缓冲器STB上):
/**************************************************************************
* 函数名称: COM_Tx
* 功能描述: CAN通信发送测试
* 其他说明:
**************************************************************************/
void COM_Tx(void)
{uint8_t u8Idx = 0;if(TRUE == u8RxFlag){u8RxFlag = FALSE;if(1 == stcRxFrame.Cst.Control_f.RTR){return;}//<<主缓冲器Can Tx第一帧stcTxFrame.StdID = 0;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.TBUF32_2[0] = 0;stcTxFrame.TBUF32_2[1] = 1;CAN_SetFrame(&stcTxFrame);CAN_TransmitCmd(CanPTBTxCmd); //PTB发送命令// delay1ms(1); //若使用单一缓冲器,连续发送失败,需要中间加延时等待上一帧发送结束(实测大于500us)//<<副缓冲器Can Tx第二帧stcTxFrame.StdID = 1;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.enBufferSel = CanSTBSel;stcTxFrame.TBUF32_2[0] = 2;stcTxFrame.TBUF32_2[1] = 3;CAN_SetFrame(&stcTxFrame);//<<副缓冲器Can Tx第三帧stcTxFrame.StdID = 2;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.enBufferSel = CanSTBSel;stcTxFrame.TBUF32_2[0] = 4;stcTxFrame.TBUF32_2[1] = 5;CAN_SetFrame(&stcTxFrame);//<<副缓冲器Can Tx第四帧stcTxFrame.StdID = 3;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.enBufferSel = CanSTBSel;stcTxFrame.TBUF32_2[0] = 6;stcTxFrame.TBUF32_2[1] = 7;CAN_SetFrame(&stcTxFrame);//<<副缓冲器Can Tx第五帧stcTxFrame.StdID = 4;stcTxFrame.Control_f.DLC = 8;stcTxFrame.Control_f.IDE = 0;stcTxFrame.Control_f.RTR = 0;stcTxFrame.enBufferSel = CanSTBSel;stcTxFrame.TBUF32_2[0] = 8;stcTxFrame.TBUF32_2[1] = 9;CAN_SetFrame(&stcTxFrame);CAN_TransmitCmd(CanSTBTxAllCmd); //STB所有帧发送命令CAN_IrqCmd(CanRxIrqEn, TRUE);}
}
测试结果如下:
综上,CAN通信收发测试完成。
相关文章:

【嵌入式】HC32F07X CAN通讯配置和使用配置不同缓冲器以连续发送
一 背景说明 使用小华(华大)的MCU HC32F07X实现 CAN 通讯配置和使用 二 原理分析 【1】CAN原理说明(参考文章《CAN通信详解》): CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种能够实现…...

Linux的常见指令(一)
目录 一、文件 二、常见指令 1、pwd 2、ls 1、ls -a 2、ls -l 3、ls -i 编辑 3、touch 4、mkdir 5、cd 6、rmdir 和 rm 7、man 8、cp 一、文件 目录和文件是在磁盘上建立的,空文件是在磁盘上占用空间的(文件包括文件内容和文件的各种属…...
Jenkins 参数动态获取目录里面的内容
Jenkins 参数动态获取目录里面的内容 假如我们想把一个目录下面的tar.gz文件作为jenkins参数,这个目录会实时更新,每次运行job的时候需要把目录里面的文件作为输入,这时候我们可以使用jenkins自带的Active Choices Parameter参数 在参数中写…...
centos 搭建内网ntp时间服务器
在 CentOS 搭建内网 NTP 时间服务器,你可以按照以下步骤操作: 安装 NTP 服务: 打开终端并以 root 用户身份登录。使用以下命令安装 NTP 服务: sudo yum install ntp配置 NTP 服务器: 打开 NTP 配置文件 /etc/ntp.conf&…...
FreeRTOS-消息队列的使用
1. 定义队列传输的内容和队列结构体对象 使用 xQueueHandle结构体创建对象 typedef struct {u8 TaskNum;u8 Cmd;u8 * buf;}QueueObject_t;xQueueHandle xQueue NULL; 2. 调用xQueueCreate API创建队列 xQueueCreate()函数:用于创建一个消息队列。 QueueHan…...

喜欢 Android 14 的 14 个理由
和去年 8 月中旬发布的 Android 13 正式版不同,今年的 Android 14 正式版延后到了 10 月 4 日——也就是 Pixel 8 系列发布的同一天。原因我们似乎也能从 Google 宣传新特性中略窥一二: 除了明确表示会率先向特定 Pixel 机型推送的 AI 壁纸生成…...

图解系列--路由器和它庞大的功能
03.01 何为路由器 路由器是指主要负责 OSI参考模型中网络层的处理工作,并根据路由表信息在不同的网络 之间转发IP 分组的网络硬件(图3-1)。这里的网络一般是指IP 子网,也可以称为广播域。此外,现在的路由器还会搭载其他各种各样的功能。 0…...

DBeaver 23.2.3发布,带来多项增强和修复
数据库管理工具DBeaver最新版本23.2.3已经发布。这个版本带来了一系列的增强和修复,提升了用户的使用体验和工作效率。 以下是DBeaver 23.2.3版本的一些亮点功能: 数据编辑器方面的改进: Excel (XLSX) 导出现在支持列自动拟合,…...

Proteus仿真--基于51单片机的按键选播电子音乐(仿真文件+程序)
本文主要介绍基于51单片机的按键选播电子音乐(完整仿真源文件及代码见文末链接) 本设计中包括一个按键和一个喇叭,点击按键可以切换选择播放不同的音乐 仿真图如下 其中点击按键K1进行音乐选播选择切换 仿真运行视频 Proteus仿真--基于5…...

node使用http模块
文章目录 前言一、创建http服务二、设置http的响应报文三、不同请求响应不同数据四、请求响应不同html文件1. 添加www文件夹2. js代码3. 效果 五、get和post请求的区别 前言 提示:这里可以添加本文要记录的大概内容: 一、创建http服务 // 1:…...
Golang Study 进阶
Golang 本文章中记录一些 Golang 中的语言特性,包括 init 函数,面向对象,defer 关键字,并发编程等。 init 函数与导包 init函数的执行流程是早于main函数的,如果想在main函数执行前做一些事情,可以在init函…...

Shopee买家通系统详细功能介绍
Shopee买家通系统是一款全自动化操作的软件,可以批量注册买家号、自动加购加心愿单、自动下单等。 批量注册买家号 准备好相应资料后,在运行注册时可以自动输入手机号、自动输入短信、自动输入设置的密码。 自动加购加心愿单 根据设置的关键词及产品编…...

git生成gitee和github两个不同的公钥
配置多个公钥 Windows 用户建议使用 Windows PowerShell 或者 Git Bash,在 命令提示符 下无 cat 和 ls 命令。 1、生成公钥文件: 通过命令 ssh-keygen 生成 SSH Key: ssh-keygen -t rsa -C "Gitee SSH Key" -f ~/.ssh/gitee_be…...

基于SSM的同学录网站
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…...
第十五节——观察者watch
一、概念 在Vue中,watch是一个用于监听数据变化的功能。它可以监听一个或多个数据,并在数据发生变化时执行相应的操作。当我们需要在数据变化时执行异步操作、计算属性或执行一些副作用时,watch就派上了用场啦。注意。watch默认只能进行浅层…...

tauri 访问静态资源,响应头为Content-Type:‘text/html‘
现象 报错: Error: THREE.FBXLoader: Unknown format. at FBXLoader.parse (index-f8291142.js:22050:15) at Object.onLoad (index-f8291142.js:22033:22) at index-f8291142.js:19769:20 使用threejs 加载fbx模型文件时,返回头中Content-…...
【佳学基因检测】Node.js中如何读取并调用内容
【佳学基因检测】Node.js中如何读取并调用内容 先给出功能实现代码: var http require(http); var fs require(fs); http.createServer(function (req, res) {fs.readFile(jiaxuejiyin.html, function(err, data) {res.writeHead(200, {Content-Type: text/html…...
java根据音频流或者音频的地址获取分贝的工具类
工具类 import lombok.extern.slf4j.Slf4j;import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.UnsupportedAudioFileException; import java.io.BufferedInputStre…...
Pycharm出现的一些问题和解决办法
1.每次启动打开多个项目,速度很慢。改为每次启动询问打开哪个单一项目 Setting -> Appearance & Behavior -> System Settings -> Project -> 关闭Reopen projects on startop 2.一直显示《正在关闭项目closing project》,关不上 pycha…...

进程优先级(nice值,top指令),独立性,竞争性,进程切换(时间片),抢占与出让,并发并行概念
目录 优先级 引入 为什么会存在优先级 特点 优先级值 nice值 更改nice值 top指令 独立性 竞争性 进程切换 引入 时间片 上下文切换 调度器 抢占与出让 强占 出让 并发和并行 并发 并行 优先级 引入 与权限不同的是,权限是能不能做的问题,优先级是什…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...