DAC实验(DAC 输出三角波实验)(DAC 输出正弦波实验)

news2024/12/24 9:18:46

DAC 输出三角波实验

本实验我们来学习使用如何让 DAC 输出三角波,DAC 初始化部分还是用 DAC 输出实验 的,所以做本实验的前提是先学习 DAC 输出实验。

使用 DAC 输出三角波,通过 KEY0/KEY1 两个按键,控制 DAC1 的通道 1 输出两种三角 波,需要通过示波器接 PA4 进行观察。LED0 闪烁,提示程序运行。

我们只需要把示波器的探头接到 DAC1 通道 1(PA4)引脚,就可以在示波器上显示 DAC 输出的波形。 

#include "./BSP/DAC/dac.h"
#include "./SYSTEM/delay/delay.h"

DAC_HandleTypeDef g_dac_handle;

/* DAC初始化函数 */
void dac_init(void)
{
    DAC_ChannelConfTypeDef dac_ch_conf = {0};
    
    g_dac_handle.Instance = DAC;
    HAL_DAC_Init(&g_dac_handle);/* 初始化 DAC */
    
    dac_ch_conf.DAC_Trigger = DAC_TRIGGER_NONE;/* 不使用触发功能,(自动模式) */
    dac_ch_conf.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;/* DAC1 输出缓冲关闭 */
    HAL_DAC_ConfigChannel(&g_dac_handle, &dac_ch_conf, DAC_CHANNEL_1);
    
    HAL_DAC_Start(&g_dac_handle, DAC_CHANNEL_1);/* 开启 DAC 通道 1 */
}

/* DAC MSP底层初始化函数 */
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{
    if(hdac->Instance == DAC)
    {
        GPIO_InitTypeDef gpio_init_struct = {0};
        
        __HAL_RCC_DAC_CLK_ENABLE();/* 使能 DAC1 的时钟 */
        __HAL_RCC_GPIOA_CLK_ENABLE();;/* 使能 DAC OUT1/2 的 IO 口时钟(都在 PA 口,PA4/PA5) */
        
        gpio_init_struct.Pin = GPIO_PIN_4;
        gpio_init_struct.Mode = GPIO_MODE_ANALOG;
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);
    }
}

/**
 * @brief       设置DAC_OUT1输出三角波
 *   @note      输出频率 ≈ 1000 / (dt * samples) Khz, 不过在dt较小的时候,比如小于5us时, 由于delay_us
 *              本身就不准了(调用函数,计算等都需要时间,延时很小的时候,这些时间会影响到延时), 频率会偏小.
 * 
 * @param       maxval : 最大值(0 < maxval < 4096), (maxval + 1)必须大于等于samples/2
 * @param       dt     : 每个采样点的延时时间(单位: us)
 * @param       samples: 采样点的个数, samples必须小于等于(maxval + 1) * 2 , 且maxval不能等于0
 * @param       n      : 输出波形个数,0~65535
 *
 * @retval      无
 */
void dac_triangular_wave(uint16_t maxval, uint16_t dt, uint16_t samples, uint16_t n)
{
    uint16_t i, j;
    float incval;                           /* 递增量 */
    float Curval;                           /* 当前值 */
    
    if((maxval + 1) <= samples)return ;     /* 数据不合法 */
        
    incval = (maxval + 1) / (samples / 2);  /* 计算递增量 */
    
    for(j = 0; j < n; j++)
    {
        Curval = 0;
        HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval);    /* 先输出0 */
        for(i = 0; i < (samples / 2); i++)  /* 输出上升沿 */
        {
            Curval  +=  incval;             /* 新的输出值 */
            HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval);
            delay_us(dt);
        }
        for(i = 0; i < (samples / 2); i++)  /* 输出下降沿 */
        {
            Curval  -=  incval;             /* 新的输出值 */
            HAL_DAC_SetValue(&g_dac_handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, Curval);
            delay_us(dt);
        }
    }
}

该函数用于设置 DAC 通道 1 输出三角波,输出频率 ≈ 1000 / (dt * samples) Khz,形参含 义在源码已经有详细注释。该函数中,我们使用 HAL_DAC_SetValue 函数来设置 DAC 的输出 值,这样得到的三角波在示波器上可以看到。如果有跳动现象(不平稳),是正常的,因为调用 函数,计算等都需要时间,这样就会导致输出的波形是不太稳定的。越高性能的 MCU,得到的 波形会越稳定。而且用 HAL 库函数操作效率没有直接操作寄存器高,所以可以像寄存器版本实 验一样,直接操作 DHR12R1 寄存器,得到的波形会相对稳定些。

由于使用 HAL 库的函数,CPU 花费的时间会更长(因为指令变多了),在时间精度要求比 较高的应用,就不适合用 HAL 库函数来操作了,这一点希望大家明白。所以学 STM32 不是说 只要会 HAL 库就可以了,对寄存器也是需要有一定的理解,最好是熟悉。这里用 HAL 库操作 只是为了演示怎么使用 HAL 库的相关函数。

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/ADC/adc.h"
#include "./BSP/DAC/dac.h"
#include "./BSP/KEY/key.h"

int main(void)
{
    uint8_t t = 0; 
    uint8_t key;
    
    HAL_Init();                         /* 初始化 HAL 库 */
    sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    delay_init(72);                     /* 延时初始化 */
    usart_init(115200);                 /* 传口初始化 */
    
    led_init();                         /* LED初始化 */
    lcd_init();                         /* LCD初始化 */
    adc_init();                         /* ADC初始化 */
    dac_init();                         /* DAC初始化 */
    key_init();                         /* KEY初始化 */
    
    lcd_show_string(30,  50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30,  70, 200, 16, 16, "DAC Triangular WAVE TEST", RED);
    lcd_show_string(30,  90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "KEY0:Wave1  KEY1:Wave2", RED);
    lcd_show_string(30, 130, 200, 16, 16, "DAC None", BLUE); /* 提示无输出 */
    
    while(1)
    {
        t++;
        key = key_scan(0);                           /* 按键扫描 */

        if (key == KEY0_PRES)                        /* 高采样率 , 约1Khz波形 */
        {
            lcd_show_string(30, 130, 200, 16, 16, "DAC Wave1 ", BLUE);
            dac_triangular_wave(4095, 5, 2000, 100); /* 幅值4095, 采样点间隔5us, 2000个采样点, 100个波形 */
            lcd_show_string(30, 130, 200, 16, 16, "DAC None  ", BLUE);
        }
        else if (key == KEY1_PRES)                   /* 低采样率 , 约1Khz波形 */
        {
            lcd_show_string(30, 130, 200, 16, 16, "DAC Wave2 ", BLUE);
            dac_triangular_wave(4095, 500, 20, 100); /* 幅值4095, 采样点间隔500us, 20个采样点, 100个波形 */
            lcd_show_string(30, 130, 200, 16, 16, "DAC None  ", BLUE);
        }

        if (t == 10)                                 /* 定时时间到了 */
        {
            LED0_TOGGLE();                           /* LED0闪烁 */
            t = 0;
        }

        delay_ms(10);
    }
}

该部分代码功能是,按下 KEY0 后,DAC 输出三角波 1,按下 KEY1 后,DAC 输出三角波 2,将 dac_triangular_wave 的形参代入公式:输出频率 ≈ 1000 / (dt * samples) KHz,得到三角 波 1 和三角波 2 的频率都是 0.1KHz。

下载代码后,可以看到 LED0 不停的闪烁,提示程序已经在运行了。LCD 显示如图 33.3.4.1 所示:

没有按下任何按键之前,LCD 屏显示 DAC None,当按下 KEY0 后,DAC 输出三角波 1, LCD 屏显示 DAC Wave1 ,三角波 1 输出完成后 LCD 屏继续显示 DAC None,当按下 KEY1后,DAC 输出三角波 2,LCD 屏显示 DAC Wave2,三角波 2 输出完成后 LCD 屏继续显示 DAC None。

其中三角波 1 和三角波 2 在示波器的显示情况如下图所示:

由上面两副测试图可以知道,三角波 1 的频率是 64.5Hz,三角波 2 的频率是 99.5Hz。三角 波 2 基本接近我们算出来的结果 0.1KHz,三角波 1 有较大误差,在介绍 dac_triangular_wave 函 数时也说了原因,加上三角波 1 的采样率比较高,所以误差就会比较大。 

DAC 输出正弦波实验

本实验我们来学习使用如何让 DAC 输出正弦波。实验将用定时器 7 来触发 DAC 进行转换 输出正弦波,以 DMA 传输数据的方式。

使用 DAC 输出正弦波,通过 KEY0/KEY1 两个按键,控制 DAC1 的通道 1 输出两种正弦 波,需要通过示波器接 PA4 进行观察。LED0 闪烁,提示程序运行。

我们只需要把示波器的探头接到 DAC1 通道 1(PA4)引脚,就可以在示波器上显示 DAC 输出的波形。PA4 在 P7 已经引出,硬件连接如图 33.4.2.1 所示:

HAL库函数 

 代码

#include "./BSP/DAC/dac.h"

DMA_HandleTypeDef g_dma_dac_handle;
DAC_HandleTypeDef g_dac_dma_handle;

extern uint16_t g_dac_sin_buf[4096];           /* 发送数据缓冲区 */

/* DAC DMA输出波形初始化函数 */
void dac_dma_wave_init(void)
{
    DAC_ChannelConfTypeDef dac_ch_conf = {0};
    
    __HAL_RCC_DMA2_CLK_ENABLE();/* DMA2 时钟使能 */
    
    g_dma_dac_handle.Instance = DMA2_Channel3;/* 设置 DMA 通道 */
    g_dma_dac_handle.Init.Direction = DMA_MEMORY_TO_PERIPH;/* 从存储器到外设模式 */
    g_dma_dac_handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;/* 存储器数据长度:16 位 */
    g_dma_dac_handle.Init.MemInc = DMA_MINC_ENABLE;/* 存储器增量模式 */
    g_dma_dac_handle.Init.Mode = DMA_CIRCULAR;/* 循环模式 */
    g_dma_dac_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;/* 外设数据长度:16 位 */
    g_dma_dac_handle.Init.PeriphInc = DMA_PINC_DISABLE;/* 外设非增量模式 */
    g_dma_dac_handle.Init.Priority = DMA_PRIORITY_HIGH;/* 优先级 */
    HAL_DMA_Init(&g_dma_dac_handle);/* 初始化 DMA */
    
    __HAL_LINKDMA(&g_dac_dma_handle, DMA_Handle1, g_dma_dac_handle);/* DMA 句柄与 DAC 句柄关联 */
    
    g_dac_dma_handle.Instance = DAC;
    HAL_DAC_Init(&g_dac_dma_handle);
    
    dac_ch_conf.DAC_Trigger = DAC_TRIGGER_T7_TRGO;/* 使用 TIM7 TRGO 事件触发 */
    dac_ch_conf.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;/* DAC1 输出缓冲关闭 */
    HAL_DAC_ConfigChannel(&g_dac_dma_handle, &dac_ch_conf, DAC_CHANNEL_1);/* DAC 通道 1 配置 */
    
    /* 配置 DMA 传输参数 */
    HAL_DMA_Start(&g_dma_dac_handle, (uint32_t)g_dac_sin_buf, (uint32_t)&DAC->DHR12R1, 0);
}

/* DAC MSP底层初始化函数 */
void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{
    if(hdac->Instance == DAC)
    {
        GPIO_InitTypeDef gpio_init_struct = {0};
        
        __HAL_RCC_DAC_CLK_ENABLE();/* 使能 DAC1 的时钟 */
        __HAL_RCC_GPIOA_CLK_ENABLE();/* DAC 通道引脚端口时钟使能 */
        
        /* STM32 单片机, 总是 PA4=DAC1_OUT1, PA5=DAC1_OUT2 */
        gpio_init_struct.Pin = GPIO_PIN_4;
        gpio_init_struct.Mode = GPIO_MODE_ANALOG;/* 模拟 */
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);
    }
}

void dac_dma_wave_enable(uint16_t cndtr, uint16_t arr, uint16_t psc)
{
    TIM_HandleTypeDef tim7_handle = {0};
    TIM_MasterConfigTypeDef tim7_master_config = {0};
    
    __HAL_RCC_TIM7_CLK_ENABLE();/* TIM7 时钟使能 */
    
    tim7_handle.Instance = TIM7;/* 选择定时器 7 */
    tim7_handle.Init.Prescaler = psc;/* 预分频 */
    tim7_handle.Init.Period = arr;/* 自动装载值 */
    tim7_handle.Init.CounterMode = TIM_COUNTERMODE_UP; /* 递增计数器 */
    HAL_TIM_Base_Init(&tim7_handle);
    
    tim7_master_config.MasterOutputTrigger = TIM_TRGO_UPDATE;/* 定时器更新事件用于触发 */
    tim7_master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    HAL_TIMEx_MasterConfigSynchronization(&tim7_handle, &tim7_master_config);/* 配置定时器 7 的更新事件触发 DAC 转换 */
    
    HAL_TIM_Base_Start(&tim7_handle);/* 启动定时器 7 */
    
    HAL_DAC_Stop_DMA(&g_dac_dma_handle, DAC_CHANNEL_1);/* 先停止之前的传输 */
    HAL_DAC_Start_DMA(&g_dac_dma_handle, DAC_CHANNEL_1, (uint32_t *)g_dac_sin_buf, cndtr, DAC_ALIGN_12B_R);
}

该函数用于初始化 DAC 用 DMA 的方式输出正弦波。本函数用到的 API 函数起前面都介 绍过,请结合前面介绍过的相关内容来理解源码。这里值得注意的是我们是采用定时器 7 触发 DAC 进行转换输出的。

该函数用于使能波形输出,利用定时器 7 的更新事件来触发 DAC 转换输出。使能定时器 7 的时钟后,调用 HAL_TIMEx_MasterConfigSynchronization 函数配置 TIM7 选择更新事件作为触 发输出 (TRGO),然后调用 HAL_DAC_Stop_DMA 函数停止 DAC 转换以及 DMA 传输,最后 再调用 HAL_DAC_Start_DMA 函数重新配置并启动 DAC 和 DMA。

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/ADC/adc.h"
#include "./BSP/DAC/dac.h"
#include "./BSP/KEY/key.h"
#include "math.h"

uint16_t g_dac_sin_buf[4096];           /* 发送数据缓冲区 */

/**
 * @brief       产生正弦波函序列
 *   @note      需保证: maxval > samples/2
 *
 * @param       maxval : 最大值(0 < maxval < 2048)
 * @param       samples: 采样点的个数
 *
 * @retval      无
 */
void dac_creat_sin_buf(uint16_t maxval, uint16_t samples)
{
    uint8_t i;
    float inc = (2 * 3.1415962) / samples; /* 计算增量(一个周期DAC_SIN_BUF个点)*/
    float outdata = 0;

    for (i = 0; i < samples; i++)
    {
        outdata = maxval * (1 + sin(inc * i)); /* 计算以dots个点为周期的每个点的值,放大maxval倍,并偏移到正数区域 */
        if (outdata > 4095)
            outdata = 4095; /* 上限限定 */
        //printf("%f\r\n",outdata);
        g_dac_sin_buf[i] = outdata;
    }
}

int main(void)
{
    uint8_t t = 0; 
    uint8_t key;
    
    HAL_Init();                         /* 初始化 HAL 库 */
    sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    delay_init(72);                     /* 延时初始化 */
    usart_init(115200);                 /* 传口初始化 */
    
    led_init();                         /* LED初始化 */
    lcd_init();                         /* LCD初始化 */
    key_init();                         /* KEY初始化 */
    
    /* 初始化DAC通道1 DMA波形输出 */
    dac_dma_wave_init();
    
    lcd_show_string(30,  50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30,  70, 200, 16, 16, "DAC DMA Sine WAVE TEST", RED);
    lcd_show_string(30,  90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "KEY0:3Khz  KEY1:30Khz", RED);
    
    dac_creat_sin_buf(2048, 100);
    dac_dma_wave_enable(100, 10 - 1, 72 - 1);/* 100Khz触发频率, 100个点, 得到1Khz的正弦波 */
    
    while(1)
    {
        t++;
        key = key_scan(0);                           /* 按键扫描 */
        
        if (key == KEY0_PRES)                               /* 高采样率 , 约1Khz波形 */
        {
            dac_creat_sin_buf(2048, 100);
            dac_dma_wave_enable(100, 10 - 1, 24 - 1);       /* 300Khz触发频率, 100个点, 得到最高3KHz的正弦波. */
        }
        else if (key == KEY1_PRES)                          /* 低采样率 , 约1Khz波形 */
        {
            dac_creat_sin_buf(2048, 10);
            dac_dma_wave_enable(10, 10 - 1, 24 - 1);        /* 300Khz触发频率, 10个点, 可以得到最高30KHz的正弦波. */
        }

        if (t == 40)        /* 定时时间到了 */
        {
            LED0_TOGGLE();  /* LED0闪烁 */
            t = 0;
        }
        delay_ms(5);
    }
}

dac_dma_wave_init 函数初始化 DAC 通道 1,并指定 DMA 搬运的数据的开始地址和目标 地址。dac_creat_sin_buf 函数用于产生正弦波序列,并保存在 g_dac_sin_buf 数组中,供给 DAC 转换。在进入wilhe(1)循环之前,dac_dma_wave_enable函数默认配置DAC的采样点个数时100, 并配置定时器 7 的溢出频率为 100KHz。这样就可以输出 1KHz 的正弦波。下面给大家解释一下 为什么是输出 1KHz 的正弦波?

定时器 7 的溢出频率为 100KHz,不记得怎么计算的朋友,请回顾基本定时器的相关内容, 这里直接把公式列出:Tout= ((arr+1)*(psc+1))/Tclk

看到 dac_dma_wave_enable(100, 10 - 1, 72 - 1);这个语句,第二个形参是自动重装载值,第 三个形参是分频系数,那么代入公式,可得:Tout= ((arr+1)*(psc+1))/Tclk= ((9+1)*(71+1))/ 72000000= 0.00001s得到定时器的更新事件周期是 0.00001 秒,即更新事件频率为 100KHz,也就得到 DAC 输 出触发频率为 100KHz。再结合总一个正弦波共有 100 个采样点,就可以得到正弦波的频率为 100KHz/100 = 1KHz。

知道了正弦波的频率怎么来的,下面代码中,按下按键 KEY0,得到 3KHz 的正弦波,按下 按键 KEY1,得到 30KHz 的正弦波,计算方法都一样的。

实验现象

没有按下任何按键之前,默认输出 1KHz(100 个采样点)的正弦波,如下图所示:

当按下 KEY0 后,DAC 输出 3KHz(100 个采样点)的正弦波,如下图所示: 当按下 KEY1 后,DAC 输出 30KHz(10 个采样点)的正弦波,如下图所示:

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

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

相关文章

Educational Codeforces Round 20 A-E

文章目录 A. Maximal Binary MatrixB. Distances to ZeroC. Maximal GCDD. Magazine AdE. Roma and Poker A. Maximal Binary Matrix 思路&#xff1a;一道很有意思的构造&#xff0c;我们可以发现&#xff0c;按照下述&#xff0c;从外到内进行一层一层的构造一定是最优的。 …

计算机网络———ipv6简解

文章目录 1.前言&#xff1a;2. ipv6简单分析&#xff1a;2.1.地址长度对比2.2. ipv6包头分析2.3. ipv6地址的压缩表示&#xff1a;2.3. NDP&#xff1a;2.4. ipv6地址动态分配&#xff1a; 1.前言&#xff1a; 因特网地址分配组织)宣布将其最2011年2月3日&#xff0c;IANA (In…

LeetCode(25)验证回文串【双指针】【简单】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 验证回文串 1.题目 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&…

Django 配置 Email Admin 详细指南

概要 Django 是一个高级的 Python Web 框架&#xff0c;它鼓励快速开发和清洁、实用的设计。当你正在开发一个 Django 项目时&#xff0c;监控网站的运行情况是非常必要的。Django 提供了一个功能强大的 admin 界面&#xff0c;但同时也可以通过配置 email admin 来获取网站的…

how to find gcc openbug

https://gcc.gnu.org/bugzilla/query.cgi?formatadvanced

决策树,sql考题,30个经典sql题目

大数据&#xff1a; 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其sql要学&#x…

C++初阶 | [三] 类和对象(中)

摘要&#xff1a;类的6个默认成员函数&#xff0c;日期类 如果一个类中什么成员都没有&#xff0c;简称为空类。然而&#xff0c;空类并不是什么成员都没有&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成6个默认成员函数。默认成员函数&#xff1a;用户没有显式…

【云原生-Kurbernetes篇】K8s的存储卷/数据卷+PV与PVC

这是一个目录标题 一、Kurbernetes中的存储卷1.1 为什么需要存储卷&#xff1f;1.2 存储卷概述1.2.1 简介1.2.2 volume字段 1.3 常用的存储卷类型1.3.1 emptyDir&#xff08;临时存储卷&#xff09;1.3.2 hostPath&#xff08;节点存储卷&#xff09;1.3.3 nfs1.3.4 cephfs 二、…

为React Ant-Design Table增加字段设置 | 京东云技术团队

最近做的几个项目经常遇到这样的需求&#xff0c;要在表格上增加一个自定义表格字段设置的功能。就是用户可以自己控制那些列需要展示。 在几个项目里都实现了一遍&#xff0c;每个项目的需求又都有点儿不一样&#xff0c;迭代了很多版&#xff0c;所以抽时间把这个功能封装了…

用script去做前端html表格分页/排序

前言: 掘弃掉与后端交互做分页和互导,有利有弊吧; 在小数据的时候,如果不停来回朝服务端发送请求,会造成堵塞.于是,放弃了之前的前后端ajax方式去请求分页表格,使用script去弄一个,降低服务器的压力; 整体思路图: 代码构造: {% extends "order_header_same.html" …

​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第9章 软件可靠性基础知识&#xff08;P320~344&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

什么是美国服务器,有哪些优势,适用于什么场景?

​  在互联网发展的过程中&#xff0c;服务器扮演着至关重要的角色。而美国作为全球信息技术的中心&#xff0c;其服务器在全球范围内受到广泛关注。  美国服务器是指在美国本土机房搭建并运行的服务器。其拥有带宽大、优质硬件、售后运维好、位置优越、数据安全性高以及免备…

C/C++输出整数部分 2021年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C输出整数部分 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C输出整数部分 2021年12月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 输入一个双精度浮点数f&#xff0c; 输出其整…

MapApp 地图应用

1. 简述 1.1 重点 1&#xff09;更好地理解 MVVM 架构 2&#xff09;更轻松地使用 SwiftUI 框架、对齐、动画和转换 1.2 资源下载地址: Swiftful-Thinking:https://www.swiftful-thinking.com/downloads 1.3 项目结构图: 1.4 图片、颜色资源文件图: 1.5 启动图片配置图: 2. Mo…

腾讯云服务器多少钱一年?腾讯云服务器88元一年,附优惠购买入口

腾讯云服务器可以以低至88元一年的价格购买&#xff01;这个价格可以说是非常实惠。现在&#xff0c;让我们一起来了解腾讯云服务器的价格以及如何购买优惠的服务器。 如何购买88元一年的腾讯云服务器&#xff1f; 购买腾讯云服务器非常简单&#xff0c;只需按照以下步骤&…

SpringBoot实现IP地址归属地查询

SpringBoot实现IP地址归属地查询 功能特性 标准化的数据格式 每个 IP 数据段的 region 信息都固定了格式&#xff1a; 国家|区域|省份|城市|ISP&#xff0c;只有中国的数据绝大部分精确到了城市&#xff0c;其他国家部分数据只能定位到国家&#xff0c;后前的选项全部是 0。…

聊一聊前端面临的安全威胁与解决对策

前端是用户在使用您的网站或Web应用程序时首先体验到的东西。如果您的Web应用程序的前端受到侵害&#xff0c;它可能会影响整个布局&#xff0c;并造成糟糕的用户体验&#xff0c;可能难以恢复。集成前端安全变得越来越重要&#xff0c;本文将指导您通过可以应用于保护您的Web应…

基于SSM的教学管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

腾讯云服务器价格表查询,腾讯云服务器怎么买便宜?

你是否需要搭建一个属于自己的网站&#xff0c;但是又不知道该如何选择和购买服务器&#xff1f;腾讯云服务器价格表查询&#xff0c;让你轻松了解各款服务器的价格及配置信息&#xff0c;帮助你选择最合适的服务器。同时&#xff0c;我们还为你提供了腾讯云服务器的优惠购买入…

利用jquery对HTML中的名字进行替代

想法&#xff1a;将网页中经常要修改的名字放在一个以jquery编写的js文件中&#xff0c;如果需要修改名字&#xff0c;直接修改js文件中的名字即可。 新建name_07.html文件&#xff0c;写入下面的代码&#xff1a; <!DOCTYPE html> <html> <head><meta …