【STM32】HAL庫 之 CAN 開發指南

基于stm32 f407vet6芯片 使用hal庫開發 can
簡單講解一下can的基礎使用

CubeMX配置

在這里插入圖片描述
這里打開CAN1 并且設置好波特率和NVIC相關的配置
波特率使用波特率計算器軟件

在這里插入圖片描述
使用采樣率最高的這段 填入

在這里插入圖片描述
得到波特率1M bit/s

然后編寫代碼
環形緩沖區

#include "driver_buffer.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"RingBuffer USERRxDataBuffer1; //定義用戶緩沖區
RingBuffer USERRxDataBuffer2;/* 初始化環形緩沖區 */
int Driver_Buffer_Init(ptRingBuffer buffer, uint16_t size)
{if (buffer == NULL || size == 0)return -1;            /* 判斷合法性 */if (buffer->fifo == NULL) /* 判斷是否為內存大小空*/{buffer->fifo = (uint8_t *)malloc(size); /* 動態分配內存 */if (buffer->fifo == NULL){//printf("Malloc %d bytes failed.\r\n", size);return -1;}}buffer->pw = buffer->pr = 0;buffer->buf_size = size;return 0;
}/* 環形緩沖區寫一個字節 */
int Driver_Buffer_Write(ptRingBuffer buffer, const uint8_t data)
{if (buffer == NULL || buffer->fifo == NULL)return -1; /* 判斷合法性 */int i = (buffer->pw + 1) % buffer->buf_size;if (i != buffer->pr) /* 判斷是否寫滿 */{buffer->fifo[buffer->pw] = data; /* */buffer->pw = i;                  /* 重置寫指針 */return 0;}return -1;
}/* 環形緩沖區寫多個字節 */
int Driver_Buffer_WriteBytes(ptRingBuffer buffer, const uint8_t *data_stream, uint8_t len)
{int i;if (buffer == NULL || buffer->fifo == NULL)return -1; /* 判斷合法性 */if (data_stream == NULL || len == 0)return -1;for (i = 0; i < len; i++){if (Driver_Buffer_Write(buffer, data_stream[i]) != 0)break;}return i;
}/* 環形緩沖區 讀一個字節 */
int Driver_Buffer_Read(ptRingBuffer buffer, uint8_t *data)
{if (buffer == NULL || buffer->fifo == NULL)return -1; /* 判斷合法性 */if (data == NULL)return -1;if (buffer->pr == buffer->pw)return -1; /* 滿 */*data = buffer->fifo[buffer->pr];buffer->pr = (buffer->pr + 1) % buffer->buf_size; /* 自增 */return 0;
}/* 環形緩沖區 讀多個字節 */
int Driver_Buffer_ReadBytes(ptRingBuffer buffer, uint8_t *data_stream, uint8_t len)
{int i = 0;if (buffer == NULL || buffer->fifo == NULL)return -1; /* 判斷合法性 */if (data_stream == NULL || len == 0)return -1;for (i = 0; i < len; i++){if (Driver_Buffer_Read(buffer, &data_stream[i]) != 0)break;}return i;
}/*  清空環形緩沖區 */
int Driver_Buffer_Clean(ptRingBuffer buffer)
{if (buffer == NULL || buffer->fifo == NULL)return -1;                             /* 判斷合法性 */memset(buffer->fifo, 0, buffer->buf_size); /* 清空 */buffer->pr = buffer->pw = 0;               /* 歸零 */return 0;
}
/*** @brief 更新數據到數組* @param buffer* @param data_stream* @return 返回更新的數據長度*/
int Driver_Buffer_RefreshData(ptRingBuffer buffer, uint8_t *data_stream)
{uint16_t len = 0;if (buffer->pw == buffer->buf_size)buffer->pw = 0;while (buffer->pw != buffer->pr){data_stream[len++] = buffer->fifo[buffer->pr];buffer->fifo[buffer->pr] = 0;buffer->pr++;if (buffer->pr >= buffer->buf_size)buffer->pr = 0;if (len >= buffer->buf_size)break;}return len;
}
#ifndef __DRIVER_BUFFER_H
#define __DRIVER_BUFFER_H#include "stdint.h"
typedef struct{uint8_t *fifo;uint16_t pw; /*寫地址*/uint16_t pr;uint16_t buf_size;}RingBuffer,*ptRingBuffer;extern RingBuffer USERRxDataBuffer1;
extern RingBuffer USERRxDataBuffer2;int Driver_Buffer_Init(ptRingBuffer buffer, uint16_t size);int Driver_Buffer_Write(ptRingBuffer buffer, const uint8_t data);int Driver_Buffer_WriteBytes(ptRingBuffer buffer, const uint8_t *data_stream, uint8_t len);int Driver_Buffer_Read(ptRingBuffer buffer, uint8_t *data);int Driver_Buffer_ReadBytes(ptRingBuffer buffer, uint8_t *data_stream, uint8_t len);int Driver_Buffer_Clean(ptRingBuffer buffer);int Driver_Buffer_RefreshData(ptRingBuffer buffer, uint8_t *data_stream);#endif
#include "driver_can.h"
#include "can.h"
#include "driver_buffer.h"#include <stdio.h> //使用printf函數
#include <stdint.h>HAL_StatusTypeDef CAN_Init(void)
{HAL_StatusTypeDef result = HAL_OK;Driver_Buffer_Init(&USERRxDataBuffer1, 256);                       /* 開辟環形緩沖區空間 */result = CAN_Filter_Config_Scale32_IdMask(&hcan1, 0x100, 0x100); // 過濾器設置return result;
}HAL_StatusTypeDef CAN_Filter_Config_Scale32_IdMask(CAN_HandleTypeDef *hcan, uint32_t id, uint32_t mask)
{HAL_CAN_Stop(hcan); // 停止canHAL_StatusTypeDef result = HAL_OK;CAN_FilterTypeDef sFilterConfig;/* 配置過濾器參數 */sFilterConfig.FilterBank = 0;                      // 過濾器組編號(0-27)sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  // 掩碼模式(或列表模式)sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 32位位寬// ID分解(右移13位取高16位,左移3位處理IDE/RTR位)sFilterConfig.FilterIdHigh = (id >> 13) & 0xFFFF;sFilterConfig.FilterIdLow = (id << 3) & 0xFFF8| CAN_ID_EXT|CAN_RTR_DATA; /*只接受拓展幀 和數據幀*/// 掩碼設置為0xFFFF0000(匹配前16位)sFilterConfig.FilterMaskIdHigh = (mask >> 13) & 0xFFFF;sFilterConfig.FilterMaskIdLow = (mask << 3) & 0xFFF8| CAN_ID_EXT|CAN_RTR_DATA; /*只接受拓展幀 和數據幀*/sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 接收FIFO選擇sFilterConfig.FilterActivation = ENABLE;           // 啟用過濾器sFilterConfig.SlaveStartFilterBank = 14;            // 雙CAN時從過濾器組起始編號  單can無意義/* 應用過濾器配置 */if (HAL_CAN_ConfigFilter(hcan, &sFilterConfig) != HAL_OK){Error_Handler();}result = HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // FIFO0消息掛起中斷result = HAL_CAN_Start(hcan);                                             // 啟動CAN外設return result;
}/* 32位列表模式 */
HAL_StatusTypeDef CAN_Filter_Config_Scale32_IdList(CAN_HandleTypeDef *hcan, uint32_t id1, uint32_t id2)
{HAL_CAN_Stop(hcan); // 停止canHAL_StatusTypeDef result = HAL_OK;CAN_FilterTypeDef sFilterConfig;/* 基礎參數配置 */sFilterConfig.FilterBank = 0;                      // 使用過濾器組0(CAN1默認組0-13)sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST;  // 列表模式,需精確匹配IDsFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 32位位寬,支持標準幀和擴展幀sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 接收報文存入FIFO0sFilterConfig.FilterActivation = ENABLE;           // 啟用過濾器sFilterConfig.SlaveStartFilterBank =14;            // CAN2使用過濾器組14-27/* 設置兩個目標擴展ID(0x18F60000和0x18F60001) */uint32_t target_id1 = id1 | CAN_ID_EXT; // 擴展幀需設置IDE位uint32_t target_id2 = id2 | CAN_ID_EXT;// 擴展ID分解:高16位右移13位,低16位左移3位(IDE/RTR位對齊)sFilterConfig.FilterIdHigh = (target_id1 >> 13) & 0xFFFF;sFilterConfig.FilterIdLow = (target_id1 << 3) & 0xFFF8| CAN_ID_EXT|CAN_RTR_DATA; /*只接受拓展幀 和數據幀*/sFilterConfig.FilterMaskIdHigh = (target_id2 >> 13) & 0xFFFF; // 第二個ID的高16位sFilterConfig.FilterMaskIdLow = (target_id2 << 3) & 0xFFF8| CAN_ID_EXT|CAN_RTR_DATA; /*只接受拓展幀 和數據幀*//* 應用過濾器配置 */if (HAL_CAN_ConfigFilter(hcan, &sFilterConfig) != HAL_OK){Error_Handler();}HAL_CAN_Start(hcan);   HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // FIFO0消息掛起中斷// 啟動CAN外設return result;
}HAL_StatusTypeDef CAN_Filter_Config_Scale16_IdMask(CAN_HandleTypeDef *hcan, uint16_t id, uint16_t mask)
{HAL_CAN_Stop(hcan); // 停止canHAL_StatusTypeDef result = HAL_OK;CAN_FilterTypeDef sFilterConfig;/* 配置過濾器參數 */sFilterConfig.FilterBank = 0;                      // 過濾器組編號(0-27)sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  // 掩碼模式(或列表模式)sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT; // 32位位寬sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 接收報文存入FIFO0sFilterConfig.FilterActivation = ENABLE;           // 啟用過濾器sFilterConfig.SlaveStartFilterBank = 0;            // CAN2使用過濾器組14-27// 標準幀ID左移5位對齊(STID[10:0]占高11位)sFilterConfig.FilterIdHigh = (id << 5);       // ID高16位寄存器(實際存儲前11位)sFilterConfig.FilterIdLow = 0x0000;           // ID低16位寄存器(未使用)sFilterConfig.FilterMaskIdHigh = (mask << 5); // 掩碼高16位寄存器sFilterConfig.FilterMaskIdLow = 0x0000;       // 掩碼低16位寄存器(未使用)/* 應用過濾器配置 */if (HAL_CAN_ConfigFilter(hcan, &sFilterConfig) != HAL_OK){Error_Handler();}// 啟動CAN外設HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // FIFO0消息掛起中斷HAL_CAN_Start(hcan);      return result;
}/* 16位列表模式 */
HAL_StatusTypeDef CAN_Filter_Config_Scale16_IdList(CAN_HandleTypeDef *hcan, uint16_t id1, uint16_t id2, uint16_t id3, uint16_t id4)
{HAL_CAN_Stop(hcan); // 停止canHAL_StatusTypeDef result = HAL_OK;CAN_FilterTypeDef sFilterConfig;/* 基礎參數配置 */sFilterConfig.FilterBank = 0;                     // 使用過濾器組0(CAN1默認組0-13)sFilterConfig.FilterMode = CAN_FILTERMODE_IDLIST; // 列表模式,需精確匹配IDsFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 接收報文存入FIFO0sFilterConfig.FilterActivation = ENABLE;           // 啟用過濾器sFilterConfig.SlaveStartFilterBank = 0;            // CAN2使用過濾器組14-27sFilterConfig.FilterIdHigh = id1 << 5;             // 標準ID 0x100sFilterConfig.FilterIdLow = id2 << 5;              // 標準ID 0x101sFilterConfig.FilterMaskIdHigh = id3 << 5;         // 標準ID 0x102sFilterConfig.FilterMaskIdLow = id4 << 5;          // 標準ID 0x103/* 應用過濾器配置 */if (HAL_CAN_ConfigFilter(hcan, &sFilterConfig) != HAL_OK){Error_Handler();}HAL_CAN_Start(hcan);                                             // 啟動CAN外設HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING); // FIFO0消息掛起中斷return result;
}/** @brief  發送一幀CAN數據* @param  hcan: CAN句柄指針* @param  id: 報文標識符(標準ID或擴展ID)* @param  data: 數據緩沖區指針(最大8字節)* @param  len: 數據長度(0-8)* @param  isExtId: 是否為擴展ID(1=擴展幀,0=標準幀)* @retval HAL狀態:HAL_OK=成功,其他=失敗*/
HAL_StatusTypeDef CAN_Send_Frame(CAN_HandleTypeDef *hcan, uint32_t id, uint8_t *data, uint8_t len, uint8_t isExtId)
{CAN_TxHeaderTypeDef txHeader;uint32_t mailbox;HAL_StatusTypeDef result = HAL_OK;/* 校驗參數合法性 */if (len > 8 || data == NULL)return HAL_ERROR;/* 配置報文頭部 */if (isExtId){txHeader.ExtId = id;       // 擴展IDtxHeader.IDE = CAN_ID_EXT; // 擴展幀標識}else{txHeader.StdId = id;       // 標準IDtxHeader.IDE = CAN_ID_STD; // 標準幀標識}txHeader.RTR = CAN_RTR_DATA;           // 數據幀(非遠程請求)txHeader.DLC = len;                    // 數據長度碼txHeader.TransmitGlobalTime = DISABLE; // 不記錄全局時間戳/* 提交發送請求 */result = HAL_CAN_AddTxMessage(hcan, &txHeader, data, &mailbox);while (HAL_CAN_GetTxMailboxesFreeLevel(hcan) != 3) // 3 個郵箱都為空;                                                  /*等待發送完成 防止丟包*/return result;
}/* CAN發送多幀數據 */
void CAN_Send_Data(CAN_HandleTypeDef *hcan, uint32_t id, uint8_t *buf, uint32_t len, uint8_t isExtId)
{uint32_t transmission_times = 0; /* 發送次數 */uint32_t remian_bytes = 0;       /* 剩余字節 */uint32_t frame_length = 0;       /* 幀長度 */frame_length = 8;                /* 標準can最大8 */transmission_times = len / frame_length;remian_bytes = len % frame_length;int i = 0;while (i < transmission_times){CAN_Send_Frame(hcan, id, buf + i * frame_length, frame_length, isExtId);i++;}if (remian_bytes > 0) // 尾幀{CAN_Send_Frame(hcan, id, buf + transmission_times * frame_length, remian_bytes, isExtId);}
}/* CAN 接收數據 */
uint32_t CAN_Receive_Message(CAN_HandleTypeDef *hcan, uint32_t RxFifo, uint8_t *buf)
{CAN_RxHeaderTypeDef RxHeader;if (HAL_CAN_GetRxFifoFillLevel(hcan, RxFifo) == 0) // 檢查郵箱{return 0; // 沒有數據}HAL_CAN_GetRxMessage(hcan, RxFifo, &RxHeader, buf);return RxHeader.DLC; // 返回接收長度
}/*** @brief 接收FIFO0的回調函數 (中斷方式)* @param hcan*/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{uint8_t can_rec_data[8];uint32_t len = 0;len = CAN_Receive_Message(hcan, CAN_RX_FIFO0, can_rec_data);Driver_Buffer_WriteBytes(&USERRxDataBuffer1, can_rec_data, len); /*將收到的數據寫到緩沖區*/char buffer[10] = "";char *ptr = buffer;for (size_t i = 0; i < 8; i++){ptr += sprintf(ptr, "%02X ", can_rec_data[i]); // 將元素轉為十六進制字符串}//usb_printf("%s\n", buffer); // 一次性輸出整個字符串
}//void MX_CAN_Init(void)
//{
//  CAN_FilterTypeDef    sFilterConfig;
//  
//  /*CANμ¥?3???ˉ*/
//  
//  hCAN.Instance = CANx;                     /* CAN?? */
//  hCAN.Init.Prescaler = 3;                  /* BTR-BRP 2¨??·?μ?  ?¨?áˊ±???μ?±????42/(1+10+3)/3=1Mbps */
//  hCAN.Init.Mode = CAN_MODE_NORMAL;         /* ?3£1¤??? */
//  hCAN.Init.SyncJumpWidth = CAN_SJW_1TQ;    /* BTR-SJW ???2????񲀠2?????? */
//  hCAN.Init.TimeSeg1 = CAN_BS1_10TQ;         /* BTR-TS1 ???1 ??á??????? */
//  hCAN.Init.TimeSeg2 = CAN_BS2_3TQ;         /* BTR-TS1 ???2 ??á??????? */
//  hCAN.Init.TimeTriggeredMode = DISABLE;    /* MCR-TTCM  1??±??·¢?????? */
//  hCAN.Init.AutoBusOff = ENABLE;            /* MCR-ABOM  ??ˉà?1?𚠯
//  hCAN.Init.AutoWakeUp = ENABLE;            /* MCR-AWUM  ????ˉ??Б?? */
//  hCAN.Init.AutoRetransmission = DISABLE;   /* MCR-NART  ???±¨???ˉ?′?	  DISABLE-??ˉ?′? */
//  hCAN.Init.ReceiveFifoLocked = DISABLE;    /* MCR-RFLM  ???IFO ??¨??  DISABLE-?3???±¨????ǔ-?±¨? */
//  hCAN.Init.TransmitFifoPriority = DISABLE; /* MCR-TXFP  ·¢?FIFO?ψ?? DISABLE-?ψ??????±¨?±?·? */
//  HAL_CAN_Init(&hCAN);
//  
//  /*CAN1y??3???ˉ*/                  
//  sFilterConfig.FilterBank = 0;                      /* 1y???0 */
//  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  /* 1¤??±?·??±???? */
//  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; /* 1y??λ??μ¥??32λ?£*/
//  sFilterConfig.FilterIdHigh = (((uint32_t)0x1314<<3)&0xFFFF0000)>>16;;               /* ?1y?μ?D??? */
//  sFilterConfig.FilterIdLow = (((uint32_t)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;; /* ?1y?μ?Dμ?? */
//  sFilterConfig.FilterMaskIdHigh = 0xFFFF;           /* 1y????6λ?λ±??? */
//  sFilterConfig.FilterMaskIdLow = 0xFFFF;            /* 1y??μ?6λ?λ±??? */
//  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;  /* 1y??±?1?aμ?FIFO 0 */
//  sFilterConfig.FilterActivation = ENABLE;            /* ??1y?? */ 
//  sFilterConfig.SlaveStartFilterBank = 0;             /* ?à′??′?y??μ??憷±? */   
//  
//  HAL_CAN_ConfigFilter(&hCAN, &sFilterConfig);
//  
//  
//}
#ifndef __DRIVER_CAN_H__
#define __DRIVER_CAN_H__#include "main.h"HAL_StatusTypeDef CAN_Init(void);HAL_StatusTypeDef CAN_Filter_Config_Scale32_IdMask(CAN_HandleTypeDef *hcan, uint32_t id, uint32_t mask);HAL_StatusTypeDef CAN_Filter_Config_Scale32_IdList(CAN_HandleTypeDef *hcan, uint32_t id1, uint32_t id2);HAL_StatusTypeDef CAN_Filter_Config_Scale16_IdMask(CAN_HandleTypeDef *hcan, uint16_t id, uint16_t mask);HAL_StatusTypeDef CAN_Filter_Config_Scale16_IdList(CAN_HandleTypeDef *hcan, uint16_t id1, uint16_t id2, uint16_t id3, uint16_t id4);HAL_StatusTypeDef CAN_Send_Frame(CAN_HandleTypeDef *hcan, uint32_t id, uint8_t *data, uint8_t len, uint8_t isExtId);void CAN_Send_Data(CAN_HandleTypeDef *hcan, uint32_t id, uint8_t *buf, uint32_t len, uint8_t isExtId);uint32_t CAN_Receive_Message(CAN_HandleTypeDef *hcan, uint32_t RxFifo, uint8_t *buf);#endif

提供了32位掩碼和列表 16位掩碼和列表的過濾器

編寫應用層代碼

void  APP_User_Task(void)
{for(int i =0 ;i<8;i++){buf[i] = i;}/*發送丟包測試*/	for(int i =0 ;i<1024;i++){tx_Pathping[i] = i%256;}CAN_Send_Data(&hcan1,0x100,tx_Pathping,1024,1);for(;;){/*接收丟包測試*/if(Driver_Buffer_RefreshData(&USERRxDataBuffer1,tx_buf)){tx_buf[7] = 0xa5;CAN_Send_Data(&hcan1,0x5A,tx_buf,8,1);}}
}	

實驗效果

在這里插入圖片描述
一開機就輸出了128幀數據 可以看到數據都是連續的沒有丟包

然后發送1024幀數據 可以看到也沒有丟包

在這里插入圖片描述
發送的數據接收到環形緩沖區 然后讀出數據打印

此工程代碼已經在STM32F407VET6 和STM32F103CBT6芯片上都驗證過了 沒有太大問題

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/84810.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/84810.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/84810.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《Scientific Reports撤稿門技術節分析》——從圖像篡改檢測到學術倫理重建的技術透視

2023年以來&#xff0c;《Scientific Reports》等開放獲取期刊頻繁曝出大規模撤稿事件&#xff0c;涉及數據造假、圖像重復、AI生成內容篡改等技術性學術不端行為。本文以技術視角切入&#xff0c;系統分析撤稿事件背后的技術動因、檢測手段漏洞、學術出版體系的技術短板及應對…

Client請求Grpc服務報錯

現象&#xff1a;err: rpc error: code Unimplemented desc 背景&#xff1a;調用鏈路A->B->C&#xff0c;A是一個Http協議的接口&#xff0c;B也是一個Http協議的接口&#xff0c; 但C是一個Grpc協議的接口。 解決思路&#xff1a;查看C服務對應的proto&#xff0c;比…

機器學習課程設計報告 —— 基于口紅數據集的情感分析

目錄 一、課程設計目的 二、數據預處理及分析 2.1 數據預處理 2.2 數據分析 三、特征選擇 3.1 特征選擇的重要性 3.2 如何進行特征選擇 3.3 特征選擇的依據 3.4 數據集的劃分 四、模型訓練與模型評估 4.1 所有算法模型不調參 4.2 K-近鄰分類模型 4.3 GaussianNB模…

Flutter 實現6個驗收碼輸入框

開箱即用&#xff0c;初始化時就喚起鍵盤&#xff0c;并選中第一個 import package:flutter/material.dart;import dart:async; // 引入 Timer 類class VerificationCode extends StatefulWidget {final String phoneNumber;const VerificationCode({super.key, required this.…

如何查看服務器有幾張GPU

要查看服務器上有多少張 GPU&#xff0c;你可以使用以下幾種方法&#xff1a; 1.1 使用 nvidia-smi工具&#xff08;針對 NVIDIA GPU&#xff09;&#xff1a; 如果你的服務器上安裝了 NVIDIA GPU 驅動程序&#xff0c;那么可以使用 nvidia-smi 命令查看詳細的 GPU 信息。 n…

3099. 哈沙德數

?題目來源&#xff1a; LeetCode題目&#xff1a;3099. 哈沙德數 - 力扣&#xff08;LeetCode&#xff09; 解題思路&#xff1a; 按要求求和判斷即可。 解題代碼&#xff1a; #python3 class Solution:def sumOfTheDigitsOfHarshadNumber(self, x: int) -> int:sumDigi…

數字化回歸本質:第一性原理驅動的制造業轉型與AI+云PLM系統實踐

2014年&#xff0c;埃隆馬斯克在南加州大學商學院的畢業演講上&#xff0c;留下了一場5分鐘的精彩分享&#xff0c;他將自己對工作和人生的思考總結為五個要點&#xff0c;其中一點說到了他的決策方式&#xff1a; “也許你聽我說過&#xff0c;要從物理學的角度思考問題&…

仿DeepSeek AI問答系統完整版(帶RAG本地知識庫+聯網搜索+深度思考) +springboot+vue3

今天教大家如何設計一個企業級的 deepseek問答 一樣的系統 , 基于目前主流的技術&#xff1a;前端vue3&#xff0c;后端springboot。同時還帶來的項目的部署教程。 系統的核心功能 1. 支持本地上傳文檔知識庫&#xff0c;RAG技術。 支持的文檔有txt&#xff0c;doc&#xff0c…

27、請求處理-【源碼分析】-怎么改變默認的_method

27、請求處理-【源碼分析】-怎么改變默認的_method 要改變 Spring Boot 中默認的 _method 參數&#xff0c;可以通過以下步驟實現&#xff1a; #### 原理分析 Spring Boot 中默認的 HiddenHttpMethodFilter 用于將表單中的 _method 參數值映射為實際的 HTTP 方法&#xff08;如…

歐拉角轉為旋轉矩陣

外旋是固定坐標系&#xff0c;內旋是動態坐標系。外旋和內旋具有等價性。 固定坐標系依次繞xyz軸旋轉&#xff0c;旋轉矩陣 動態坐標系依次繞zyx軸旋轉&#xff0c;旋轉矩陣 numpy和scipy計算對比 import numpy as np from numpy import sin, cos, pi # 抑制科學計數法&#…

【AI學習筆記】Coze平臺實現生成小紅書熱門多圖筆記

背景前搖&原視頻教程&#xff1a; 最近總是在小紅書上刷到多圖組成的養生小妙招、效率提升小tips、退休奶奶療愈語錄等等這樣的圖文筆記&#xff0c;而且人物圖像一眼就是AI畫的。 當時我以為這個排版和文字是人工的&#xff0c;就讓AI保持角色一致性畫了下圖&#xff0c;…

如何選擇自動化編程平臺

從事自動化行業的工作者都知道&#xff0c;做PLC編程需要PLC編程軟件&#xff0c;做HMI可視化需要HMI編程軟件&#xff0c;做SCADA需要SCADA編程軟件&#xff0c;做DCS需要DCS軟件&#xff0c;做仿真調試需要仿真軟件。這些軟件有國外的、國內的&#xff0c;有傳統自動化廠商開…

Bug 背后的隱藏劇情

Bug 背后的隱藏劇情 flyfish 1. 「bug」&#xff1a;70多年前那只被拍進史書的飛蛾 故事原型&#xff1a;1947年哈佛實驗室的「昆蟲命案」 1947年的計算機長啥樣&#xff1f;像一間教室那么大&#xff0c;塞滿了幾萬根繼電器&#xff08;類似老式開關&#xff09;&#xff…

如何將通話記錄從Android傳輸到Android

“如何將通話記錄從 Android 轉移到 Android&#xff1f;我換了一部新的 Android 手機&#xff0c;想要將通話記錄復制到其中。”您需要將通話記錄從 Android 傳輸到 Android 是一種常見的情況&#xff0c;因為通話記錄是手機上最重要的數據之一。幸運的是&#xff0c;如果您從…

Android 云手機橫屏模式下真機鍵盤遮擋輸入框問題處理

一、背景 打開橫屏應用,點擊云機EditText輸入框,輸入框被鍵盤遮擋,如下圖&#xff1a; 未打開鍵盤狀態: 點擊第二個輸入框,鍵盤遮擋了輸入框&#xff1a; 二、解決方案&#xff08;推薦第三中方案,博主采用的也是第三種方案&#xff09; 博主這里整理了三種方案&#xff1a;…

進程IO之 進程

一、進程相關概念 1.什么是進程 程序&#xff1a;靜態的&#xff0c;編譯好的可執行文件&#xff0c;存放在磁盤中的指令和數據的集合 進程&#xff1a;動態的&#xff0c;是程序的一次執行過程&#xff0c;是獨立的可調度的任務 2.進程的特點 &#xff08;1&#xff09;對…

Condition源碼解讀(二)

本章我們繼續將Condition的最后一個方法signal方法&#xff0c;如果前面沒有看過的可以點擊LockSupport與Condition解析來看看Condition解讀的前半部分。 signal方法&#xff1a; public final void signal() {if (!AbstractQueuedLongSynchronizer.this.isHeldExclusively())…

股票收益率的計算

首先&#xff0c;需要從 Tushare.pro 注冊一個賬號并調用其API獲取股票日線數據&#xff08;具體操作請查看官網&#xff09;。 以通過調用tushare獲取股票000001(平安銀行)的股票數據為例&#xff0c;這里不設置日期&#xff0c;那么默認獲取Tushare提供的所有歷史數據。也可…

《算法筆記》13.2小節——專題擴展->樹狀數組(BIT) 問題 D: 數列-訓練套題T10T3

數列(sequence.pas/c/cpp) - 問題描述 一個簡單的數列問題&#xff1a;給定一個長度為n的數列&#xff0c;求這樣的三個元素ai, aj, ak的個數&#xff0c;滿足ai < aj > ak&#xff0c;且i < j < k。 - 輸入數據 第一行是一個整數n(n < 50000)。 第二行n個整…

C# Windows Forms應用程序-001

目錄 項目概述 主要組件及功能 類定義 控件聲明 構造函數 Dispose 方法 InitializeComponents 方法 控件配置詳解 Button 控件 (button1) TextBox 控件 (textBox1) GroupBox 控件 (groupBox1) Label 控件 (label1 至 label5) OpenFileDialog 控件 (openFileDialog1…