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

25/1/16 嵌入式笔记 STM32F108

输入捕获

TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_TimeBaseStruct.TIM_Period = 0xFFFF;  // 自动重装载值
TIM_TimeBaseStruct.TIM_Prescaler = 71;  // 预分频值
TIM_TimeBaseStruct.TIM_ClockDivision = 0;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;  // 向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);
  1. 频率计算

    • 通过两次捕获的计数器值之差,结合定时器的时钟频率,可以计算出信号的频率或周期。

输入捕获的配置步骤

使能定时器时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  // 使能TIM2时钟

配置定时器基本参数

TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_TimeBaseStruct.TIM_Period = 0xFFFF;  // 自动重装载值
TIM_TimeBaseStruct.TIM_Prescaler = 71;  // 预分频值
TIM_TimeBaseStruct.TIM_ClockDivision = 0;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;  // 向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);

配置输入捕获模式

TIM_ICInitTypeDef TIM_ICStruct;
TIM_ICStruct.TIM_Channel = TIM_Channel_1;  // 选择通道1
TIM_ICStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;  // 捕获上升沿
TIM_ICStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;  // 直接输入
TIM_ICStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;  // 不分频
TIM_ICStruct.TIM_ICFilter = 0x0;  // 无滤波
TIM_ICInit(TIM2, &TIM_ICStruct);

使能捕获中断

TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);  // 使能捕获中断
NVIC_EnableIRQ(TIM2_IRQn);  // 使能TIM2中断

使能定时器

TIM_Cmd(TIM2, ENABLE);  // 使能TIM2

完整代码

#include "stm32f10x.h"volatile uint16_t CaptureValue1 = 0;  // 第一次捕获值
volatile uint16_t CaptureValue2 = 0;  // 第二次捕获值
volatile uint16_t Period = 0;  // 信号周期
volatile uint32_t Frequency = 0;  // 信号频率void TIM2_IC_Init(void) {// 使能TIM2时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);// 配置定时器基本参数TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;TIM_TimeBaseStruct.TIM_Period = 0xFFFF;  // 自动重装载值TIM_TimeBaseStruct.TIM_Prescaler = 71;  // 预分频值TIM_TimeBaseStruct.TIM_ClockDivision = 0;TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;  // 向上计数模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);// 配置输入捕获模式TIM_ICInitTypeDef TIM_ICStruct;TIM_ICStruct.TIM_Channel = TIM_Channel_1;  // 选择通道1TIM_ICStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;  // 捕获上升沿TIM_ICStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;  // 直接输入TIM_ICStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;  // 不分频TIM_ICStruct.TIM_ICFilter = 0x0;  // 无滤波TIM_ICInit(TIM2, &TIM_ICStruct);// 使能捕获中断TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);  // 使能捕获中断NVIC_EnableIRQ(TIM2_IRQn);  // 使能TIM2中断// 使能定时器TIM_Cmd(TIM2, ENABLE);
}void TIM2_IRQHandler(void) {if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) {if (CaptureValue1 == 0) {// 第一次捕获CaptureValue1 = TIM_GetCapture1(TIM2);} else {// 第二次捕获CaptureValue2 = TIM_GetCapture1(TIM2);// 计算周期if (CaptureValue2 > CaptureValue1) {Period = CaptureValue2 - CaptureValue1;} else {Period = (0xFFFF - CaptureValue1) + CaptureValue2;}// 计算频率Frequency = 1000000 / Period;  // 假设定时器时钟为1MHz// 重置捕获值CaptureValue1 = 0;CaptureValue2 = 0;}// 清除中断标志TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);}
}int main(void) {// 初始化输入捕获TIM2_IC_Init();while (1) {// 主循环}
}

编码器接口

1. 编码器接口的基本原理

  1. 编码器信号

    • 旋转编码器通常输出两路正交信号(A相和B相),用于表示旋转方向和速度。

  2. 计数器

    • 编码器接口通过捕获A相和B相的边沿信号,驱动定时器的计数器(CNT)递增或递减。

  3. 速度计算

    • 通过读取计数器的值,可以计算出编码器的旋转速度。

速度计算

  • 编码器分辨率:假设编码器的分辨率为1000脉冲/转。

  • 速度计算

    • 速度 = 编码器计数器值 / 编码器分辨率。

编码器接口的配置步骤

使能定时器时钟

  • STM32的外设(如定时器)默认是关闭时钟的,以节省功耗。

  • 使用外设前,必须使能其时钟,否则外设无法工作。

  • 这里使能了TIM2的时钟,因为我们将使用TIM2的编码器接口功能。

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  // 使能TIM2时钟

配置定时器基本参数

  • 自动重装载值(TIM_Period)

    • 设置定时器计数器的最大值。这里设置为 0xFFFF(16位定时器的最大值),表示计数器从0计数到65535后溢出。

    • 编码器模式下,计数器会根据编码器的脉冲信号递增或递减,因此需要足够大的计数范围。

  • 预分频器(TIM_Prescaler)

    • 用于分频定时器的时钟频率。这里设置为0,表示不分频,定时器直接使用输入时钟频率。

    • 如果编码器脉冲频率较高,可以适当增加预分频值以降低计数器频率。

  • 时钟分频(TIM_ClockDivision)

    • 用于分频定时器的输入时钟。这里设置为0,表示不进行额外的时钟分频。

  • 计数模式(TIM_CounterMode)

    • 设置计数器的计数模式。编码器模式下,计数模式通常设置为向上计数(TIM_CounterMode_Up),但实际计数方向由编码器信号决定。

TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_TimeBaseStruct.TIM_Period = 0xFFFF;  // 自动重装载值
TIM_TimeBaseStruct.TIM_Prescaler = 0;  // 不分频
TIM_TimeBaseStruct.TIM_ClockDivision = 0;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;  // 向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);

配置编码器接口模式

  • 编码器模式(TIM_EncoderMode_TI12)

    • 设置定时器为编码器模式,使用TIM2的通道1和通道2(TI1和TI2)作为编码器的输入信号。

    • 编码器模式会根据A相和B相信号的边沿变化来驱动计数器递增或递减。

  • 输入捕获极性(TIM_ICPolarity_Rising)

    • 设置编码器信号的捕获边沿。这里设置为上升沿触发,表示在A相和B相信号的上升沿时捕获计数器值。

TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

配置输入捕获通道

  • 通道选择(TIM_Channel)

    • 选择定时器的通道1和通道2作为编码器的输入信号。

  • 捕获极性(TIM_ICPolarity)

    • 设置捕获信号的边沿。这里设置为上升沿触发。

  • 输入选择(TIM_ICSelection)

    • 设置输入信号的来源。这里设置为直接输入(TIM_ICSelection_DirectTI),表示直接使用TIM2的通道1和通道2作为输入。

  • 输入分频(TIM_ICPrescaler)

    • 设置输入信号的分频。这里设置为不分频(TIM_ICPSC_DIV1),表示每个边沿都触发捕获。

  • 输入滤波(TIM_ICFilter)

    • 设置输入信号的滤波。这里设置为无滤波(0x0),表示不对输入信号进行滤波。

TIM_ICInitTypeDef TIM_ICStruct;
TIM_ICStruct.TIM_Channel = TIM_Channel_1;  // 选择通道1
TIM_ICStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;  // 捕获上升沿
TIM_ICStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;  // 直接输入
TIM_ICStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;  // 不分频
TIM_ICStruct.TIM_ICFilter = 0x0;  // 无滤波
TIM_ICInit(TIM2, &TIM_ICStruct);TIM_ICStruct.TIM_Channel = TIM_Channel_2;  // 选择通道2
TIM_ICInit(TIM2, &TIM_ICStruct);

 使能定时器

  • 使能定时器后,定时器开始工作,计数器会根据编码器信号的变化递增或递减。

  • 如果不使能定时器,编码器接口将无法工作。

TIM_Cmd(TIM2, ENABLE);  // 使能TIM2
完整代码
#include "stm32f10x.h"volatile int16_t EncoderCount = 0;  // 编码器计数器值void TIM2_Encoder_Init(void) {// 使能TIM2时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);// 配置定时器基本参数TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;TIM_TimeBaseStruct.TIM_Period = 0xFFFF;  // 自动重装载值TIM_TimeBaseStruct.TIM_Prescaler = 0;  // 不分频TIM_TimeBaseStruct.TIM_ClockDivision = 0;TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;  // 向上计数模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);// 配置编码器接口模式TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);// 配置输入捕获通道TIM_ICInitTypeDef TIM_ICStruct;TIM_ICStruct.TIM_Channel = TIM_Channel_1;  // 选择通道1TIM_ICStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;  // 捕获上升沿TIM_ICStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;  // 直接输入TIM_ICStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;  // 不分频TIM_ICStruct.TIM_ICFilter = 0x0;  // 无滤波TIM_ICInit(TIM2, &TIM_ICStruct);TIM_ICStruct.TIM_Channel = TIM_Channel_2;  // 选择通道2TIM_ICInit(TIM2, &TIM_ICStruct);// 使能定时器TIM_Cmd(TIM2, ENABLE);
}int main(void) {// 初始化编码器接口TIM2_Encoder_Init();while (1) {// 读取编码器计数器值EncoderCount = TIM_GetCounter(TIM2);// 主循环}
}

模数转换器

ADC基本结构

ADC(Analog-to-Digital Converter,模数转换器)用于将模拟信号转换为数字信号。STM32的ADC模块通常包括以下主要部分:

1.1 模拟看门狗(Analog Watchdog)
  • 作用:监控ADC转换结果,当转换结果超出设定的阈值范围时,触发中断或事件。

  • 应用场景:用于检测模拟信号是否在正常范围内。

1.2 中断输出控制
  • 作用:在ADC转换完成、模拟看门狗触发等事件发生时,产生中断信号。

  • 应用场景:用于通知CPU处理ADC转换结果。

1.3 CPU
  • 作用:处理ADC转换结果,执行相应的逻辑。

1.4 ADC转换器
  • 作用:将模拟信号转换为数字信号。

  • 分辨率:STM32的ADC通常支持12位分辨率,即转换结果为0到4095。

1.5 AD数据寄存器
  • 作用:存储ADC转换结果。

  • 规则组结果:存储规则组通道的转换结果。

  • 注入组结果:存储注入组通道的转换结果。

1.6 规则组(Regular Group)
  • 作用:用于常规的ADC转换,支持多个通道按顺序转换。

  • 特点:规则组转换结果存储在单个寄存器中。

1.7 注入组(Injected Group)
  • 作用:用于高优先级的ADC转换,支持多个通道按顺序转换。

  • 特点:注入组转换结果存储在多个寄存器中,优先级高于规则组。

1.8 温度传感器
  • 作用:内置温度传感器,用于测量芯片温度。

  • 特点:通常连接到ADC的某个通道。

1.9 VREFINT
  • 作用:内部参考电压,用于校准ADC转换结果。

  • 特点:通常连接到ADC的某个通道。

1.10 START
  • 作用:启动ADC转换。

  • 触发方式:可以通过软件或外部事件触发。

1.11 CLOCK
  • 作用:提供ADC转换的时钟信号。

  • 来源:通常由RCC(Reset and Clock Control)模块提供。

1.12 触发控制
  • 作用:控制ADC转换的触发方式。

  • 触发源:可以是定时器、外部信号等。

1.13 RCC
  • 作用:提供ADC模块的时钟信号。

  • 配置:通过RCC配置ADC的时钟频率。

1.14 开关控制
  • 作用:控制ADC模块的开启和关闭。

  • 应用场景:用于节省功耗。

#include "stm32f10x.h"  // 包含STM32F10x系列的头文件void ADC_Init(void) {// 1. 使能GPIOA和ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);// 2. 配置GPIOA的引脚0为模拟输入模式GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;  // 选择引脚0GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;  // 模拟输入模式GPIO_Init(GPIOA, &GPIO_InitStruct);// 3. 配置ADC1ADC_InitTypeDef ADC_InitStruct;ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;  // 独立模式ADC_InitStruct.ADC_ScanConvMode = DISABLE;  // 单通道模式ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;  // 单次转换模式ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 软件触发ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;  // 数据右对齐ADC_InitStruct.ADC_NbrOfChannel = 1;  // 1个通道ADC_Init(ADC1, &ADC_InitStruct);// 4. 配置ADC1的通道0(PA0)ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);// 5. 使能ADC1ADC_Cmd(ADC1, ENABLE);// 6. 校准ADC1ADC_ResetCalibration(ADC1);  // 重置校准寄存器while (ADC_GetResetCalibrationStatus(ADC1));  // 等待重置完成ADC_StartCalibration(ADC1);  // 开始校准while (ADC_GetCalibrationStatus(ADC1));  // 等待校准完成
}uint16_t ADC_Read(void) {// 1. 启动ADC转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);// 2. 等待转换完成while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));// 3. 读取转换结果return ADC_GetConversionValue(ADC1);
}int main(void) {// 初始化ADCADC_Init();while (1) {// 读取ADC值uint16_t adcValue = ADC_Read();// 处理ADC值(例如:打印到串口或控制LED)// ...}
}

直接存储器DMA

通信接口

USART协议

相关文章:

25/1/16 嵌入式笔记 STM32F108

输入捕获 TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_TimeBaseStruct.TIM_Period 0xFFFF; // 自动重装载值 TIM_TimeBaseStruct.TIM_Prescaler 71; // 预分频值 TIM_TimeBaseStruct.TIM_ClockDivision 0; TIM_TimeBaseStruct.TIM_CounterMode TIM_CounterMode_Up…...

mac 安装 node

brew versions node // 安装 node brew versions node14 // 安装指定版本 卸载node: sudo npm uninstall npm -g sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receipts/org.nodejs.* sudo rm -rf /usr/local/include/node /Users/$USER/.npm su…...

mysql常用运维命令

mysql常用运维命令 查看当前所有连接 -- 查看当前所有连接 SHOW FULL PROCESSLIST;说明: 关注State状态列,是否有锁。如果大量状态是waiting for handler commit检查磁盘是否占满关注Time耗时列,是否有慢查询关注Command列,如果…...

正则表达式学习网站

网上亲测好用的网站: Regexlearn 这个网站可以从0开始教会正则表达式的使用。 mklab 包含常用表达式,车次,超链接,号码等提取。...

gradle,adb命令行编译备忘

追踪依赖(为了解决duplicateClass…错误) gradlew.bat app:dependencies > dep-tree.txt # 分析dep-tree.txt的依赖结构,找到对应的包,可能需要做exclude控制,或者查看库issueverbose编译(我一直需要verbose) gradlew.bat assembleDebug -Dhttps.pr…...

C++:工具VSCode的编译和调试文件内容:

ubuntu24.04, vscode 配置文件 C 的环境 下载的gcc,使用命令为 sudo aptitude update sudo aptitude install build-essential -f- sudo: 以超级用户权限运行命令。 - aptitude: 包管理工具,用于安装、更新和删除软件包。 - install: 安装指…...

SpringMVC Idea 搭建 部署war

1.创建 Idea项目 使用Maven模板 创建 webApp模板项目 2.导入依赖 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://ma…...

YOLOv10-1.1部分代码阅读笔记-loaders.py

loaders.py ultralytics\data\loaders.py 目录 loaders.py 1.所需的库和模块 2.class SourceTypes: 3.class LoadStreams: 4.class LoadScreenshots: 5.class LoadImagesAndVideos: 6.class LoadPilAndNumpy: 7.class LoadTensor: 8.def autocast_list(source…...

Windows的Redis查看自己设置的密码并更改设置密码

查看密码 由于我的Redis安装很久了&#xff0c;所以忘记是否有设置密码&#xff0c;查看步骤如下&#xff1a; 启动redis&#xff0c;启动流程可以看这篇文章&#xff1a;https://blog.csdn.net/changyana/article/details/127679871 在redis安装目录下打开redis-cli.exe&…...

【Linux】sed编辑器二

一、处理多行命令 sed编辑器有3种可用于处理多行文本的特殊命令。 N&#xff1a;加入数据流中的下一行&#xff0c;创建一个多行组进行处理&#xff1b;D&#xff1a;删除多行组中的一行&#xff1b;P&#xff1a;打印多行组中的一行。 1、next命令&#xff1a;N 单行next命…...

docker 部署 Kafka 单机和集群

一、准备工作 安装 Docker 确保本机已安装 Docker。可以通过以下命令检查 Docker 是否已安装&#xff1a;docker --version如果未安装&#xff0c;可以访问 Docker 官网下载并安装 Docker Desktop&#xff08;Windows 和 Mac&#xff09;或使用包管理器安装&#xff08;Linux&…...

PHP语言的软件开发工具

PHP语言的软件开发工具 在当今数字化的时代&#xff0c;软件开发已经成为一种常见的职业。无论是企业级应用、网站开发还是移动应用&#xff0c;开发者们都需要用到各种各样的工具。PHP作为一种广泛使用的服务器端脚本语言&#xff0c;因其简单、灵活与强大的功能&#xff0c;…...

前端【3】--CSS布局,CSS实现横向布局,盒子模型

盒子分类 1、块级盒子 2、内联级盒子 3、内联块级盒子 4、弹性盒子 5、盒子内部分区 方法一&#xff1a;使用 float 普通盒子实现横向布局 方法二&#xff1a;使用 display: inline-block 内联块级元素实现横向布局 方法三&#xff1a;使用弹性盒子 flexbox&#xff0…...

SQL语句IN和OR的区别

在SQL中&#xff0c;IN和OR都用于筛选条件&#xff0c;但它们的用途和性能上有一些区别。以下是两者的对比&#xff1a; 1. 语法 IN SELECT * FROM table_name WHERE column_name IN (value1, value2, value3);IN用于检查某列的值是否在一个给定的值列表中。 OR SELECT * FRO…...

OCP使用中的常见问题与解决方法

OCP的常见问题 页面卡顿&#xff1a; 遇到页面卡顿的问题时&#xff0c;首先需要区分是全局性的卡顿&#xff0c;即所有页面都出现延迟或响应缓慢&#xff0c;还是仅限于特定的监控页面。 监控数据看不到: 需要明确是全部数据都无法查看&#xff0c;还是仅限于特定集群的数…...

Git 版本控制:.gitignore 文件完全指南

.gitignore 文件是 Git 版本控制系统中的一个重要配置文件&#xff0c;用于告诉 Git 哪些文件和目录应该被忽略&#xff0c;不需要纳入版本控制。以下是关于 .gitignore 的完整笔记。 基本概念 .gitignore 文件可以放在项目的任何目录下&#xff0c;其作用范围包括所在目录及…...

STM32 FreeRTOS 介绍

目录 什么是裸机开发 什么是操作系统 通用操作系统 实时操作系统 FreeRTOS简介 FreeRTOS发展历史 FreeRTOS优势 FreeRTOS特点 什么是裸机开发 裸机开发指的是在没有操作系统&#xff08;OS&#xff09;或者其他高级软件支持的情况下&#xff0c;直接在裸机硬件上进行软…...

在 Azure 100 学生订阅中新建 Ubuntu VPS 并部署 Mastodon 服务器

今天想和大家分享一下如何在 Azure 的 100 学生订阅中&#xff0c;创建一台 Ubuntu VPS&#xff0c;并通过 Docker 部署 Mastodon 服务器。Mastodon 是一个开源的社交网络平台&#xff0c;允许用户创建自己的实例&#xff0c;类似于 Twitter&#xff0c;但更加去中心化。Docker…...

【Linux网络编程】序列化与反序列化

目录 一&#xff0c;序列化和反序列化的说明 二&#xff0c;Jsoncpp库的介绍 三&#xff0c;Jsoncpp库的使用 3-1&#xff0c;Json::Value类 3-2&#xff0c;Json::StreamWriter类 3-3&#xff0c;Json::CharReader类 一&#xff0c;序列化和反序列化的说明 序列化与反…...

Spring Boot中的自动配置原理是什么

Spring Boot 自动配置原理 Spring Boot 的自动配置机制基于 条件化配置&#xff0c;通过 EnableAutoConfiguration 注解来启用。自动配置的核心原理是 基于类路径和环境条件来推断所需要的配置&#xff0c;Spring Boot 会根据项目中引入的依赖和当前环境来自动装配相关的配置项…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...