32单片机从入门到精通之硬件架构——时钟树配置(三)

最近很喜欢的一段句子:每个年龄段都有每个年龄段的压力 ,每个阶段都有每个阶段的烦恼。希望我们都能顶住生活的压力, 慢慢提升自己,好好生活。
我知道你最近很累,但是请你一定要坚持下去, 千万不要太着急 ,学会调节好情绪慢慢来想要的 ,岁月都会给 ,就算无人问津也好,技不如人也罢, 千万别让烦恼和焦虑毁了你本就不多的热情和定力。
定好目标给自己一点时间沉淀 努力成为更好的人 你一定可以!

目录

上一篇博客试卷讲解

一、选择题(每题2分,共10分)

二、简答题(每题10分,共30分)

三、填空题(每题2分,共10分)

四、编程题(每题20分,共40分)

五、应用设计题(每题15分,共15分)

时钟树配置详解

1. 系统时钟源选择

2. 使用PLL (Phase-Locked Loop) 倍频基础时钟频率

3. 配置步骤示例 (以STM32F4系列为例)

4. 注意事项

试卷

一、选择题(每题2分,共10分)

二、简答题(每题10分,共30分)

三、填空题(每题2分,共10分)

四、编程题(每题20分,共40分)

五、应用设计题(每题15分,共15分)


上一篇博客试卷讲解

一、选择题(每题2分,共10分)

  1. AHB主要用于连接哪种类型的设备?

  2. A) 低速外围设备
  3. B) 中速外围设备
  4. C) 高速设备 (正确答案)
  5. D) 内存映射外设
  6. APB1和APB2的主要区别在于什么?

  7. A) 数据宽度
  8. B) 工作频率 (正确答案)
  9. C) 支持的外设类型
  10. D) DMA支持
  11. DMA控制器允许数据在内存和其他外设之间直接传输,这减轻了哪个组件的负担?

  12. A) 外围设备
  13. B) 存储器
  14. C) CPU (正确答案)
  15. D) 总线矩阵
  16. STM32中,用于连接传感器、EEPROM等外围设备的两线制同步串行总线称为?

  17. A) SPI
  18. B) UART
  19. C) I²C (正确答案)
  20. D) CAN
  21. 下列哪项不是DMA的特点?

  22. A) 后台数据传输
  23. B) 需要CPU干预
  24. C) 内置中断机制
  25. D) 提高系统吞吐量 (正确答案为B)
二、简答题(每题10分,共30分)
  1. 简要描述AHB (Advanced High-performance Bus) 的特点及其应用场景。

  2. 解释什么是DMA (Direct Memory Access),以及它在STM32中的作用。

  3. 请简要说明APB1和APB2的主要用途,并举例说明它们分别连接哪些类型的外围设备。

三、填空题(每题2分,共10分)
  1. STM32系列单片机基于______架构,支持多种低功耗模式,如睡眠、停止和待机。 (ARM Cortex-M)

  2. AHB总线的数据宽度通常为______位或______位。 (32, 64)

  3. DMA可以配置多种传输模式,如单次传输、块传输和______。 (循环传输)

  4. APB1主要用于连接______速度的外围设备,如定时器、UART、SPI、I²C等。 (低速)

  5. DMA控制器通过内置的______机制,在传输完成时通知CPU。 (中断)

四、编程题(每题20分,共40分)
  1. 使用STM32 HAL库编写一段代码,初始化AHB总线上的一个外设(例如,启用GPIOA时钟),并简要注释代码功能。
#include "stm32f4xx_hal.h"

// 初始化AHB总线上的外设(例如,启用GPIOA时钟)
void AHB_Peripheral_Init(void) {
    // 启用GPIOA时钟,GPIOA位于AHB总线上
    __HAL_RCC_GPIOA_CLK_ENABLE();
}

int main(void) {
    HAL_Init();  // 初始化HAL库

    AHB_Peripheral_Init();  // 初始化AHB总线上的外设

    // 主循环
    while (1) {
        // 用户代码
    }
}
  1. 编写一段代码,配置DMA以从ADC模块读取数据,并将数据存储到指定的内存缓冲区。确保正确配置DMA通道、传输模式和优先级。
#include "stm32f4xx_hal.h"

#define BUFFER_SIZE 10
uint16_t ADC_Buffer[BUFFER_SIZE];

// 初始化DMA并配置ADC进行DMA传输
void DMA_ADC_Init(void) {
    __HAL_RCC_DMA2_CLK_ENABLE();  // 启用DMA2时钟

    // 配置DMA通道
    DMA_HandleTypeDef hdma_adc;
    hdma_adc.Instance = DMA2_Stream0;  // 使用DMA2 Stream0
    hdma_adc.Init.Channel = DMA_CHANNEL_0;
    hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_adc.Init.Mode = DMA_CIRCULAR;  // 循环模式
    hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;

    if (HAL_DMA_Init(&hdma_adc) != HAL_OK) {
        // 错误处理
        Error_Handler();
    }

    // 将DMA流与ADC关联
    __HAL_LINKDMA(&hadc, DMA_Handle, hdma_adc);

    // 配置ADC
    ADC_ChannelConfTypeDef sConfig = {0};
    hadc.Instance = ADC1;
    hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc.Init.Resolution = ADC_RESOLUTION_12B;
    hadc.Init.ScanConvMode = DISABLE;
    hadc.Init.ContinuousConvMode = ENABLE;
    hadc.Init.DiscontinuousConvMode = DISABLE;
    hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc.Init.NbrOfConversion = 1;
    hadc.Init.DMAContinuousRequests = ENABLE;
    hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

    if (HAL_ADC_Init(&hadc) != HAL_OK) {
        // 错误处理
        Error_Handler();
    }

    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
    if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
        // 错误处理
        Error_Handler();
    }

    // 开始DMA传输
    HAL_ADC_Start_DMA(&hadc, (uint32_t*)ADC_Buffer, BUFFER_SIZE);
}

int main(void) {
    HAL_Init();  // 初始化HAL库

    DMA_ADC_Init();  // 初始化DMA并配置ADC

    // 主循环
    while (1) {
        // 用户代码
    }
}

void Error_Handler(void) {
    // 错误处理代码
    while (1) {
        // 停留在这里
    }
}
五、应用设计题(每题15分,共15分)
  1. 设计一个基于STM32的智能环境监控系统,包括温度、湿度、光照强度等参数的监测。详细描述硬件选型、软件架构及数据上传方案。考虑如何通过Wi-Fi模块将数据发送到云端服务器。
  • 硬件选型

  • MCU:STM32F4系列,具备足够的处理能力和丰富的外设资源。
  • 传感器:DHT22(温湿度)、BH1750(光照强度)。
  • Wi-Fi模块:ESP8266或ESP32,提供Wi-Fi连接能力。
  • 电源管理:LDO稳压器,确保稳定供电。
  • 通信接口:UART用于与Wi-Fi模块通信。
  • 软件架构

  • 主控程序:负责初始化和调度各个任务,如定时采集传感器数据、处理Wi-Fi连接等。
  • 传感器驱动:实现对各类型传感器的初始化和数据读取。
  • 网络协议栈:使用AT命令集或直接调用ESP8266/ESP32 SDK中的API进行TCP/IP通信。
  • 云平台接口:根据所选云平台(如阿里云IoT、AWS IoT)开发相应的API调用逻辑。
  • 数据上传方案

  • 本地缓存:在STM32内部SRAM或外部Flash中临时保存采集的数据。
  • 定期上传:每隔固定时间间隔(如每分钟)将缓存的数据打包并通过Wi-Fi发送至云端服务器。
  • 异常处理:在网络连接失败时自动重试,保证数据传输的可靠性。
  • 时钟树配置详解

    在嵌入式系统中,特别是基于STM32微控制器的项目里,时钟树配置是至关重要的一步。它决定了系统的运行速度和性能。以下是关于如何配置系统时钟源、使用PLL(锁相环)来倍频基础时钟频率以达到更高工作速度的具体步骤。

    1. 系统时钟源选择

    内部RC振荡器 (HSI)

  • 特点:内置的高速内部RC振荡器,无需外部元件,启动快,但精度较低。
  • 适用场景:适用于对成本敏感的应用或需要快速启动的应用。
  • 外部晶体振荡器 (HSE)

  • 特点:通过外部连接的晶体振荡器提供更精确的时钟源,通常具有更高的稳定性和准确性。
  • 适用场景:适用于对时钟精度要求高的应用,如通信协议、定时任务等。
  • 2. 使用PLL (Phase-Locked Loop) 倍频基础时钟频率

    PLL可以将输入的基础时钟频率进行倍频,从而产生更高的工作频率。这对于提高处理器性能非常有用。配置PLL时,需要注意以下几点:

  • 输入时钟源选择:可以选择HSI、HSE作为PLL的输入时钟源。
  • 倍频系数设置:根据所需的最终输出频率,设置合适的倍频系数(M, N, P, Q, R)。不同的MCU型号可能有不同的配置选项。
  • 分频因子设置:有时需要对PLL输出再进行分频,以适应特定外设的需求。
  • 3. 配置步骤示例 (以STM32F4系列为例)
    #include "stm32f4xx_hal.h"
    
    void SystemClock_Config(void)
    {
        RCC_OscInitTypeDef RCC_OscInitStruct = {0};
        RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
        RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
    
        // 初始化所有使能的外围设备的时钟
        __HAL_RCC_PWR_CLK_ENABLE();
        __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    
        // 配置主振荡器 (HSE/HSI)
        RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
        RCC_OscInitStruct.HSEState = RCC_HSE_ON; // 使用外部8MHz晶体振荡器
        RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
        RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
        RCC_OscInitStruct.PLL.PLLM = 8; // 输入分频因子
        RCC_OscInitStruct.PLL.PLLN = 336; // 倍频因子
        RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // 输出分频因子
        RCC_OscInitStruct.PLL.PLLQ = 7; // USB OTG FS, SDIO, RNG时钟源分频因子
        if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
        {
            Error_Handler();
        }
    
        // 初始化系统时钟
        RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
        RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
        RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
        RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
        RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
    
        if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
        {
            Error_Handler();
        }
    
        // 配置USB OTG FS时钟
        PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CLK48;
        PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL;
        if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
        {
            Error_Handler();
        }
    }
    4. 注意事项
  • 时钟稳定性:确保使用的外部晶体振荡器符合数据手册中的规格要求,以保证时钟的稳定性和可靠性。
  • 电源电压:某些高频率操作可能需要调整VDD核心电压,确保满足MCU的最大工作频率需求。
  • 闪存等待状态:当系统时钟频率较高时,必须适当增加闪存的等待周期数(FLASH Latency),以避免读取错误。
  • 功耗考虑:如果对功耗有严格要求,应权衡时钟频率与功耗之间的关系,选择最合适的配置方案。
  • 试卷

    一、选择题(每题2分,共10分)
    1. 系统时钟源可以选择以下哪两种?

    2. A) 内部RC振荡器 (HSI) 和外部晶体振荡器 (HSE)
    3. B) 外部晶体振荡器 (HSE) 和低速内部RC振荡器 (LSI)
    4. C) 高速外部RC振荡器 (HSER) 和内部晶体振荡器 (ISI)
    5. D) 内部RC振荡器 (HSI) 和低速外部晶体振荡器 (LSE)
    6. PLL (Phase-Locked Loop) 的主要作用是什么?

    7. A) 减少功耗
    8. B) 提高内存访问速度
    9. C) 倍频基础时钟频率
    10. D) 增加外设数量
    11. 在STM32中,使用PLL进行倍频时,通常需要设置哪些参数?

    12. A) 输入分频因子、倍频系数、输出分频因子
    13. B) 内存地址映射、中断优先级、DMA通道
    14. C) USB接口配置、SPI波特率、I²C地址
    15. D) 输入分频因子、倍频系数、输出分频因子
    16. 对于需要快速启动的应用,应该选择哪种时钟源?

    17. A) 内部RC振荡器 (HSI)
    18. B) 外部晶体振荡器 (HSE)
    19. C) 低速内部RC振荡器 (LSI)
    20. D) 低速外部晶体振荡器 (LSE)
    21. 当使用外部晶体振荡器 (HSE) 作为PLL输入时,通常它的频率是多少?

    22. A) 8 MHz 或 25 MHz
    23. B) 16 MHz 或 32 MHz
    24. C) 8 MHz 或 25 MHz
    25. D) 12 MHz 或 24 MHz
    二、简答题(每题10分,共30分)
    1. 简要描述系统时钟源的选择依据及其应用场景。

    2. 解释PLL (Phase-Locked Loop) 在嵌入式系统中的作用,并说明如何通过PLL提高系统的工作速度。

    3. 在配置STM32的时钟树时,为什么需要调整闪存等待状态(FLASH Latency)?

    三、填空题(每题2分,共10分)
    1. STM32系列单片机可以通过______或______提供系统时钟源。

    2. PLL可以将输入的基础时钟频率进行______,以达到更高的工作速度。

    3. 在配置PLL时,需要设置输入分频因子、______和输出分频因子。

    4. 为了确保系统的稳定性和可靠性,使用的外部晶体振荡器必须符合______中的规格要求。

    5. 如果对功耗有严格要求,应权衡时钟频率与______之间的关系,选择最合适的配置方案。

    四、编程题(每题20分,共40分)
    1. 编写一段代码,配置STM32的时钟树,使用外部8MHz晶体振荡器 (HSE) 作为系统时钟源,并通过PLL将时钟频率倍频至168MHz。请包括必要的初始化步骤和错误处理机制。

    2. 编写一段代码,配置STM32的USB OTG FS时钟源为PLL输出,并确保其频率为48MHz。同时,确保所有相关外设的时钟配置正确。

    五、应用设计题(每题15分,共15分)
    1. 设计一个基于STM32的智能环境监控系统,详细描述如何配置时钟树以满足高性能和低功耗的需求。考虑以下因素:
    2. 系统的主要功能模块(如传感器读取、Wi-Fi通信等)
    3. 各模块的最佳工作频率
    4. 如何通过时钟配置优化系统的整体性能和功耗

    作者:不能只会打代码

    物联沃分享整理
    物联沃-IOTWORD物联网 » 32单片机从入门到精通之硬件架构——时钟树配置(三)

    发表回复