【GL08】STM32--ADC/DAC

一、ADC简介

        ADC 即模拟信号到数字信号的转换,即用数字信号展现模拟的世界,所有的计算机或者数字处理器只能接受以 0 和 1 两种状态的数字信号,而对于模拟信号,则无法识别,而需要经过模拟数字转换器来感受模拟的世界。
        ADC 的本身的性能也是非常重要的,ADC 的主要指标有分辨率(Resolution)、采样速率(Sample Rate)、量化误差(Quantuzing Error)、增益误差(Gain Error)、微分非线性(Differential Nonlinerity)。

        1. ADC参数

        1.分辨率:数字变化一个最小量时模拟信号的变化量,定义为满刻度与2n 的比值,其中 n为 ADC 位数,分辨率越高,数字量转换一格时对应的模拟量变化越精细,越能表示实际的模拟信号。

        2.采样速率:每秒的采样次数称为采样速率,又称为吞吐率,以每秒采样数为单位,即SPS(Sample Per Secind)。

        3.转换速率:与采样速率不同,采样时间与转换速率成反比,即完成一次完整的 AD 转换所需要的时间,采样时间由 ADC 的转换时间和建立时间等构成。在建立时间中受到外部信号源的输出阻抗的影响,信号源的输出阻抗越大,ADC 建立时间将越长,从而增加了采样时间,可以利用运算放大器的高输入阻抗低输出阻抗特性设计成一个电压跟随器,再接到ADC 模拟输入端,这样可以减小串入到模拟输入端的电阻,从而减少建立时间以保证 ADC能活得更大的采样率,串接电压跟随器还可以起到减小被采样对象对系统干扰的作用。另外,在多通道采样中,由于通道切换需要时间,也要充分考虑 ADC 建立时间的问题。

        4.量化误差:由 ADC 的优先分辨率引起的误差,即优先分辨率 ADC 的阶梯状转换特性曲线与理想 ADC 的特性曲线之间的最大偏差。通常是 1 个或半个最小数字量的模拟变化量(1LSB 或 1/2LSB)。

        5.偏移误差。增益误差、微分积分线性误差

        2.ADC类型

        (1)并联比较型ADC

        (2)逐次逼近型ADC

二、ADC封装代码

        包括:初始化、配置、读取数据、数据处理。

ADC_HandleTypeDef g_adc_handle;   /* ADC句柄 *//***ADC初始化函数*我们使用16位精度, ADC采样时钟=32M, 转换时间为:采样周期 + 8.5个ADC周期*设置最大采样周期: 810.5, 则转换时间 = 819个ADC周期 = 25.6us*/
void adc_init(void)
{g_adc_handle.Instance = ADC_ADCX;                                               /* 选择哪个ADC */g_adc_handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;                        /* 输入时钟2分频,即adc_ker_ck=per_ck/2=32Mhz */g_adc_handle.Init.Resolution = ADC_RESOLUTION_16B;                              /* 16位模式  */g_adc_handle.Init.ScanConvMode = ADC_SCAN_DISABLE;                              /* 非扫描模式,仅用到一个通道 */g_adc_handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;                           /* 关闭EOC中断 */g_adc_handle.Init.LowPowerAutoWait = DISABLE;                                   /* 自动低功耗关闭 */g_adc_handle.Init.ContinuousConvMode = DISABLE;                                 /* 关闭连续转换模式 */g_adc_handle.Init.NbrOfConversion = 1;                                          /* 赋值范围是1~16,本实验用到1个常规通道 */g_adc_handle.Init.DiscontinuousConvMode = DISABLE;                              /* 禁止常规转换组不连续采样模式 */g_adc_handle.Init.NbrOfDiscConversion = 0;                                      /* 配置不连续采样模式的通道数,禁止常规转换组不连续采样模式后,此参数忽略 */g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;                        /* 软件触发 */g_adc_handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;         /* 采用软件触发的话,此位忽略 */g_adc_handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;             /* 常规通道的数据仅仅保存在DR寄存器里面 */g_adc_handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;                           /* 有新的数据后直接覆盖掉旧数据 */g_adc_handle.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;                         /* 设置ADC转换结果的左移位数 */g_adc_handle.Init.OversamplingMode = DISABLE;                                   /* 关闭过采样 */HAL_ADC_Init(&g_adc_handle);                                                    /* 初始化 */HAL_ADCEx_Calibration_Start(&g_adc_handle, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED); /* ADC校准 */
}/*** @brief       ADC底层驱动,引脚配置,时钟使能此函数会被HAL_ADC_Init()调用* @param       hadc:ADC句柄* @retval      无*/
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{if(hadc->Instance == ADC_ADCX){GPIO_InitTypeDef gpio_init_struct;ADC_ADCX_CHY_CLK_ENABLE();                      /* 使能ADC1/2时钟 */ADC_ADCX_CHY_GPIO_CLK_ENABLE();                 /* 开启ADC通道IO引脚时钟 */__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);    /* ADC外设时钟选择 */gpio_init_struct.Pin = ADC_ADCX_CHY_GPIO_PIN;   /* ADC通道IO引脚 */gpio_init_struct.Mode = GPIO_MODE_ANALOG;       /* 模拟 */HAL_GPIO_Init(ADC_ADCX_CHY_GPIO_PORT, &gpio_init_struct);}
}/*** @brief       获得ADC转换后的结果 * @param       ch: 通道值 0~19,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_19* @retval      返回值:转换结果*/
uint32_t adc_get_result(uint32_t ch)
{ADC_ChannelConfTypeDef adc_ch_conf = {0};adc_ch_conf.Channel = ch;                              /* 通道 */adc_ch_conf.Rank = ADC_REGULAR_RANK_1;                 /* 序列 */adc_ch_conf.SamplingTime = ADC_SAMPLETIME_810CYCLES_5; /* 采样时间,设置最大采样周期: 810.5个ADC周期 */adc_ch_conf.SingleDiff = ADC_SINGLE_ENDED;             /* 单边采集 */adc_ch_conf.OffsetNumber = ADC_OFFSET_NONE;            /* 不使用偏移量的通道 */adc_ch_conf.Offset = 0;                                /* 偏移量为0 */HAL_ADC_ConfigChannel(&g_adc_handle, &adc_ch_conf);    /* 通道配置 */HAL_ADC_Start(&g_adc_handle);                          /* 开启ADC */HAL_ADC_PollForConversion(&g_adc_handle, 10);          /* 轮询转换 */return HAL_ADC_GetValue(&g_adc_handle);                /* 返回最近一次ADC1常规组的转换结果 */
}/*** @brief       获取通道ch的转换值,取times次,然后平均* @param       ch      : 通道号, 0~19* @param       times   : 获取次数* @retval      通道ch的times次转换结果平均值*/
uint32_t adc_get_result_average(uint32_t ch, uint8_t times)
{uint32_t temp_val = 0;uint8_t t;for (t = 0; t < times; t++) /* 获取times次数据 */{temp_val += adc_get_result(ch);delay_ms(5);}return temp_val / times;    /* 返回平均值 */
}

三、ADC运用(重点)

        STM32H750 系列有 3 个 ADC, 都可以独立工作,其中 ADC1 和 ADC2 还可以组成双重模式(提高采样率)。 STM32H750 的 ADC 分辨率高达 16 位,每个 ADC 具有多达 20 个的采集通道,这些通道的 A/D 转换可以单次、连续、扫描或间断模式执行。 ADC的结果可以左对齐或右对齐方式存储在 32 位数据寄存器中。STM32H750 的 ADC 最大的转换速率为 4.5Mhz,也就是转换时间为 0.22us(12 位分辨率时),不要让 ADC 的时钟超过 36M,否则将导致结果准确度下降。(STM32F1系列:ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生)

        1.ADC_DMA封装函数 
//ADC_DMA.c
uint16_t dma_i;
uint16_t adc1_val_buf[ADC1_CHANNEL_CNT*ADC1_CHANNEL_FRE]; //传递给DMA存放多通道采样值的数组
uint32_t adc1_aver_val[ADC1_CHANNEL_CNT] = {0}; //计算多通道的平均采样值的过程数组
uint16_t value[ADC1_CHANNEL_CNT] = {0};//多通道的平均采样值的数组
uint16_t value_max[ADC1_CHANNEL_CNT] = {0};void ADC_Sample_Start(){if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&adc1_val_buf, (ADC1_CHANNEL_CNT * ADC1_CHANNEL_FRE)) != HAL_OK){Error_Handler(); }
}void ADC_Process(){//处理DMA数据for(dma_i = 0; dma_i < ADC1_CHANNEL_CNT; dma_i++){adc1_aver_val[dma_i] = 0;}/* 在采样值数组中分别取出每个通道的采样值并求和 */for(dma_i = 0; dma_i < ADC1_CHANNEL_FRE; dma_i++){adc1_aver_val[0] +=  adc1_val_buf[dma_i*ADC1_CHANNEL_CNT+0];adc1_aver_val[1] +=  adc1_val_buf[dma_i*ADC1_CHANNEL_CNT+1];adc1_aver_val[2] +=  adc1_val_buf[dma_i*ADC1_CHANNEL_CNT+2];}/* 依次对每个通道采样值求平均值 */for(dma_i = 0; dma_i < ADC1_CHANNEL_CNT; dma_i++){value[dma_i] = adc1_aver_val[dma_i] / ADC1_CHANNEL_FRE;}}
// ADC_DMA.c#include "main.h"
#include "adc.h"//ADC DMA传输
#define ADC1_CHANNEL_CNT 4 	//采样通道数
#define ADC1_CHANNEL_FRE 5	//单个通道采样次数,用来取平均值
extern uint16_t adc1_val_buf[ADC1_CHANNEL_CNT*ADC1_CHANNEL_FRE];
extern uint32_t adc1_aver_val[ADC1_CHANNEL_CNT]; //计算多通道的平均采样值的过程数组
extern uint16_t value[ADC1_CHANNEL_CNT];
extern uint16_t dma_i;void ADC_Sample_Start();
void ADC_Process();
        2.ADC常用函数HAL库
//DAC常用函数
HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel);     //开启DAC输出
HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel);   //关闭DAC输出
HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment); //需要函数中不断开启,开启DAC的DMA输出
HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel); //关闭DAC的DMA输出
HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data);  //设置DAC输出值
HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel);  //获取DAC输出值

四、DAC知识点

        STM32H750 的 DAC 模块( 数字/模拟转换模块) 是 12 位数字输入,电压输出型的 DAC。DAC 可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。 DAC 工作在 12 位模式时,数据可以设置成左对齐或右对齐。 DAC 模块有 2 个输出通道,每个通道都有单独的转换器。在双 DAC 模式下, 2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个通道的输出。 DAC 可以通过引脚输入参考电压 Vref+(通 ADC 共用) 以获得更精确的转换结果。

        PWM--DAC原理

        PWM(Pulse Width Modulation,脉冲宽度调制)DAC技术是一种利用PWM信号模拟输出连续变化电压或电流的技术。在PWM中,信号是一个周期固定的方波,其特点是占空比(高电平持续时间相对于整个周期的比例)是可以调节的。对于一个PWM信号来说,理论上它可以被看作是由一个不变的直流分量和一系列不同频率的交流分量组成,其中直流分量对应于PWM信号的平均值,而其他交流分量则随着占空比的变化而包含不同的谐波成分。

        在PWM DAC应用中,通过改变PWM信号的占空比来模拟不同的电压等级。由于PWM本身是数字信号,要将其转换为模拟信号,就需要通过一个低通滤波器来滤除高频的PWM方波分量,保留并平滑其直流分量。这样一来,随着PWM占空比的改变,经过滤波后的输出信号就变成了一个连续变化且与占空比成比例的模拟电压或电流信号。

        因此,PWM DAC是一种经济高效的数模转换方案,尤其适用于嵌入式系统和其他对成本、功耗或集成度有较高要求的应用场合,但由于受到滤波器性能的限制,其输出模拟信号的质量(如分辨率、线性度、噪声和失真)相较于专用的高精度DAC可能较低。为了提高PWM DAC的输出精度,可以通过增加PWM位数(提高分辨率)、优化滤波器设计以及采用多个PWM通道并行合成更高级别的DAC等方式来改善性能。


// 定义全局PWM-DAC定时器通道句柄
TIM_HandleTypeDef g_timx_pwm_chy_handle;// PWM DAC初始化函数
// 该函数用于初始化TIM1定时器,使其产生PWM信号用于控制DAC输出电压
void pwmdac_init(uint16_t arr, uint16_t psc)
{// 初始化定时器通道PWM配置结构体TIM_OC_InitTypeDef timx_oc_pwm_chy = {0};// 设置定时器实例为TIM1g_timx_pwm_chy_handle.Instance = TIM1;// 配置TIM1的基本参数,包括预分频psc和自动重载值arrg_timx_pwm_chy_handle.Init.Prescaler = psc;g_timx_pwm_chy_handle.Init.Period = arr;g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数模式g_timx_pwm_chy_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; // 自动重装载使能// 初始化TIM1定时器PWM模式HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle);// 配置TIM1通道1为PWM模式1timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1;timx_oc_pwm_chy.Pulse = 0; // 初始脉宽设置为0timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_HIGH; // PWM极性为高电平有效HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle, &timx_oc_pwm_chy, TIM_CHANNEL_1); // 配置TIM1通道1// 启动TIM1通道1的PWM输出HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, TIM_CHANNEL_1);
}// TIM MSP初始化函数
// 该函数主要用于初始化TIM1相关的GPIO,使其可以与TIM1通道相配合工作
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM1){GPIO_InitTypeDef gpio_init_struct;// 使能GPIOA和TIM1时钟__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_TIM1_CLK_ENABLE();// 配置TIM1通道1对应的GPIOA Pin 8gpio_init_struct.Pin = GPIO_PIN_8;gpio_init_struct.Mode = GPIO_MODE_AF_PP; // 设置为推挽复用输出模式gpio_init_struct.Pull = GPIO_PULLUP; // 上拉使能,防止悬空gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速输出HAL_GPIO_Init(GPIOA, &gpio_init_struct); // 初始化GPIOA Pin 8}
}// 设置PWM DAC输出电压函数
// 该函数接收一个电压值vol(单位毫伏),并根据该值调整TIM1通道1的PWM占空比以改变DAC输出电压
void pwmdac_set_voltage(uint16_t vol)
{// 将输入电压值从毫伏转换为与TIM1比较寄存器匹配的比例值float temp = vol;temp /= 1000; // 单位转换为伏特temp = temp * 256 / 3.3; // 将电压值映射到0-256区间,假设DAC参考电压为3.3V// 设置TIM1通道1的比较寄存器(即PWM占空比)__HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, TIM_CHANNEL_1, temp);
}

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

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

相关文章

Blender进阶:着色器节点

11 着色器节点 11.1着色器 着色器Shader&#xff0c;负责给物体表面着色。 综合以下参数&#xff1a; -基础色-金属度、粗超度、透明度-法向-入射光颜色、强度、角度。。 着色器本质上是一段程序、算法&#xff0c;即着色器编程。 在节点编辑器中&#xff0c;支持算法的可…

SQLark百灵连接——整合项目监控过程

关键词&#xff1a;SQL编写、数据查询、数据导入、达梦数据库、项目管理、信息透明 项目监控背景 作为新手项目经理的我&#xff0c;经常觉得哪儿哪儿都是问题&#xff0c;今天催这个&#xff0c;明天推那个&#xff0c;可就是什么事都推不动&#xff0c;谁都不配合。后来&…

ELK配置转存redis缓存,采集nginx访问日志

在136服务器上部署mysql 启动mysql服务 可通过以下命令查找安装的软件包 怎么查找安装软件的日志文件位置rpm -qc mysql-server&#xff0c;即可显示mysql.log位置 也可通过查找配置文件中的log关键字来查找log文件日志位置 用awk命令&#xff0c;以切割&#xff0c;输出第二个…

提升当当网数据爬取效率:代理IP并发抓取技术

在当今的互联网时代&#xff0c;数据已成为企业竞争的关键资源。爬虫技术作为获取网络数据的重要手段&#xff0c;其应用范围越来越广泛。然而&#xff0c;随着各大网站反爬虫机制的不断加强&#xff0c;爬虫面临着越来越多的挑战。其中&#xff0c;IP被封禁是最常见的问题之一…

基于微信小程序的图书馆座位预约系统+LW示例参考

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

学习笔记:ElasticSearch搜索引擎

学习视频&#xff1a;【尚硅谷】ElasticSearch教程入门到精通&#xff08;基于ELK技术栈elasticsearch 7.x8.x新特性&#xff09; 学习笔记&#xff1a;Elasticsearch学习笔记 目录 第1章 Elasticsearch概述01. 开篇02. 技术选型 2. 第二章 ElasticSearch入门03. 环境准备04. …

Vue Router进阶详解

导航守卫 若依框架登录鉴权详解&#xff08;动态路由&#xff09;_若依鉴权-CSDN博客 完整的导航解析流程 导航被触发&#xff1a; 当用户点击页面中的链接、使用编程式导航&#xff08;如router.push或router.replace&#xff09;或手动输入URL时&#xff0c;导航流程被触发。…

力扣排序242题 有效的子母异位词

题目&#xff1a; 242.有效的字母异位词 给定两个字符串s和t &#xff0c;编写一个函数来判断 t是否是s的字母异位词。 示例1: 输入: s "anagram", t "nagaram" 输出: true 解题思路&#xff1a; 要判断两个字符串s和t是否为子母异位词&#xff0c;也…

html简易流程图

效果图 使用htmlcssjs&#xff0c;无图片&#xff0c;没用Canvas demo: <!DOCTYPE html> <html> <head><link href"draw.css" rel"stylesheet" /><script src"draw.js" type"text/javascript"></…

51单片机教程(一)- 开发环境搭建

1、开发环境搭建 1 环境准备 1 单片机介绍 单片机&#xff08;Single-Chip Microcomputer&#xff0c;简称MCU&#xff09;是一种集成电路芯片&#xff0c;是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、…

【1个月速成Java】基于Android平台开发个人记账app学习日记——第3天,分析项目结构

24.11.02 1.分析项目初始结构 IDEA有2种查看Android项目模式&#xff0c;一种是原始的projects模式&#xff0c;重点介绍这个模式下的项目结构 Android模式下的项目结构 这个是经过Android处理后的&#xff0c;并不是真正的项目结构&#xff0c;但是看着很简洁 projects模式…

chrome编辑替换js文件的图文教程

一、找到要修改替换的js文件 二、将文件保存到本地 三、在本地新建一个文件 路径最好跟你要替换的文件的路径保持一致&#xff0c; 四、选中js文件替换 回到原文件右击选择保存并覆盖 点击完保存并覆盖之后回到替换的新文件中&#xff0c;在自动生成的webpack文件中对文件进…

大学城水电管理:Spring Boot应用案例

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理大学城水电管理系统的相关信息成为必然。开…

硅谷15菜单权限

菜单权限 15.1 路由的拆分 15.1.1 路由分析 菜单的权限: 超级管理员账号:admin atguigu123 拥有全部的菜单、按钮的权限 飞行员账号 硅谷333 111111 不包含权限管理模块、按钮的权限并非全部按钮 同一个项目&#xff1a;不同人(职位是不一样的,他能访问到的菜单、…

3D Gaussian Splatting代码详解(二):模型构建

3 模型构建 gaussians GaussianModel(dataset.sh_degree) 3.1 初始化函数 __init__ 构造函数 构造函数 __init__ 的主要作用是初始化 3D 高斯模型的各项参数和激活函数&#xff0c;用于生成 3D 空间中的高斯表示。 初始化球谐函数的参数&#xff1a; self.active_sh_degre…

初知C++:继承

文章目录 1. 继承的概念及定义1.1 继承的概念1.2 继承定义1.2.1 定义格式1.2.2 继承基类成员访问方式的变化 2.基类和派生类间的转换3. 继承中的作用域3.1 隐藏规则3.2 考察继承作用域相关选择题 4. 派生类的默认成员函数4.1 4个常见默认成员函数4.2实现一个不能被继承的类 5. …

Java实战项目-基于 SpringBoot+Vue 的医院管理系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

二分,CF 2036 G - Library of Magic

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 G - Library of Magic 二、解题报告 1、思路分析 首先 query(1, n) a ^…

【测试平台】打包 子节点ios环境配置

主要记录如何配置ios打包机环境&#xff0c;ios环境相对来说比较简单的&#xff0c;研发配置好证书可以本地打包&#xff0c;接入流程比较简单了。 打包机系统升级 1.升级mac OS系统 一般升级好几个小时&#xff0c;可以晚上下载好 2.下载xcode并安装 Appstroe 下载安装xco…

矩阵的奇异值分解SVD

为了论述矩阵的奇异值与奇异值分解!需要下面的结论!