【STM32-学习笔记-6-】DMA

文章目录

  • DMA
    • Ⅰ、DMA框图
    • Ⅱ、DMA基本结构
    • Ⅲ、不同外设的DMA请求
    • Ⅳ、DMA函数
    • Ⅴ、DMA_InitTypeDef结构体参数
      • ①、DMA_PeripheralBaseAddr
      • ②、DMA_PeripheralDataSize
      • ③、DMA_PeripheralInc
      • ④、DMA_MemoryBaseAddr
      • ⑤、DMA_MemoryDataSize
      • ⑥、DMA_MemoryInc
      • ⑦、DMA_DIR
      • ⑧、DMA_BufferSize
      • ⑨、DMA_Mode
      • ⑩、DMA_M2M
      • ①①、DMA_Priority
    • Ⅵ、DMA配置示例
      • DMA+AD多通道
        • 1. ADC单次扫描+DMA数据转运
        • 2. ADC连续扫描+DMA循环转运

DMA

Ⅰ、DMA框图

image-20241227112815688

Ⅱ、DMA基本结构

image-20241227112841087

Ⅲ、不同外设的DMA请求

image-20241227113057979

Ⅳ、DMA函数

// 重置指定的DMA通道寄存器为默认值
void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx);// 初始化指定的DMA通道,根据初始化结构体配置参数
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);// 初始化DMA初始化结构体的默认值
void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct);// 开启或关闭指定的DMA通道
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);// 开启或关闭DMA通道的中断
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);// 设置DMA当前数据计数器的值
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); // 获取DMA当前数据计数器的值
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);// 获取DMA标志状态
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
// 清除DMA标志
void DMA_ClearFlag(uint32_t DMAy_FLAG);// 获取DMA中断状态	
ITStatus DMA_GetITStatus(uint32_t DMAy_IT);
// 清除DMA中断待处理位
void DMA_ClearITPendingBit(uint32_t DMAy_IT);

Ⅴ、DMA_InitTypeDef结构体参数

①、DMA_PeripheralBaseAddr

指定DMA通道的外设基地址外设寄存器-起始地址

    • 类型uint32_t
    • 取值范围:任意有效的外设地址
    • 作用:这是DMA操作的外设端的起始地址,例如ADC、USART等外设的数据寄存器地址

②、DMA_PeripheralDataSize

指定外设寄存器的数据宽度配置DMA传输时外设数据的大小

  • 该参数可以是@ref DMA_peripheral_data_size

    • 宏定义解释

      1. DMA_PeripheralDataSize_Byte
        • 描述:表示外设数据大小为1字节(8位)
          • 每次DMA传输的数据大小为1字节
      2. DMA_PeripheralDataSize_HalfWord
        • 描述:表示外设数据大小为半字(16位)
          • 每次DMA传输的数据大小为2字节
      3. DMA_PeripheralDataSize_Word
        • 描述:表示外设数据大小为1字(32位)
          • 每次DMA传输的数据大小为4字节

      宏函数

      1. IS_DMA_PERIPHERAL_DATA_SIZE(SIZE)
        • 描述:检查给定的外设数据大小设置是否有效
        • 参数SIZE,代表DMA的外设数据大小
        • 功能:检查SIZE是否等于DMA_PeripheralDataSize_ByteDMA_PeripheralDataSize_HalfWordDMA_PeripheralDataSize_Word中的任一个。
        • 返回值:如果SIZE有效,返回1(真),否则返回0(假)

③、DMA_PeripheralInc

指定外设地址寄存器是否递增

    • 类型uint32_t
    • 取值范围
      • DMA_PeripheralInc_Disable:外设地址不递增
      • DMA_PeripheralInc_Enable:外设地址递增
    • 作用:控制外设地址在每次数据传输后是否递增

④、DMA_MemoryBaseAddr

指定DMA通道的内存基地址存储器-起始地址

    • 类型uint32_t
    • 取值范围:任意有效的内存地址
    • 作用:这是DMA操作的内存端的起始地址,例如一个缓冲区的起始地址

⑤、DMA_MemoryDataSize

指定内存数据宽度存储器-数据宽度

    • 类型uint32_t
    • 取值范围
      • DMA_MemoryDataSize_Byte:数据宽度为8位
      • DMA_MemoryDataSize_HalfWord:数据宽度为16位
      • DMA_MemoryDataSize_Word:数据宽度为32位
    • 作用:确定内存数据的大小

⑥、DMA_MemoryInc

指定内存地址寄存器是否递增指定存储器-是否递增

    • 类型uint32_t
    • 取值范围
      • DMA_MemoryInc_Disable:内存地址不递增
      • DMA_MemoryInc_Enable:内存地址递增
    • 作用:控制内存地址在每次数据传输后是否递增

⑦、DMA_DIR

指定数据传输方向,即外设是数据源还是数据目标指定外设站点是源还是目标

    • 类型uint32_t
    • 取值范围
      • DMA_DIR_PeripheralSRC外设是数据源,内存是数据目标
      • DMA_DIR_PeripheralDST:外设是数据目标,内存是数据源
    • 作用:确定数据传输的方向

⑧、DMA_BufferSize

指定DMA通道的缓冲区大小,以数据单元为单位

  • DMA_InitStruct.DMA_BufferSize = Size; 传递Size个大小为<数据宽度>的数据

    • 类型uint32_t
    • 取值范围:0到65535
    • 作用:确定要传输的数据量。数据单元的大小取决于DMA_PeripheralDataSizeDMA_MemoryDataSize的配置,具体取决于传输方向

⑨、DMA_Mode

指定DMAy通道的工作模式是否要自动重装

    • 类型uint32_t
    • 取值范围
      • DMA_Mode_Normal正常模式,传输完成后停止
      • DMA_Mode_Circular:循环模式(自动重装),传输完成后从头开始
    • 作用:确定DMA传输的模式。循环模式不适用于内存到内存的传输

⑩、DMA_M2M

是否使用软件触发存储器到存储器

    • 类型uint32_t
    • 描述:指定DMA通道是否用于内存到内存的传输
    • 取值范围
      • DMA_M2M_Disable不使用内存到内存传输
      • DMA_M2M_Enable使用内存到内存传输
    • 作用:确定DMA通道是否用于内存到内存的传输

①①、DMA_Priority

指定DMA通道的软件优先级

  • 按需求配置

    • 类型uint32_t
    • 取值范围
      • DMA_Priority_Low低优先级
      • DMA_Priority_Medium中优先级
      • DMA_Priority_High高优先级
      • DMA_Priority_VeryHigh非常高优先级
    • 作用:确定DMA通道的优先级,影响多个DMA请求的处理顺序

Ⅵ、DMA配置示例

#include "stm32f10x.h"                  // Device headeruint32_t Temp_Size;//存储数据计数器的值void MyDMA_Init(uint32_t Source, uint32_t Dest, uint32_t Size)//参数需为两个数组的数组名
{Temp_Size = Size;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);DMA_InitTypeDef DMA_InitStruct;DMA_InitStruct.DMA_PeripheralBaseAddr = Source;//外设寄存器-起始地址DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设寄存器-数据宽度(此处为1byte)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//指定外设地址寄存器-是否递增DMA_InitStruct.DMA_MemoryBaseAddr = Dest;//存储器-起始地址DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器-数据宽度DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//指定存储器-是否递增DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设站点是源还是目标DMA_InitStruct.DMA_BufferSize = Size;//传递Size个大小为<数据宽度>的数据DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//指定DMAy通道的工作模式(是否要自动重装)DMA_InitStruct.DMA_M2M = DMA_M2M_Enable;//是否使用软件触发(存储器到存储器)DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//指定DMAy通道的软件优先级DMA_Init(DMA1_Channel1, &DMA_InitStruct);DMA_Cmd(DMA1_Channel1, DISABLE);//使能或失能DMA
}void MyDMA_Transfer(void)//调用函数则开始转运
{DMA_Cmd(DMA1_Channel1, DISABLE);//失能DMADMA_SetCurrDataCounter(DMA1_Channel1, Temp_Size);//设置DMA当前数据计数器的值DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMAwhile(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET)//获取DMA标志状态(等待转运完成)DMA_ClearFlag(DMA1_FLAG_TC1);//清除DMA标志位
}

DMA+AD多通道

1. ADC单次扫描+DMA数据转运
#include "stm32f10x.h"                  // Device header
//模拟量转换为数字量
//AD多通道(ADC扫描模式+DMA数据转运)uint16_t Dest_Data[4];void AD_Init(void)
{	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//开启DMA时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟(72MHz/6=12MHz)//配置GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_41Cycles5);//配置ADC常规通道ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_41Cycles5);//配置ADC常规通道ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_41Cycles5);//配置ADC常规通道ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_41Cycles5);//配置ADC常规通道//配置ADCADC_InitTypeDef ADC_InitStruct;ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//将ADC配置为独立或操作双模式ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//单次转换or连续转换ADC_InitStruct.ADC_ScanConvMode = ENABLE;//非扫描模式or扫描模式ADC_InitStruct.ADC_NbrOfChannel = 4;//指定要转换的ADC通道的数量ADC_Init(ADC1, &ADC_InitStruct);//配置DMA	DMA_InitTypeDef DMA_InitStruct;DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设寄存器-起始地址DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设寄存器-数据宽度(此处为1byte)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//指定外设地址寄存器-是否递增DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)Dest_Data;//存储器-起始地址DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器-数据宽度DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//指定存储器-是否递增DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设站点是源还是目标DMA_InitStruct.DMA_BufferSize = 4;//传递Size个大小为<数据宽度>的数据DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//指定DMAy通道的工作模式(是否要自动重装)DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;//是否使用软件触发(存储器到存储器)DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//指定DMAy通道的软件优先级DMA_Init(DMA1_Channel1, &DMA_InitStruct);ADC_DMACmd(ADC1, ENABLE);//开启ADC的DMA功能DMA_Cmd(DMA1_Channel1, ENABLE);//使能或失能DMAADC_Cmd(ADC1, ENABLE);//开启ADC//ADC复位+校准ADC_ResetCalibration(ADC1);//重置ADC校准,准备进行校准操作while(ADC_GetResetCalibrationStatus(ADC1) == SET);//获取ADC重置校准状态,检查是否完成ADC_StartCalibration(ADC1);//开始ADC校准while(ADC_GetCalibrationStatus(ADC1) == SET);//获取ADC校准状态,检查是否完成
}void AD_GetValue(void)//获取模拟值
{//选择不同的通道或取ADC值DMA_Cmd(DMA1_Channel1, DISABLE);//失能DMADMA_SetCurrDataCounter(DMA1_Channel1, 4);//设置DMA当前数据计数器的值DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMAADC_SoftwareStartConvCmd(ADC1, ENABLE);//开启软件启动ADC转换,用于软件触发转换--启动while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET)//获取DMA标志状态(等待转运完成)DMA_ClearFlag(DMA1_FLAG_TC1);//清除DMA标志位}
2. ADC连续扫描+DMA循环转运
#include "stm32f10x.h"                  // Device header
//模拟量转换为数字量
//AD多通道(ADC连续扫描+DMA循环转运)uint16_t Dest_Data[4];void AD_Init(void)
{	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//开启DMA时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟(72MHz/6=12MHz)//配置GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_41Cycles5);//配置ADC常规通道ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_41Cycles5);//配置ADC常规通道ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_41Cycles5);//配置ADC常规通道ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_41Cycles5);//配置ADC常规通道//配置ADCADC_InitTypeDef ADC_InitStruct;ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//将ADC配置为独立或操作双模式ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//单次转换or连续转换**********************************************ADC_InitStruct.ADC_ScanConvMode = ENABLE;//非扫描模式or扫描模式ADC_InitStruct.ADC_NbrOfChannel = 4;//指定要转换的ADC通道的数量ADC_Init(ADC1, &ADC_InitStruct);//配置DMA	DMA_InitTypeDef DMA_InitStruct;DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外设寄存器-起始地址DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设寄存器-数据宽度(此处为1byte)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//指定外设地址寄存器-是否递增DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)Dest_Data;//存储器-起始地址DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器-数据宽度DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//指定存储器-是否递增DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设站点是源还是目标DMA_InitStruct.DMA_BufferSize = 4;//传递Size个大小为<数据宽度>的数据DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;//指定DMAy通道的工作模式(是否要自动重装)******************************DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;//是否使用软件触发(存储器到存储器)DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//指定DMAy通道的软件优先级DMA_Init(DMA1_Channel1, &DMA_InitStruct);ADC_DMACmd(ADC1, ENABLE);//开启ADC的DMA功能DMA_Cmd(DMA1_Channel1, ENABLE);//使能或失能DMAADC_Cmd(ADC1, ENABLE);//开启ADC//ADC复位+校准ADC_ResetCalibration(ADC1);//重置ADC校准,准备进行校准操作while(ADC_GetResetCalibrationStatus(ADC1) == SET);//获取ADC重置校准状态,检查是否完成ADC_StartCalibration(ADC1);//开始ADC校准while(ADC_GetCalibrationStatus(ADC1) == SET);//获取ADC校准状态,检查是否完成ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开启软件启动ADC转换,用于软件触发转换--启动********************************
}
//*****************************************************************************************

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

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

相关文章

SQL Server中可以通过扩展事件来自动抓取阻塞

在SQL Server中可以通过扩展事件来自动抓取阻塞&#xff0c;以下是详细流程&#xff1a; 开启阻塞跟踪配置&#xff1a; • 执行以下SQL语句来启用相关配置&#xff1a; EXEC sp_configureshow advanced options, 1; RECONFIGURE; EXEC sp_configure blocked process thresh…

【爬虫】单个网站链接爬取文献数据:标题、摘要、作者等信息

源码链接&#xff1a; https://github.com/Niceeggplant/Single—Site-Crawler.git 一、项目概述 从指定网页中提取文章关键信息的工具。通过输入文章的 URL&#xff0c;程序将自动抓取网页内容 二、技术选型与原理 requests 库&#xff1a;这是 Python 中用于发送 HTTP 请求…

关于扫描模型 拓扑 和 传递贴图工作流笔记

关于MAYA拓扑和传递贴图的操作笔记 一、拓扑低模: 1、拓扑工作区位置: 1、准备出 目标 高模。 (高模的状态如上 ↑ )。 2、打开顶点吸附,和建模工具区,选择四边形绘制. 2、拓扑快捷键使…

解决无法远程管理Windows Server服务器核心安装

问题 有时&#xff0c;人们会为了节省运算资源&#xff0c;例如运行Hyper-V虚拟机&#xff0c;而选择Windows Server核心安装&#xff0c;即无图形化界面。这时&#xff0c;我们就只能通过Powershell命令对其进行操控&#xff0c;或为了获得图形化界面而使用远程服务器管理工具…

【计算机网络】lab7 TCP协议

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;计算机网络_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 实验目的…

JavaRestClient 客户端初始化+索引库操作

1. 介绍 ES官方提供了各种不同语言的客户端&#xff0c;用来操作ES。这些客户端的本质就是组装DSL语句&#xff0c;通过http请求发送给ES。 Elasticsearch目前最新版本是8.0&#xff0c;其java客户端有很大变化。不过大多数企业使用的还是8以下版本 2. 客户端初始化 在elastic…

【JVM-2.2】使用JConsole监控和管理Java应用程序:从入门到精通

在Java应用程序的开发和运维过程中&#xff0c;监控和管理应用程序的性能和资源使用情况是非常重要的。JConsole是Java Development Kit&#xff08;JDK&#xff09;自带的一款图形化监控工具&#xff0c;它可以帮助开发者实时监控Java应用程序的内存、线程、类加载以及垃圾回收…

基于html5实现音乐录音播放动画源码

源码介绍 基于html5实现音乐录音播放动画源码是一款类似Shazam的UI&#xff0c;点击按钮后&#xff0c;会变成为一个监听按钮。旁边会有音符飞入这个监听按钮&#xff0c;最后转换成一个音乐播放器。 效果预览 源码获取 基于html5实现音乐录音播放动画源码

《自动驾驶与机器人中的SLAM技术》ch1:自动驾驶

目录 1.1 自动驾驶技术 1.2 自动驾驶中的定位与地图 1.1 自动驾驶技术 1.2 自动驾驶中的定位与地图 L2 在技术实现上会更倾向于实时感知&#xff0c;乃至可以使用感知结果直接构建鸟瞰图&#xff08;bird eye view, BEV&#xff09;&#xff0c;而 L4 则依赖离线地图。 高精地…

【LeetCode】:删除回文子数组【困难】

class Solution { public:// 思考:能否用滚动数组进行优化int minimumMoves(vector<int>& arr) {// 定义状态dp[i][j]为i-j的最小步数int n arr.size();vector<vector<int>> dp(n, vector<int>(n, 1e9 7));// 可以把这 1 次理解为一种 最小操作单…

ChatGPT入门之文本情绪识别:先了解LSTM如何处理文字序列

文章目录 0. 首先聊聊什么是RNN1. 理解LSTM&#xff0c;从数据如何喂给 LSTM开始2. LSTM每个门是如何处理序列数据的&#xff1f;2.1 遗忘门&#xff08;Forget Gate&#xff09;&#xff1a;该忘掉哪些信息&#xff1f;2.2 输入门&#xff08;Input Gate&#xff09;&#xff…

AI学习路线图-邱锡鹏-神经网络与深度学习

1 需求 神经网络与深度学习 2 接口 3 示例 4 参考资料

C#用直线和曲线抗锯齿

使用 GDI 绘制一条线时&#xff0c;要提供线条的起点和终点&#xff0c;但不必提供有关线条上各个像素的任何信息。 GDI 与显示驱动程序软件协同工作&#xff0c;确定将打开哪些像素以在特定显示设备上显示该线条。 效果对比 代码实现 关键代码 e.Graphics.SmoothingMode Sm…

【opencv】第8章 图像轮廓与图像分割修复

8.1 查找并绘制轮廓 一个轮廓一般对应一系列的点&#xff0c;也就是图像中的一条曲线。其表示方法可能 根据不同的情况而有所不同。在OpenCV 中&#xff0c;可以用findContours()函数从二值图 像中查找轮廓 8.1.1 寻找轮廓&#xff1a; findContours() 函数 findContours) 函…

Unity 大地图功能 离线瓦片地图

不使用第二个摄像机实现类似开放世界的大地图功能。 功能如下&#xff1a; 按下M键打开/关闭大地图功能 打开大地图时&#xff0c;默认玩家位置居中 大地图支持拖拽&#xff0c;可调节拖拽速度&#xff0c;支持XY轴翻转 支持大地图设置边缘偏移量 可设置是否启动拖拽边界 …

Bootstrap 前端 UI 框架

Bootstrap官网&#xff1a;Bootstrap中文网 铂特优选 Bootstrap 下载 点击进入中文文档 点击下载 生产文件是开发响应式网页应用&#xff0c;源码是底层逻辑代码&#xff0c;因为是要制作响应式网页&#xff0c;所以下载开发文件 引入 css 文件&#xff0c; bootstrap.css 和 …

error: linker `link.exe` not found

开始学习rust&#xff0c;安装好rust的环境&#xff0c;开始从hello world开始&#xff0c;结果用在win10环境下&#xff0c;使用vs code或cmd窗口编译rust报错&#xff1a; PS E:\study_codes\rust-demo\chart01> rustc hello.rs error: linker link.exe not found| note:…

django基于Python的校园个人闲置物品换购平台

Django 基于 Python 的校园个人闲置物品换购平台 一、平台概述 Django 基于 Python 的校园个人闲置物品换购平台是专为校园师生打造的一个便捷、环保且充满活力的线上交易场所。它借助 Django 这一强大的 Python Web 开发框架&#xff0c;整合了校园内丰富的闲置物品资源&…

【Vim Masterclass 笔记10】S06L23:Vim 核心操作训练之 —— 文本的搜索、查找与替换操作(第二部分)

文章目录 S06L23 Search, Find, and Replace - Part Two1 文本替换命令 :s/old/new/2 指定范围的文本替换3 特例&#xff1a;路径的替换4 文件行号的配置5 要点总结&#xff08;1&#xff09;搜索当前行&#xff08;Same Line Searching&#xff09;&#xff08;2&#xff09;跨…

【计算机网络】课程 实验五 静态路由配置

实验五 静态路由配置 一、实验目的 理解静态路由的工作原理&#xff0c;掌握如何配置静态路由。 二、实验分析与设计 【背景描述】 假设校园网分为 2 个区域&#xff0c;每个区域内使用 1 台路由器连接 2 个子网&#xff0c; 现要在路由器上 做适当配置&#xff0c;实现校…