32单片机从入门到精通之硬件架构——总线系统(二)

一个真正强大的人,不会把太多心思花在取悦和亲附别人上面,所谓的圈子、资源,都只是衍生品,最重要的是提高自己的内功。
你要默默做好你该做的事情,等你变得足够优秀时,你想要的都会主动来找你,你会发现身边都是好人。
很喜欢的一段话:梧高凤必至,花香蝶自来人终向前走,花自向阳开,弱的时候,坏人最多。这个世界的温柔,来自于你的强大!

目录

上一篇博客习题讲解

选择题:

简答题:

填空题:

编程题

代码编写:

中断处理:

ADC应用:

应用设计题

项目设计:

优化建议:

开放性问题

讨论题:

创新应用:

总线系统知识点详解及代码案例

1. AHB (Advanced High-performance Bus)

2. APB1/APB2 (Advanced Peripheral Bus)

3. DMA (Direct Memory Access)

一张试卷

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

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

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

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

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


上一篇博客习题讲解

选择题:
  1. ARM Cortex-M系列中,哪一个内核具有浮点运算单元(FPU)?
  2. A) Cortex-M0
  3. B) Cortex-M3
  4. C) Cortex-M4 (正确答案)
  5. D) Cortex-M7 (也正确,但M4是最早引入FPU的版本)
简答题:
  1. 请简要描述STM32 MCU中GPIO引脚的几种工作模式,并举例说明每种模式的应用场景。

     

    STM32 MCU中的GPIO引脚有多种工作模式,主要包括以下几种:

  2. 输入模式(Input Mode):分为上拉输入、下拉输入和浮动输入。例如,读取按钮状态时可以使用上拉或下拉输入。
  3. 输出模式(Output Mode):包括推挽输出和开漏输出。推挽输出用于驱动LED等需要高电平和低电平的设备;开漏输出则常用于I²C通信。
  4. 复用功能模式(Alternate Function Mode):用于将GPIO引脚配置为外设功能,如USART、SPI、I²C等接口。
  5. 模拟模式(Analog Mode):允许引脚作为ADC输入端口,用于采集模拟信号。
  6. 解释什么是DMA (Direct Memory Access),以及它在STM32中的作用。

     

    DMA(直接内存访问)是一种硬件机制,允许数据在内存和其他外设之间直接传输,而无需CPU干预。在STM32中,DMA主要用于加速数据传输,减轻CPU负担,提高系统效率。例如,在进行ADC采样时,DMA可以直接将采样的数据存储到指定的内存缓冲区,使得CPU可以专注于其他任务。

填空题:
  1. STM32系列单片机基于______架构,支持多种低功耗模式,如睡眠、停止和待机。

  2. ARM Cortex-M
  3. 在STM32中,用于连接传感器、EEPROM等外围设备的两线制同步串行总线称为______。

  4. I²C
编程题
代码编写:
  1. 使用STM32 HAL库编写一段代码,配置一个GPIO引脚为输入模式,并读取其状态。如果该引脚处于高电平,则点亮另一个引脚上的LED;否则熄灭LED。
#include "stm32f4xx_hal.h"

// 定义引脚
#define BUTTON_PIN GPIO_PIN_0
#define LED_PIN GPIO_PIN_1
#define GPIO_PORT GPIOD

void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();

    while (1)
    {
        // 读取按钮状态
        if (HAL_GPIO_ReadPin(GPIO_PORT, BUTTON_PIN) == GPIO_PIN_SET)
        {
            // 如果按钮处于高电平,点亮LED
            HAL_GPIO_WritePin(GPIO_PORT, LED_PIN, GPIO_PIN_SET);
        }
        else
        {
            // 否则熄灭LED
            HAL_GPIO_WritePin(GPIO_PORT, LED_PIN, GPIO_PIN_RESET);
        }
    }
}

static void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOD_CLK_ENABLE(); // 启用GPIOD时钟

    // 配置LED引脚为推挽输出模式
    GPIO_InitStruct.Pin = LED_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIO_PORT, &GPIO_InitStruct);

    // 配置按钮引脚为上拉输入模式
    GPIO_InitStruct.Pin = BUTTON_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIO_PORT, &GPIO_InitStruct);
}
中断处理:
  1. 编写一段代码,设置一个外部中断,当按下按钮时触发中断服务程序(ISR),并在其中切换LED的状态。确保正确配置NVIC以设定中断优先级。
#include "stm32f4xx_hal.h"

// 定义引脚
#define BUTTON_PIN GPIO_PIN_0
#define LED_PIN GPIO_PIN_1
#define GPIO_PORT GPIOD

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

extern void Error_Handler(void);

volatile uint8_t led_state = 0;

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();

    while (1)
    {
        // 主循环
    }
}

static void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    EXTI_HandleTypeDef hexti = {0};

    __HAL_RCC_GPIOD_CLK_ENABLE(); // 启用GPIOD时钟

    // 配置LED引脚为推挽输出模式
    GPIO_InitStruct.Pin = LED_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIO_PORT, &GPIO_InitStruct);

    // 配置按钮引脚为外部中断模式
    GPIO_InitStruct.Pin = BUTTON_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; // 下降沿触发
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIO_PORT, &GPIO_InitStruct);

    // 配置NVIC优先级
    HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == BUTTON_PIN)
    {
        // 切换LED状态
        led_state = !led_state;
        HAL_GPIO_WritePin(GPIO_PORT, LED_PIN, led_state ? GPIO_PIN_SET : GPIO_PIN_RESET);
    }
}

void EXTI0_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(BUTTON_PIN);
}
ADC应用:
  1. 设计并实现一个简单的模拟信号采集系统,使用STM32的ADC模块读取电压值,并通过串口输出到电脑显示。要求能够调整采样率和分辨率。
#include "stm32f4xx_hal.h"
#include <stdio.h>

#define ADC_CHANNEL ADC_CHANNEL_0
#define USARTx USART2
#define USARTx_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE()
#define USARTx_TX_PIN GPIO_PIN_2
#define USARTx_RX_PIN GPIO_PIN_3
#define USARTx_GPIO_PORT GPIOA
#define USARTx_AF USART_AF7_USART2

#define BUFFER_SIZE 10

uint16_t adc_value;
char buffer[20];

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART_Init(void);
static void MX_ADC_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART_Init();
    MX_ADC_Init();

    // 开始ADC转换
    HAL_ADC_Start(&hadc);

    while (1)
    {
        // 触发一次转换
        if (HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY) == HAL_OK)
        {
            // 获取转换结果
            adc_value = HAL_ADC_GetValue(&hadc);

            // 将ADC值转换为字符串并发送到串口
            sprintf(buffer, "ADC Value: %d\r\n", adc_value);
            HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
        }

        HAL_Delay(1000); // 模拟采样率调整
    }
}

static void MX_ADC_Init(void)
{
    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 = DISABLE;
    hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

    if (HAL_ADC_Init(&hadc) != HAL_OK)
    {
        Error_Handler();
    }

    sConfig.Channel = ADC_CHANNEL;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
    if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
    {
        Error_Handler();
    }
}

static void MX_USART_Init(void)
{
    huart2.Instance = USARTx;
    huart2.Init.BaudRate = 115200;
    huart2.Init.WordLength = UART_WORDLENGTH_8B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_NONE;
    huart2.Init.Mode = UART_MODE_TX_RX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart2) != HAL_OK)
    {
        Error_Handler();
    }
}

static void MX_GPIO_Init(void)
{
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // USART TX/RX 配置
    GPIO_InitStruct.Pin = USARTx_TX_PIN | USARTx_RX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = USARTx_AF;
    HAL_GPIO_Init(USARTx_GPIO_PORT, &GPIO_InitStruct);
}
应用设计题
项目设计:
  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发送至云端服务器。
  • 异常处理:在网络连接失败时自动重试,保证数据传输的可靠性。
  • 优化建议:
    1. 针对上述智能环境监控系统,提出至少三项性能或功耗方面的优化措施,并解释为什么这些改进是有效的。
  • 降低采样频率:适当减少传感器采样频率,既能满足监控需求又能节省电力。对于变化缓慢的环境参数(如温度、湿度),每几分钟采集一次即可。
  • 进入低功耗模式:利用STM32的低功耗特性,在不活动期间让MCU进入睡眠模式,仅保留必要的唤醒源(如RTC闹钟)。这样可以在不影响功能的前提下大幅降低能耗。
  • 优化Wi-Fi连接策略:采用按需连接的方式,即只有在需要发送数据时才激活Wi-Fi模块,完成传输后立即断开连接。这不仅可以减少射频发射带来的功耗,还能延长电池寿命。
  • 开放性问题
    讨论题:
    1. 讨论在嵌入式系统开发过程中,选择使用HAL库还是LL库(Low-Level Library)的影响因素。这两种库各有何优缺点?
  • HAL库的优点

  • 易用性:提供了高层次的抽象层,简化了硬件编程复杂度,减少了开发者的工作量。
  • 移植性:代码更容易在不同型号的STM32芯片间迁移,提高了项目的灵活性。
  • 社区支持:拥有庞大的用户群体和技术文档,遇到问题时更容易找到解决方案。
  • HAL库的缺点

  • 性能损失:由于额外的抽象层,可能会导致一定的性能开销。
  • 资源占用:相比LL库,HAL库通常会占用更多的RAM和Flash空间。
  • LL库的优点

  • 高效能:直接操作寄存器,几乎没有性能损失,适合对实时性和效率要求高的应用场景。
  • 轻量化:代码体积小,适合资源受限的嵌入式系统。
  • LL库的缺点

  • 学习曲线陡峭:需要深入了解硬件细节,增加了开发难度。
  • 维护成本高:代码可移植性差,不同芯片间的差异可能导致大量修改。
  • 创新应用:
    1. 思考并描述一种新颖的应用场景,充分利用STM32丰富的外设接口特性,解决某个实际问题或改善现有产品的用户体验。
  • 智能家居网关:结合STM32的强大处理能力和多样的外设接口,设计一款智能家居网关,集成Zigbee、蓝牙、Wi-Fi等多种无线通信方式,作为家庭自动化系统的中枢节点。用户可以通过手机APP远程控制家中的智能设备(如灯光、空调、窗帘等),同时还可以接收来自各种传感器(如烟雾报警器、漏水探测器)的安全警报信息。此外,该网关还可以集成语音助手功能,实现自然语言交互,进一步提升用户的便利性和安全性。
  • 总线系统知识点详解及代码案例

    1. AHB (Advanced High-performance Bus)

    知识点讲解

  • 用途:AHB主要用于连接高速设备,如CPU、DMA控制器、存储器以及需要高带宽的数据通路。
  • 特点
  • 支持突发传输(Burst Transfer),可以一次性传输多个数据块,提高传输效率。
  • 提供多主控支持(Multi-Master Support),允许多个主设备同时访问共享资源。
  • 具有优先级仲裁机制,确保关键任务得到及时响应。
  • 数据宽度通常为32位或64位,具体取决于硬件设计。
  • 代码案例(以ARM Cortex-M系列MCU为例)

    #include "stm32f4xx_hal.h"
    
    // 初始化AHB总线上的外设(例如,启用GPIO时钟)
    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) {
            // 用户代码
        }
    }

    代码注释

  • __HAL_RCC_GPIOA_CLK_ENABLE():启用GPIOA时钟。GPIOA是连接在AHB上的一个高速外围设备,因此通过这个函数可以初始化AHB总线上的外设。
  • 2. APB1/APB2 (Advanced Peripheral Bus)

    知识点讲解

  • 用途
  • APB1:用于连接低速外围设备,如定时器、UART、SPI、I²C等。
  • APB2:用于连接中速外围设备,如ADC、DAC、PWM等。
  • 特点
  • 数据宽度一般为32位,但传输速率低于AHB。
  • 简化的协议设计,减少了功耗和复杂度。
  • 单周期访问模式,适合不需要高带宽的外设。
  • APB1和APB2的区别主要在于它们连接的不同类型的外设及其工作频率;APB2往往具有更高的时钟频率。
  • 代码案例(以STM32F4系列MCU为例)

    #include "stm32f4xx_hal.h"
    
    // 初始化APB1和APB2总线上的外设(例如,启用USART2时钟,它位于APB1上)
    void APB_Peripheral_Init(void) {
        // 启用USART2时钟,USART2位于APB1总线上
        __HAL_RCC_USART2_CLK_ENABLE();
    
        // 启用TIM1时钟,TIM1位于APB2总线上
        __HAL_RCC_TIM1_CLK_ENABLE();
    }
    
    int main(void) {
        HAL_Init();  // 初始化HAL库
    
        APB_Peripheral_Init();  // 初始化APB总线上的外设
    
        // 主循环
        while (1) {
            // 用户代码
        }
    }

    代码注释

  • __HAL_RCC_USART2_CLK_ENABLE():启用USART2时钟。USART2是一个典型的低速外围设备,位于APB1总线上。
  • __HAL_RCC_TIM1_CLK_ENABLE():启用TIM1时钟。TIM1是一个中速外围设备,位于APB2总线上。
  • 3. DMA (Direct Memory Access)

    知识点讲解

  • 用途:DMA允许数据在内存和其他外设之间直接传输,减轻CPU的负担,使CPU可以专注于其他计算任务。
  • 特点
  • 支持后台数据传输,无需CPU干预。
  • 可以配置多种传输模式,如单次传输、块传输、循环传输等。
  • 内置中断机制,在传输完成时通知CPU。
  • 提升了系统的整体吞吐量和响应速度,特别是在处理大量数据时效果显著。
  • 代码案例(以STM32F4系列MCU为例)

    #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) {
            // 停留在这里
        }
    }

    代码注释

  • __HAL_RCC_DMA2_CLK_ENABLE():启用DMA2时钟,DMA2负责管理DMA传输。
  • DMA_HandleTypeDef:定义DMA句柄,用于配置和控制DMA操作。
  • HAL_DMA_Init():初始化DMA句柄,配置DMA传输参数。
  • __HAL_LINKDMA():将DMA流与ADC关联,确保DMA可以直接从ADC获取数据。
  • HAL_ADC_Init() 和 HAL_ADC_ConfigChannel():初始化ADC,并配置ADC通道。
  • HAL_ADC_Start_DMA():启动ADC与DMA之间的数据传输,采用循环模式(DMA_CIRCULAR),使得每次转换后的数据自动写入指定的内存缓冲区。
  • Error_Handler():错误处理函数,当初始化失败时进入死循环。
  • 通过上述代码示例,您可以更好地理解如何在实际项目中使用AHB、APB1/APB2和DMA来优化嵌入式系统的性能。这些代码片段展示了如何配置和使用这些总线系统,从而实现高效的数据传输和外围设备管理。

    一张试卷

    一、选择题(每题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) 提高系统吞吐量
    二、简答题(每题10分,共30分)
    1. 简要描述AHB (Advanced High-performance Bus) 的特点及其应用场景。

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

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

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

    2. AHB总线的数据宽度通常为______位或______位。

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

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

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

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

    2. 编写一段代码,配置DMA以从ADC模块读取数据,并将数据存储到指定的内存缓冲区。确保正确配置DMA通道、传输模式和优先级。

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

    作者:不能只会打代码

    物联沃分享整理
    物联沃-IOTWORD物联网 » 32单片机从入门到精通之硬件架构——总线系统(二)

    发表回复