stm32week10

news2025/4/13 13:03:42

stm32学习

七.CAN

7.STM32 CAN外设

标识符过滤器:
每个过滤器的核心由两个32位寄存器组成:R1[31:0]和R2[31:0]

图片消失了

FSCx:位宽设置,置0为16位,置1为32位
FBMx:模式设置,置0为屏蔽模式,置1为列表模式
FFAx:关联模式,置0为FIFO0,置1为FIFO1
FACTx;激活设置,置0,禁用,置1,启用
匹配模式:
若是列表模式,则按设置的ID匹配一个ID
若是屏蔽模式,若屏蔽(mask)为1,则表示该位需严格匹配,为0则不严格匹配
过滤器配置示例:

图片消失了

左移5位或者21位是为了避开后面的RTR、IDE位之类的

CAN的三种测试模式:

图片消失了

CAN的三种工作模式:

图片消失了

位时间特性:

图片消失了

波特率=APB1时钟/分频系数/1位Tq的数量=36MHz/(BRP[9:0]+1)/(1+(TS1[3:0]+1))+(TS2[2:0]+1)

中断:
CAN外设占用4个专用的中断向量
发送中断:发送邮箱空时产生
FIFO0中断:收到一个报文/FIFO0满/FIFO0溢出时产生
FIFO1中断:收到一个报文/FIFO1满/FIFO1溢出时产生
状态改变错误中断:出错/唤醒/进入睡眠时产生
事件标志和中断产生:

图片消失了

时间触发通信:

图片消失了

错误处理和离线恢复:
TEC和REC根据错误的情况增加或者减少
ABOM:置1,开启离线自动恢复,进入离线状态后,就自动开启恢复过程;置0,关闭离线自动恢复,软件必须先请求进入然后再退出初始化模式,随后恢复过程才被开启

图片消失了

8.单个设备的环回测试

初始化代码:

void MyCAN_Init(void)
{
    // 使能GPIOA和CAN1外设时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  // GPIOA属于APB2总线
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);  // CAN1属于APB1总线
    
    // 配置CAN_TX引脚(PA12)为复用推挽输出模式
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;       // 复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;          // PA12对应CAN_TX
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   // 输出速度50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置CAN_RX引脚(PA11)为上拉输入模式
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;          // PA11对应CAN_RX
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   // 输入模式速度配置无效
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // CAN总线基本配置
    CAN_InitTypeDef CAN_InitStructure;
    CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;     // 环回模式(测试模式)
    CAN_InitStructure.CAN_Prescaler = 48;               // 预分频器:36MHz/48=750KHz
    // 时间段配置(同步段+传播段+相位缓冲段):
    // 同步段tq=1,BS1=2tq,BS2=3tq → 总周期=1+2+3=6tq → 波特率=750KHz/6=125Kbps
    CAN_InitStructure.CAN_BS1 = CAN_BS1_2tq;            // 同步后采样点位置
    CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;            // 信号重新同步时间
    CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;            // 重新同步跳跃宽度
    // 其他模式配置(默认关闭高级功能)
    CAN_InitStructure.CAN_NART = DISABLE;               // 禁止自动重传
    CAN_InitStructure.CAN_TXFP = DISABLE;               // 发送优先级由标识符决定
    CAN_Init(CAN1, &CAN_InitStructure);                 // 应用配置到CAN1
    
    // 过滤器配置(允许所有消息通过)
    CAN_FilterInitTypeDef CAN_FilterInitStructure;
    CAN_FilterInitStructure.CAN_FilterNumber = 0;       // 使用过滤器0
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;  // 过滤器ID高位
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;   // 过滤器ID低位
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; // 过滤器掩码高位
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;// 过滤器掩码低位
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; // 32位过滤
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // 掩码模式
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; // 分配到FIFO0
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; // 启用过滤器
    CAN_FilterInit(&CAN_FilterInitStructure);           // 应用过滤器配置
}

发送接收函数:

// CAN数据发送函数
// 参数:ID - 标准帧ID(0-0x7FF),Length - 数据长度(0-8),Data - 数据指针
void MyCAN_Transmit(uint32_t ID, uint8_t Length, uint8_t *Data)
{
    CanTxMsg TxMessage;                               // 定义发送消息结构体
    TxMessage.StdId = ID;                             // 设置标准帧ID
    TxMessage.ExtId = ID;                             // 扩展帧ID(未使用)
    TxMessage.IDE = CAN_Id_Standard;                  // 使用标准帧格式
    TxMessage.RTR = CAN_RTR_Data;                     // 数据帧(非远程请求)
    TxMessage.DLC = Length;                           // 设置数据长度
    for (uint8_t i = 0; i < Length; i ++)             // 拷贝数据到发送缓冲区
    {
        TxMessage.Data[i] = Data[i];
    }
    
    uint8_t TransmitMailbox = CAN_Transmit(CAN1, &TxMessage); // 发送请求
    
    // 等待发送完成(带超时保护)
    uint32_t Timeout = 0;
    while (CAN_TransmitStatus(CAN1, TransmitMailbox) != CAN_TxStatus_Ok)
    {
        Timeout++;                                    
        if (Timeout > 100000)                         // 超时退出(防止死锁)
        {
            break;
        }
    }
}

// 检查接收缓冲区状态
// 返回值:1-有新数据,0-无数据
uint8_t MyCAN_ReceiveFlag(void)
{
    // 检查FIFO0中待处理消息数量(>0表示有新数据)
    if (CAN_MessagePending(CAN1, CAN_FIFO0) > 0)
    {
        return 1;
    }
    return 0;
}

// CAN数据接收函数
// 参数:ID - 接收到的帧ID,Length - 数据长度,Data - 接收数据缓冲区
void MyCAN_Receive(uint32_t *ID, uint8_t *Length, uint8_t *Data)
{
    CanRxMsg RxMessage;                               // 定义接收消息结构体
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);         // 从FIFO0读取数据
    
    // 根据帧类型获取ID(支持标准帧和扩展帧)
    if (RxMessage.IDE == CAN_Id_Standard)
    {
        *ID = RxMessage.StdId;
    }
    else
    {
        *ID = RxMessage.ExtId;
    }
    
    // 处理数据帧(忽略远程帧)
    if (RxMessage.RTR == CAN_RTR_Data)
    {
        *Length = RxMessage.DLC;                      // 获取数据长度
        for (uint8_t i = 0; i < *Length; i ++)
        {
            Data[i] = RxMessage.Data[i];              // 拷贝接收数据
        }
    }
    else
    {
        // 此处可添加远程帧处理逻辑
    }
}

9.数据帧-遥控帧

// 自定义 CAN 发送函数,用于将 CAN 消息发送出去
void MyCAN_Transmit(CanTxMsg *TxMessage)
{
    // 调用 CAN_Transmit 函数尝试将消息发送到 CAN1 总线,并获取使用的发送邮箱编号
    uint8_t TransmitMailbox = CAN_Transmit(CAN1, TxMessage);

    // 初始化超时计数器
    uint32_t Timeout = 0;
    // 循环检查消息是否发送成功
    while (CAN_TransmitStatus(CAN1, TransmitMailbox) != CAN_TxStatus_Ok)
    {
        // 超时计数器递增
        Timeout ++;
        // 如果超时计数器超过 100000,退出循环
        if (Timeout > 100000)
        {
            break;
        }
    }
}

// 自定义 CAN 接收函数,用于从 CAN1 总线接收消息
void MyCAN_Receive(CanRxMsg *RxMessage)
{
    // 调用 CAN_Receive 函数从 CAN1 的 FIFO0 接收消息
    CAN_Receive(CAN1, CAN_FIFO0, RxMessage);
}

主函数中的测试程序:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
#include "MyCAN.h"

uint8_t KeyNum;

// 定义一个 CAN 发送消息数组,包含多条不同的 CAN 消息
CanTxMsg TxMsgArray[] = {
/*   StdId     ExtId         IDE             RTR        DLC         Data[8]          */
    {0x555, 0x00000000, CAN_Id_Standard, CAN_RTR_Data,   4, {0x11, 0x22, 0x33, 0x44}},
    {0x000, 0x12345678, CAN_Id_Extended, CAN_RTR_Data,   4, {0xAA, 0xBB, 0xCC, 0xDD}},
    {0x666, 0x00000000, CAN_Id_Standard, CAN_RTR_Remote, 0, {0x00, 0x00, 0x00, 0x00}},
    {0x000, 0x0789ABCD, CAN_Id_Extended, CAN_RTR_Remote, 0, {0x00, 0x00, 0x00, 0x00}},
};

// 定义发送消息数组的索引变量
uint8_t pTxMsgArray = 0;

// 定义 CAN 接收消息结构体变量
CanRxMsg RxMsg;

int main(void)
{
    OLED_Init();
    Key_Init();
    MyCAN_Init();

    OLED_ShowString(1, 1, " Rx :");
    OLED_ShowString(2, 1, "RxID:");
    OLED_ShowString(3, 1, "Leng:");
    OLED_ShowString(4, 1, "Data:");

    while (1)
    {
        KeyNum = Key_GetNum();

        if (KeyNum == 1)
        {
            // 调用自定义 CAN 发送函数,发送当前索引对应的 CAN 消息
            MyCAN_Transmit(&TxMsgArray[pTxMsgArray]);

            // 发送消息数组索引递增
            pTxMsgArray ++;
            // 如果索引超过数组长度,将索引重置为 0
            if (pTxMsgArray >= sizeof(TxMsgArray) / sizeof(CanTxMsg))
            {
                pTxMsgArray = 0;
            }
        }

        // 如果有 CAN 接收标志
        if (MyCAN_ReceiveFlag())
        {
            // 调用自定义 CAN 接收函数,接收 CAN 消息
            MyCAN_Receive(&RxMsg);

            // 如果接收到的消息是标准帧
            if (RxMsg.IDE == CAN_Id_Standard)
            {
                // 在 OLED 第一行显示 "Std"
                OLED_ShowString(1, 6, "Std");

                // 在 OLED 第二行显示标准 ID 的十六进制值
                OLED_ShowHexNum(2, 6, RxMsg.StdId, 8);
            }
            // 如果接收到的消息是扩展帧
            else if (RxMsg.IDE == CAN_Id_Extended)
            {
                // 在 OLED 第一行显示 "Ext"
                OLED_ShowString(1, 6, "Ext");

                // 在 OLED 第二行显示扩展 ID 的十六进制值
                OLED_ShowHexNum(2, 6, RxMsg.ExtId, 8);
            }

            // 如果接收到的消息是数据帧
            if (RxMsg.RTR == CAN_RTR_Data)
            {
                // 在 OLED 第一行显示 "Data  "
                OLED_ShowString(1, 10, "Data  ");

                // 在 OLED 第三行显示数据长度的十六进制值
                OLED_ShowHexNum(3, 6, RxMsg.DLC, 1);

                // 在 OLED 第四行显示数据的十六进制值
                OLED_ShowHexNum(4, 6, RxMsg.Data[0], 2);
                OLED_ShowHexNum(4, 9, RxMsg.Data[1], 2);
                OLED_ShowHexNum(4, 12, RxMsg.Data[2], 2);
                OLED_ShowHexNum(4, 15, RxMsg.Data[3], 2);
            }
            // 如果接收到的消息是远程帧
            else if (RxMsg.RTR == CAN_RTR_Remote)
            {
                // 在 OLED 第一行显示 "Remote"
                OLED_ShowString(1, 10, "Remote");

                // 在 OLED 第三行显示数据长度的十六进制值
                OLED_ShowHexNum(3, 6, RxMsg.DLC, 1);

                // 在 OLED 第四行显示 0x00 的十六进制值
                OLED_ShowHexNum(4, 6, 0x00, 2);
                OLED_ShowHexNum(4, 9, 0x00, 2);
                OLED_ShowHexNum(4, 12, 0x00, 2);
                OLED_ShowHexNum(4, 15, 0x00, 2);
            }
        }
    }
}

10.定时发送

// 此函数用于初始化定时器2,设置其工作模式、定时周期、中断等参数
void Timer_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    // 配置定时器2使用内部时钟源。定时器可以使用内部或外部时钟源,这里选择内部时钟
    TIM_InternalClockConfig(TIM2);

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period = 1000 - 1;
    TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);

    // 清除定时器2的更新标志位。在初始化时清除标志位,避免误触发中断
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);
    // 使能定时器2的更新中断。当定时器产生更新事件时,会触发中断服务函数
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    // 配置NVIC(嵌套向量中断控制器)的优先级分组为2。这决定了中断的抢占优先级和子优先级的分配方式
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    NVIC_InitTypeDef NVIC_InitStructure;
    // 设置NVIC的中断通道为定时器2中断
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    // 使能定时器2的中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    // 设置定时器2中断的抢占优先级为2。抢占优先级高的中断可以打断正在执行的低优先级中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    // 设置定时器2中断的子优先级为1。在抢占优先级相同的情况下,子优先级高的中断先执行
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStructure);

    TIM_Cmd(TIM2, ENABLE);
}
#include "stm32f10x.h"                  // 包含STM32F10x系列微控制器的头文件,用于访问硬件寄存器和外设
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
#include "MyCAN.h"
#include "Timer.h"

uint8_t KeyNum;

uint8_t TimingFlag;
uint8_t TriggerFlag;
uint8_t RequestFlag;

// 定义定时发送的CAN消息结构体
CanTxMsg TxMsg_Timing = {
    .StdId = 0x100,          // 标准标识符
    .ExtId = 0x00000000,     // 扩展标识符
    .IDE = CAN_Id_Standard,  // 使用标准标识符
    .RTR = CAN_RTR_Data,     // 消息类型为数据帧
    .DLC = 4,                // 数据长度为4字节
    .Data = {0x11, 0x22, 0x33, 0x44}
};

// 定义触发发送的CAN消息结构体
CanTxMsg TxMsg_Trigger = {
    .StdId = 0x200,          // 标准标识符
    .ExtId = 0x00000000,     // 扩展标识符
    .IDE = CAN_Id_Standard,  // 使用标准标识符
    .RTR = CAN_RTR_Data,     // 消息类型为数据帧
    .DLC = 4,                // 数据长度为4字节
    .Data = {0x11, 0x22, 0x33, 0x44}
};

// 定义请求发送的CAN消息结构体
CanTxMsg TxMsg_Request = {
    .StdId = 0x300,          // 标准标识符
    .ExtId = 0x00000000,     // 扩展标识符
    .IDE = CAN_Id_Standard,  // 使用标准标识符
    .RTR = CAN_RTR_Data,     // 消息类型为数据帧
    .DLC = 4,                // 数据长度为4字节
    .Data = {0x11, 0x22, 0x33, 0x44}
};

// 定义接收CAN消息的结构体
CanRxMsg RxMsg;

int main(void)
{
    OLED_Init();
    Key_Init();
    MyCAN_Init();
    Timer_Init();
    
    // 在OLED显示屏上显示标题
    OLED_ShowString(1, 1, "Tx");
    OLED_ShowString(2, 1, "Tim:");
    OLED_ShowString(3, 1, "Tri:");
    OLED_ShowString(4, 1, "Req:");
    
    // 主循环
    while (1)
    {
        /*定时发送*/
        if (TimingFlag == 1)
        {
            // 清除定时标志位
            TimingFlag = 0;
            
            TxMsg_Timing.Data[0] ++;
            TxMsg_Timing.Data[1] ++;
            TxMsg_Timing.Data[2] ++;
            TxMsg_Timing.Data[3] ++;
            
            MyCAN_Transmit(&TxMsg_Timing);
            
            OLED_ShowHexNum(2, 5, TxMsg_Timing.Data[0], 2);
            OLED_ShowHexNum(2, 8, TxMsg_Timing.Data[1], 2);
            OLED_ShowHexNum(2, 11, TxMsg_Timing.Data[2], 2);
            OLED_ShowHexNum(2, 14, TxMsg_Timing.Data[3], 2);
        }
        
        /*触发发送*/
        KeyNum = Key_GetNum();
        if (KeyNum == 1)
        {
            // 设置触发标志位
            TriggerFlag = 1;
        }
        
        if (TriggerFlag == 1)
        {
            // 清除触发标志位
            TriggerFlag = 0;
            
            TxMsg_Trigger.Data[0] ++;
            TxMsg_Trigger.Data[1] ++;
            TxMsg_Trigger.Data[2] ++;
            TxMsg_Trigger.Data[3] ++;
            
            MyCAN_Transmit(&TxMsg_Trigger);
            
            OLED_ShowHexNum(3, 5, TxMsg_Trigger.Data[0], 2);
            OLED_ShowHexNum(3, 8, TxMsg_Trigger.Data[1], 2);
            OLED_ShowHexNum(3, 11, TxMsg_Trigger.Data[2], 2);
            OLED_ShowHexNum(3, 14, TxMsg_Trigger.Data[3], 2);
        }
        
        /*请求发送*/
        if (MyCAN_ReceiveFlag())
        {
            // 接收CAN消息
            MyCAN_Receive(&RxMsg);
            
            // 判断是否为标准帧、远程帧且标识符为0x300
            if (RxMsg.IDE == CAN_Id_Standard &&
                RxMsg.RTR == CAN_RTR_Remote &&
                RxMsg.StdId == 0x300)
            {
                // 设置请求标志位
                RequestFlag = 1;
            }
            
            // 判断是否为标准帧、数据帧且标识符为0x3FF
            if (RxMsg.IDE == CAN_Id_Standard &&
                RxMsg.RTR == CAN_RTR_Data &&
                RxMsg.StdId == 0x3FF)
            {
                // 设置请求标志位
                RequestFlag = 1;
            }
        }
        
        if (RequestFlag == 1)
        {
            // 清除请求标志位
            RequestFlag = 0;
            
            TxMsg_Request.Data[0] ++;
            TxMsg_Request.Data[1] ++;
            TxMsg_Request.Data[2] ++;
            TxMsg_Request.Data[3] ++;
            
            MyCAN_Transmit(&TxMsg_Request);
            
            OLED_ShowHexNum(4, 5, TxMsg_Request.Data[0], 2);
            OLED_ShowHexNum(4, 8, TxMsg_Request.Data[1], 2);
            OLED_ShowHexNum(4, 11, TxMsg_Request.Data[2], 2);
            OLED_ShowHexNum(4, 14, TxMsg_Request.Data[3], 2);
        }
    }
}

// 定时器2中断服务函数
void TIM2_IRQHandler(void)
{
    // 判断定时器2更新中断标志位是否置位
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
    {
        // 设置定时标志位
        TimingFlag = 1;
        // 清除定时器2更新中断标志位
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}

八.stm32基础

1.介绍

图片消失了

Cortex内核分类:

图片消失了

STM32微控制器有多种封装类型,每种封装类型都有其特定的特点和应用场景
常见的STM32封装类型:

  1. LQFP:LQFP封装是一种常见的平面封装类型,具有四边引脚,适用于大多数通用应用。LQFP封装的引脚数量从32到144不等,适合需要较多引脚的应用
  2. VFQFPN:VFQFPN封装是一种无引脚封装类型,具有较小的占用空间和较好的散热性能
  3. BGA:BGA封装是一种高密度封装类型,具有球形引脚阵列,适用于高性能和高密度的应用

LQFP144:

图片消失了

复位电路:

图片消失了

boot启动电路:

图片消失了

Cortex-M内核有硬件调试模块(JTAG和SWD调试接口),该模块可在取指(指令断点)或访问数据(数据断点)时停止。内核停止时,可以查询内核的内部状态和系统的外部状态。完成查询后,可恢复程序执行
F1系列可以通过AFIO_MAPR寄存器的SWJ_CFG[2:0]位来释放部分或者全部SWJ-DP引脚

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

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

相关文章

看雪 get_pwn3(2016 CCTF 中的 pwn3)

get_pwn3(2016 CCTF 中的 pwn3) 格式化字符串漏洞 get_pwn3(2016 CCTF 中的 pwn3) (1) motalymotaly-VMware-Virtual-Platform:~/桌面$ file pwn3 pwn3: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, …

python全栈-JavaScript

python全栈-js 文章目录 js基础变量与常量JavaScript引入到HTML文件中JavaScript注释与常见输出方式 数据类型typeof 显示数据类型算数运算符之加法运算符运算符之算术运算符运算符之赋值运算符运算符之比较运算符运算符之布尔运算符运算符之位运算符运算符优先级类型转换 控制…

操作系统概述(3)

批处理系统 1.单道批处理系统 单道批处理系统是成批地处理作用&#xff0c;并且始终只有一道作业在内存中的系统。优点&#xff1a;提高系统资源的利用率和系统吞吐量。缺点&#xff1a;系统中的资源得不到充分利用。 2.多道批处理系统 引入多道程序设计技术&#xff0c;是…

SolidWorks2025三维计算机辅助设计(3D CAD)软件超详细图文安装教程(2025最新版保姆级教程)

目录 前言 一、SolidWorks下载 二、SolidWorks安装 三、启动SolidWorks 前言 SolidWorks 是一款由法国达索系统&#xff08;Dassault Systmes&#xff09;公司开发的三维计算机辅助设计&#xff08;3D CAD&#xff09;软件&#xff0c;广泛用于机械设计、工程仿真和产品开…

JBDC Java数据库连接(1)

目录 JDBC概述 定义 JDBC API 实例 JDBC搭建 建立与数据库连接&#xff1a; 形式&#xff1a; 实例 获得Satement执行sql语句 Satement中的方法: 实例 实例 JDBC概述 定义 JDBC&#xff08;Java DataBase Connectivity&#xff09;java数据库连接是一种用于执行SQL…

git rebase复杂场景验证

经常面临复杂的分支管理&#xff0c;这里对几种场景的行为做一些验证。 结论总结 git rebase br_name&#xff1a;等价与新建br_name分支&#xff0c;然后找到当前分支与br_name分支的分叉点。然后把分叉点以后的提交&#xff08;当前分支&#xff09;一个一个的cherry-pick过…

从搜索丝滑过渡到动态规划的学习指南

搜索&动态规划 前言砝码称重满分代码及思路solution 1&#xff08;动态规划&#xff09;solution 2&#xff08;BFS&#xff09; 跳跃满分代码及思路solution 1(动态规划)solution 2 (BFS) 积木画满分代码及思路动态规划思路讲解solution 前言 本文主要是通过一些竞赛真题…

(一)栈结构、队列结构

01-线性结构-数组-栈结构 线性结构&#xff08;Linear List)是由n&#xff08;n>0)个数据元素&#xff08;结点&#xff09; a[0], a[1], a[2], a[3],...,a[n-1]组成的有限序列 数组 通常数组的内存是连续的&#xff0c;所以在知道数组下标的情况下&#xff0c;访问效率是…

MySQL基础 [五] - 表的增删查改

目录 Create&#xff08;insert&#xff09; Retrieve&#xff08;select&#xff09; where条件 ​编辑 NULL的查询 结果排序(order by) 筛选分页结果 (limit) Update Delete 删除表 截断表&#xff08;truncate&#xff09; 插入查询结果&#xff08;insertselect&…

4.7学习总结 可变参数+集合工具类Collections+不可变集合

可变参数&#xff1a; 示例&#xff1a; public class test {public static void main(String[] args) {int sumgetSum(1,2,3,4,5,6,7,8,9,10);System.out.println(sum);}public static int getSum(int...arr){int sum0;for(int i:arr){sumi;}return sum;} } 细节&#xff1a…

OpenGL学习笔记(简介、三角形、着色器、纹理、坐标系统、摄像机)

目录 简介核心模式与立即渲染模式状态机对象GLFW和GLAD Hello OpenGLTriangle 三角形顶点缓冲对象 VBO顶点数组对象 VAO元素缓冲对象 EBO/ 索引缓冲对象 IEO 着色器GLSL数据类型输入输出Uniform 纹理纹理过滤Mipmap 多级渐远纹理实际使用方式纹理单元 坐标系统裁剪空间 摄像机自…

vmware虚拟机上Ubuntu或者其他系统无法联网的解决方法

一、检查虚拟机是否开启了网络服务 打开方式&#xff1a;控制面板->-管理工具--->服务 查找 VMware DHCP Service 和VMware NAT Service &#xff0c;确保这两个服务已经启动。如下图&#xff0c;没有启动就点击启动。 二、设置网络类型 我们一般使用前两种多一些&…

OpenVLA-OFT——微调VLA时加快推理的三大关键设计:支持动作分块的并行解码、连续动作表示以及L1回归(含输入灵活化及对指令遵循的加强)

前言 25年3.26日&#xff0c;这是一个值得纪念的日子&#xff0c;这一天&#xff0c;我司「七月在线」的定位正式升级为了&#xff1a;具身智能的场景落地与定制开发商 &#xff0c;后续则从定制开发 逐步过渡到 标准产品化 比如25年q2起&#xff0c;在定制开发之外&#xff0…

LabVIEW 油井动液面在线监测系统​

项目背景 传统油井动液面测量依赖人工现场操作&#xff0c;面临成本高、效率低、安全风险大等问题。尤其在偏远地区或复杂工况下&#xff0c;测量准确性与时效性难以保障。本系统通过LabVIEW虚拟仪器技术实现硬件与软件深度融合&#xff0c;为油田智能化转型提供实时连续监测解…

泛微ECOLOGY9 解决文档中打开发票类PDF文件无内容的配置方法

解决文档中打开发票类PDF文件无内容的配置方法 情况如下&#xff1a; 如果OA文档中打开的PDF文件如下图这样空白的&#xff0c;那么可以试试下面的方法进行解决。 解决方法&#xff1a; 在OA安装目录中找到 ecology/WEB-INF/prop/docpreview.properties 配置文件&#xff…

大模型RAG项目实战-知识库问答助手v1版

安装 Ollama 根据官网指导&#xff0c;安装对应版本即可。 下载安装指导文档&#xff1a; handy-ollama/docs/C1/1. Ollama 介绍.md at main datawhalechina/handy-ollama 注意&#xff1a;在 Windows 下安装 Ollama 后&#xff0c;强烈建议通过配置环境变量来修改模型存储…

统计子矩阵

1.统计子矩阵 - 蓝桥云课 统计子矩阵 问题描述 给定一个 NM 的矩阵 A&#xff0c;请你统计有多少个子矩阵&#xff08;最小 11&#xff0c;最大 NM&#xff09;满足子矩阵中所有数的和不超过给定的整数 K&#xff1f; 输入格式 第一行包含三个整数 N&#xff0c;M 和 K。 …

C++第1讲:基础语法;通讯录管理系统

黑马程序员匠心之作|C教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili 对应的笔记&#xff1a; https://github.com/AccumulateMore/CPlusPlus 标签: C&C | welcome to here 一、C初识 1.1.注释 1.2.变量 1.3.常量&#xff1a;记录程序中不可更改的数据 1.4.关…

Python高阶函数-filter

1. 基本概念 filter() 是Python内置的高阶函数&#xff0c;用于过滤序列中的元素。它接收一个函数和一个可迭代对象作为参数&#xff0c;返回一个迭代器&#xff0c;包含使函数返回True的所有元素。 filter(function, iterable)2. 工作原理 惰性计算&#xff1a;filter对象是…

拍摄的婚庆视频有些DAT的视频文件打不开怎么办

3-12 现在的婚庆公司大多提供结婚的拍摄服务&#xff0c;或者有一些第三方公司做这方面业务&#xff0c;对于视频拍摄来说&#xff0c;有时候会遇到这样一种问题&#xff0c;就是拍摄下来的视频文件&#xff0c;然后会有一两个视频文件是损坏的&#xff0c;播放不了&#xff0…