智能硬件知识

第二章

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

第五章

在这里插入图片描述
在这里插入图片描述

第六章

在这里插入图片描述
在这里插入图片描述

第七章

在这里插入图片描述
在这里插入图片描述

第八章

在这里插入图片描述

第九章

在这里插入图片描述

第十章

在这里插入图片描述

考点

条件编译

volatile、static、 union、 struct、 const指针

堆与栈的不同点

3.功能模块应用题

(1) GPIO 的应用:流水灯的电路及软件编码、驱动数码管的电路及编码。

(2)外部中断的应用:电路及回调函数编码。

(3) USART 应用:以某种数据帧格式实现轮询、中断及DMA方式的数据发送及接收,包括使用STM32CubeMX进行USART1配置的大致过程、补充代码。

(4)定时器的应用:用定时器产生周期和占空比可变的PWM信号、定时点亮LED。

(5) ADC的应用:采集2路模拟信号。

4.综合应用题

(1)综合运用定时器、ADC和GPIO。用定时器实现定时启动ADC,用GPIO控制的数码管显示ADC的采集值。

(2)综合运用定时器、ADC 和UART。用定时器实现定时启动ADC,用UART发送ADC的采集值。

3(1)

题目:(1) GPIO 的应用:流水灯的电路及软件编码、驱动数码管的电路及编码。
以下是一个简单的流水灯电路设计示例:
电路设计:
使用多个LED灯(如4个)连接在一起,按顺序排列形成一条线。
每个LED灯通过一个限流电阻与正向电压源相连。
每个LED灯的负极通过一个开关或晶体管控制引脚与控制器相连。
软件编码:
在微控制器中,使用编程语言(如C语言)编写程序来控制流水灯的流动效果。

以下是一个简单的流水灯的软件编码示例:

#include <stdio.h>
#include "stm32f4xx.h"

int main(void) {
  // 初始化LED灯引脚为输出
  GPIO_InitTypeDef GPIO_InitStruct;
  GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  while (1) {
    // 依次点亮LED灯
    for (int i = 0; i < 4; i++) {
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3, (1 << i));
      HAL_Delay(500);  // 延时500毫秒
    }
  }
}

以上代码假设LED灯的引脚连接到STM32微控制器的GPIOD引脚0、1、2和3上。程序中使用循环依次点亮LED灯,通过延时函数控制灯的亮灭和流动效果。

关于数码管的电路设计和编码方式,需要进一步明确数码管的类型和接口(如共阳/共阴、七段数码管/八段数码管等),以及使用的控制器(如74HC595移位寄存器、MAX7219驱动芯片等)。

一般而言,数码管的电路设计包括将数码管引脚连接到相应的IO引脚或驱动芯片上,并通过编程来控制数码管的显示。

编码方式根据数码管类型的不同而异,常见的编码方式有直接编码、译码器编码、位选编码等。具体的编码方式取决于数码管的类型和所使用的驱动芯片。

请提供更详细的信息,例如数码管的类型和所使用的控制器,以便提供更具体的电路和编码示例。

3(2)

题目:(2)外部中断的应用:电路及回调函数编码。
外部中断的应用可以用于检测外部事件(如按钮按下、传感器触发等)并进行相应的处理。以下是一个基于STM32系列微控制器和STM32 HAL库的外部中断应用的电路设计和回调函数编码示例。

电路设计:

连接外部中断引脚和相应的外部事件触发源(如按钮)。
确保外部中断引脚与控制器的外部中断线(EXTI)相连。
为外部中断引脚配置中断触发方式(上升沿触发、下降沿触发等)。

#include "stm32f4xx.h"

// 定义外部中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
  // 在此处处理外部中断事件
  if (GPIO_Pin == GPIO_PIN_0) {
    // 外部中断引脚GPIO_Pin为GPIO_PIN_0时的处理逻辑
    // ...
  } else if (GPIO_Pin == GPIO_PIN_1) {
    // 外部中断引脚GPIO_Pin为GPIO_PIN_1时的处理逻辑
    // ...
  }
}

int main(void) {
  // 初始化GPIO引脚为输入
  GPIO_InitTypeDef GPIO_InitStruct;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;  // 上升沿触发
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;  // 上拉/下拉
  GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;  // 外部中断引脚
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);  // 初始化GPIOA引脚

  // 使能外部中断
  HAL_NVIC_EnableIRQ(EXTI0_IRQn);  // 使能外部中断0
  HAL_NVIC_EnableIRQ(EXTI1_IRQn);  // 使能外部中断1

  while (1) {
    // 主循环中的其他代码
    // ...
  }
}

// 外部中断0的中断处理函数
void EXTI0_IRQHandler(void) {
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

// 外部中断1的中断处理函数
void EXTI1_IRQHandler(void) {
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
}

以上代码示例假设外部中断引脚连接到STM32微控制器的GPIOA引脚0和1上。在主函数中,通过初始化GPIO引脚为输入并配置中断触发方式来准备外部中断。然后使用HAL_NVIC_EnableIRQ()函数使能外部中断,并在主循环中执行其他代码。当外部中断触发时,相应的中断处理函数EXTI0_IRQHandler()和EXTI1_IRQHandler()将会被调用,并通过HAL_GPIO_EXTI_IRQHandler()函数调用回调函数HAL_GPIO_EXTI_Callback()来处理外部中断事件。

请注意,以上代码仅提供了基本的框架,具体的外部中断处理逻辑需要根据实际需求进行编写。

3(3)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题目:(3) USART 应用:以某种数据帧格式实现轮询、中断及DMA方式的数据发送及接收,包括使用STM32CubeMX进行USART1配置的大致过程、补充代码。

#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"

#define BUFFER_SIZE 10

UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart1_rx;

uint8_t txBuffer[BUFFER_SIZE] = "Hello";
uint8_t rxBuffer[BUFFER_SIZE];

void USART1_Init(void);
void DMA_USART1_Init(void);
void USART1_SendPolling(void);
void USART1_SendInterrupt(void);
void USART1_SendDMA(void);
void USART1_ReceivePolling(void);
void USART1_ReceiveInterrupt(void);
void USART1_ReceiveDMA(void);

int main(void)
{
  HAL_Init();//初始化HAL库
  USART1_Init();
  DMA_USART1_Init();
  
  while (1)
  {
    // 轮询方式发送数据
    USART1_SendPolling();
    
    // 轮询方式接收数据
    USART1_ReceivePolling();
    
    // 中断方式发送数据
    USART1_SendInterrupt();
    
    // 中断方式接收数据
    USART1_ReceiveInterrupt();
    
    // DMA方式发送数据
    USART1_SendDMA();
    
    // DMA方式接收数据
    USART1_ReceiveDMA();
  }
}

void USART1_Init(void)
{
  // 初始化USART1的GPIO引脚
  GPIO_InitTypeDef GPIO_InitStruct;
  __HAL_RCC_GPIOB_CLK_ENABLE();
  
  GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  //这段代码初始化了GPIO端口B的引脚6和引脚7,设置它们为复用功能的推挽输出模式,上拉电阻使其保持高电平,设置GPIO的工作速度为非常高频率,选择GPIO的复用功能为USART1。
  
  // 初始化USART1的配置参数
  __HAL_RCC_USART1_CLK_ENABLE();
  //该代码使能了USART1外设的时钟。
  
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart1);
  //这段代码初始化了USART1的配置参数。设置USART1的实例为USART1,波特率为115200,数据位长度为8位,停止位为1位,无奇偶校验,工作模式为发送和接收模式,无硬件流控制,过采样率为16倍。
}

void DMA_USART1_Init(void)
{
  // 初始化USART1的DMA配置参数
  __HAL_RCC_DMA2_CLK_ENABLE();
  
  hdma_usart1_tx.Instance = DMA2_Stream7;
  hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4;
  hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
  hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  hdma_usart1_tx.Init.Mode = DMA_NORMAL;----设置DMA传输模式
  hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;---设置DMA优先级
  hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  HAL_DMA_Init(&hdma_usart1_tx);
  //这部分代码配置了 USART1 的 DMA 发送通道(DMA2_Stream7)。其中设置了通道号、传输方向(从内存到外设)、外设地址增量模式禁止、内存地址增量模式使能、数据对齐方式等。然后通过 HAL_DMA_Init() 函数对 DMA 进行初始化。

  
  __HAL_LINKDMA(&huart1, hdmatx, hdma_usart1_tx);
  
  hdma_usart1_rx.Instance = DMA2_Stream5;
  hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
  hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
  hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  hdma_usart1_rx.Init.Mode = DMA_NORMAL;
  hdma_usart1_rx.Init.Priority = DMA_PRIORITY_HIGH;
  hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  HAL_DMA_Init(&hdma_usart1_rx);
  这部分代码配置了 USART1 的 DMA 接收通道(DMA2_Stream5)。与发送通道类似,设置了通道号、传输方向(从外设到内存)、外设地址增量模式禁止、内存地址增量模式使能、数据对齐方式等。然后通过 HAL_DMA_Init() 函数对 DMA 进行初始化。
  
  __HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx);
  
  // 使能USART1的DMA接收中断
  HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);
  
  // 使能USART1的DMA发送中断
  HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
}

void USART1_SendPolling(void)
{
  HAL_UART_Transmit(&huart1, txBuffer, BUFFER_SIZE, HAL_MAX_DELAY);
}

void USART1_SendInterrupt(void)
{
  HAL_UART_Transmit_IT(&huart1, txBuffer, BUFFER_SIZE);
  HAL_UART_IRQHandler(&huart1);
}

void USART1_SendDMA(void)
{
  HAL_UART_Transmit_DMA(&huart1, txBuffer, BUFFER_SIZE);
}

void USART1_ReceivePolling(void)
{
  HAL_UART_Receive(&huart1, rxBuffer, BUFFER_SIZE, HAL_MAX_DELAY);
}

void USART1_ReceiveInterrupt(void)
{
  HAL_UART_Receive_IT(&huart1, rxBuffer, BUFFER_SIZE);
  HAL_UART_IRQHandler(&huart1);
}

void USART1_ReceiveDMA(void)
{
  HAL_UART_Receive_DMA(&huart1, rxBuffer, BUFFER_SIZE);
}

void DMA2_Stream5_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hdma_usart1_rx);
}

void DMA2_Stream7_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hdma_usart1_tx);
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart == &huart1)
  {
    // UART发送完成中断回调函数
  }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart == &huart1)
  {
    // UART接收完成中断回调函数
  }
}


3(4)

在这里插入图片描述
要使用定时器产生可变周期和占空比的PWM信号,并定时点亮LED,可以按照以下步骤进行:
初始化定时器和GPIO引脚:
初始化定时器,选择合适的定时器(如TIM1、TIM2等),设置时钟源和预分频系数。
配置定时器的工作模式为PWM模式,设置计数器的自动重装载值。
配置输出通道对应的GPIO引脚为PWM输出模式。
初始化LED引脚为输出模式。
配置定时器的周期和占空比:
根据需要,设置定时器的周期和占空比,可以通过修改自动重装载值和占空比寄存器的值来实现。
启动定时器:
启动定时器,使其开始计数。
等待定时器中断:
进入一个无限循环,等待定时器中断触发。
在定时器中断处理函数中控制LED点亮:
在定时器中断处理函数中,设置LED引脚的状态,使其点亮或熄灭。
题目:(4)定时器的应用:用定时器产生周期和占空比可变的PWM信号、定时点亮LED。

#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"

TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;

uint32_t period = 1000;     // 初始周期为 1000
uint32_t dutyCycle = 500;   // 初始占空比为 50%

void TIM1_PWM_Init(void);
void TIM2_Init(void);
void GPIO_Init(void);

int main(void)
{
  HAL_Init();
  TIM1_PWM_Init();
  TIM2_Init();
  GPIO_Init();
  
  int pwmMode = 1;  // PWM 模式标志,初始为 1
  
  while (1)
  {
    if (pwmMode)
    {
      // 按键检测,调整周期和占空比
      if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
      {
        HAL_Delay(10);  // 延时去抖动
        if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
        {
          // 增加周期
          period += 100;
          if (period > 2000)
            period = 2000;
        
          // 更新周期寄存器的值
          __HAL_TIM_SET_AUTORELOAD(&htim1, period - 1);
        }
      }
    
      if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
      {
        HAL_Delay(10);  // 延时去抖动
        if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
        {
          // 增加占空比
          dutyCycle += 100;
          if (dutyCycle > period)
            dutyCycle = period;
        
          // 更新占空比寄存器的值
          __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, dutyCycle);
        }
      }
    }
    else
    {
      // 在指定时间间隔内循环闪烁 LED 灯
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);   // 点亮 LED
      HAL_Delay(500);  // 延时 500ms
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET); // 熄灭 LED
      HAL_Delay(500);  // 延时 500ms
    }
    
    // 按键检测,切换功能模式
    if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) == GPIO_PIN_RESET)
    {
      HAL_Delay(10);  // 延时去抖动
      if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) == GPIO_PIN_RESET)
      {
        pwmMode = !pwmMode;  // 切换功能模式
      }
    }
  }
}

void TIM1_PWM_Init(void)
{
  TIM_OC_InitTypeDef sConfigOC;
  
  __HAL_RCC_TIM1_CLK_ENABLE();
  
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = (SystemCoreClock / 1000000) - 1;  // 配置定时器时钟为 1MHz
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = period - 1;  // 设置周期
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_PWM_Init(&htim1);
  
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = dutyCycle;    // 设置初始占空比
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
  
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);  // 启动定时器
}

void TIM2_Init(void)
{
  __HAL_RCC_TIM2_CLK_ENABLE();
  
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = (SystemCoreClock / 1000) - 1;   // 配置定时器时钟为 1kHz
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 1000 - 1;    // 设置定时器的周期为 1s
  HAL_TIM_Base_Init(&htim2);
  
  HAL_TIM_Base_Start(&htim2);      // 启动定时器
}

void GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  
  __HAL_RCC_GPIOA_CLK_ENABLE();
  
  GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
  
  GPIO_InitStruct.Pin = GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include "stm32f4xx.h"

void TIM_PWM_Init(void);
void LED_Init(void);

int main(void)
{
  TIM_PWM_Init();
  LED_Init();

  while (1)
  {
    // 等待定时器中断
  }
}

void TIM_PWM_Init(void)
{
  // 初始化定时器和PWM参数
  TIM_HandleTypeDef htim;
  TIM_OC_InitTypeDef sConfig;
  
  // 选择合适的定时器和通道(例如TIM1和TIM_CHANNEL_1)
  htim.Instance = TIM1;
  htim.Init.Prescaler = 0;
  htim.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim.Init.Period = 999; // 设置定时器周期
  htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_PWM_Init(&htim);
  
  // 配置PWM参数
  sConfig.OCMode = TIM_OCMODE_PWM1;
  sConfig.Pulse = 500; // 设置占空比
  sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfig.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(&htim, &sConfig, TIM_CHANNEL_1);
  
  // 启动定时器和PWM输出
  HAL_TIM_PWM_Start(&htim, TIM_CHANNEL_1);
}

void LED_Init(void)
{
  // 初始化LED引脚为输出模式
  GPIO_InitTypeDef GPIO_InitStruct;
  
  // 配置LED引脚对应的GPIO端口和引脚号
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}

void TIM1_UP_TIM10_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM1, TIM_IT_UPDATE) != RESET)
  {
    // 清除定时器中断标志位
    TIM_ClearITPendingBit(TIM1, TIM_IT_UPDATE);

    // 控制LED点亮或熄灭
    GPIOC->ODR ^= GPIO_PIN_13;
  }
}

3(5)

题目:(5) ADC的应用:采集2路模拟信号。

#include "stm32xxxx.h" // 包含您所使用的 STM32 系列芯片的头文件
#include "stm32xxxx_hal_adc.h" // 包含 STM32 HAL 库的 ADC 头文件

ADC_HandleTypeDef hadc; // 定义 ADC 句柄

void initializeADC()
{
  // 初始化 ADC 句柄
  hadc.Instance = ADC1; // 假设使用 ADC1
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; // ADC 时钟分频为 PCLK/2
  hadc.Init.Resolution = ADC_RESOLUTION_12B; // ADC 分辨率为 12 位
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐
  // 更多的初始化配置根据需要设置

  // 初始化 ADC
  HAL_ADC_Init(&hadc);------------库函数
}

void captureAnalogSignals()
{
  // 启动 ADC 转换
  HAL_ADC_Start(&hadc);----------库函数

  // 等待转换完成
  HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY); ------------库函数// 使用阻塞方式等待转换完成
  
  // 读取采样值
  uint16_t sample1 = HAL_ADC_GetValue(&hadc);------------库函数

  // 启动下一次转换
  HAL_ADC_Start(&hadc);

  // 等待转换完成
  HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);

  // 读取采样值
  uint16_t sample2 = HAL_ADC_GetValue(&hadc);

  // 处理和使用采样值
  // 在这里进行进一步的操作,例如数据分析、滤波、显示或发送到其他设备等
}

int main()
{
  // 初始化 ADC
  initializeADC();

  // 循环采集两路模拟信号
  while (1)
  {
    captureAnalogSignals();
    // 在这里可以添加延时,控制采样频率
  }

  return 0;
}

4(1)

题目:(1)综合运用定时器、ADC和GPIO。用定时器实现定时启动ADC,用GPIO控制的数码管显示ADC的采集值。

#include "stm32xxxx.h" // 包含您所使用的 STM32 系列芯片的头文件
#include "stm32xxxx_hal_adc.h" // 包含 STM32 HAL 库的 ADC 头文件
#include "stm32xxxx_hal_gpio.h" // 包含 STM32 HAL 库的 GPIO 头文件
#include "stm32xxxx_hal_rcc.h" // 包含 STM32 HAL 库的 RCC 头文件
#include "stm32xxxx_hal_tim.h" // 包含 STM32 HAL 库的定时器头文件

ADC_HandleTypeDef hadc; // 定义 ADC 句柄
TIM_HandleTypeDef htim; // 定义定时器句柄

uint16_t adcValue; // 用于保存 ADC 采样值

void initializeADC()
{
  // 初始化 ADC 句柄
  hadc.Instance = ADC1; // 假设使用 ADC1
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; // ADC 时钟分频为 PCLK/2
  hadc.Init.Resolution = ADC_RESOLUTION_12B; // ADC 分辨率为 12 位
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐
  // 更多的初始化配置根据需要设置

  // 初始化 ADC
  HAL_ADC_Init(&hadc);
}

void initializeTimer()
{
  // 初始化定时器句柄
  htim.Instance = TIM2; // 假设使用 TIM2
  htim.Init.Prescaler = 10000 - 1; // 预分频器值,定时器频率为 10 kHz
  htim.Init.Period = 1000 - 1; // 计数周期,定时周期为 1 秒
  // 更多的初始化配置根据需要设置

  // 初始化定时器
  HAL_TIM_Base_Init(&htim);
}

void initializeGPIO()
{
  // 初始化 GPIO 引脚
  GPIO_InitTypeDef GPIO_InitStruct;

  GPIO_InitStruct.Pin = GPIO_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 输出模式,推挽输出
  GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 输出速度为低速
  // 更多的初始化配置根据需要设置

  // 初始化 GPIO
  HAL_GPIO_Init(GPIO_Port, &GPIO_InitStruct);
}


void startADCConversion()
{
  // 启动 ADC 转换
  HAL_ADC_Start(&hadc);
}

void readADCValue()
{
  // 等待转换完成
  HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY); // 使用阻塞方式等待转换完成

  // 读取采样值
  adcValue = HAL_ADC_GetValue(&hadc);
  
}

void displayADCValue()
{
  // 将 ADC 采样值显示在数码管上
  // 根据您使用的具体数码管和 GPIO 引脚连接方式进行相应的操作
  // 在这里进行数码管的控制和显示操作
  if (adcValue >= 0 && adcValue <= 9)
  {
    HAL_GPIO_WritePin(GPIO_Port, GPIO_Pin, GPIO_PIN_SET);
  } 
  else 
  {
    HAL_GPIO_WritePin(GPIO_Port, GPIO_Pin, GPIO_PIN_RESET);
  }
 
}

int main()
{
  // 初始化 ADC 和定时器
  initializeADC();
  initializeTimer();

  // 配置 GPIO 和数码管
  // 根据您使用的具体数码管和 GPIO 引脚连接方式进行相应的配置
  initializeGPIO();

  // 启动定时器
  HAL_TIM_Base_Start_IT(&htim); // 启动定时器并开启中断

  // 主循环
  while (1)
  {
    // 在定时器中断中进行 ADC 采样和数码管显示
  }

  return 0;
}

// 定时器中断处理函数
void TIM2_IRQHandler()
{
  if (__HAL_TIM_GET_FLAG(&htim, TIM_FLAG_UPDATE) != RESET)
  {
    if (__HAL_TIM_GET_IT_SOURCE(&htim, TIM_IT_UPDATE) != RESET)
    {
      __HAL_TIM_CLEAR_IT(&htim, TIM_IT_UPDATE);
      
      // 在定时器中断中启动 ADC 转换
      startADCConversion();

      // 读取 ADC 采样值
      readADCValue();

      // 在定时器中断中显示 ADC 采样值
      displayADCValue();
    }
  }
}

4(2)

题目:(2)综合运用定时器、ADC 和UART。用定时器实现定时启动ADC,用UART发送ADC的采集值。

#include "stm32xxxx.h" // 包含您所使用的 STM32 系列芯片的头文件
#include "stm32xxxx_hal_adc.h" // 包含 STM32 HAL 库的 ADC 头文件
#include "stm32xxxx_hal_uart.h" // 包含 STM32 HAL 库的 UART 头文件
#include "stm32xxxx_hal_rcc.h" // 包含 STM32 HAL 库的 RCC 头文件

ADC_HandleTypeDef hadc; // 定义 ADC 句柄
UART_HandleTypeDef huart; // 定义 UART 句柄
TIM_HandleTypeDef htim; // 定义定时器句柄

void initializeADC()
{
  // 初始化 ADC 句柄
  hadc.Instance = ADC1; // 假设使用 ADC1
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; // ADC 时钟分频为 PCLK/2
  hadc.Init.Resolution = ADC_RESOLUTION_12B; // ADC 分辨率为 12 位
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐
  // 更多的初始化配置根据需要设置

  // 初始化 ADC
  HAL_ADC_Init(&hadc);
}

void initializeUART()
{
  // 初始化 UART 句柄
  huart.Instance = USART1; // 假设使用 USART1
  huart.Init.BaudRate = 115200; // 波特率为 115200
  huart.Init.WordLength = UART_WORDLENGTH_8B; // 数据位长度为 8 位
  huart.Init.StopBits = UART_STOPBITS_1; // 停止位为 1 位
  huart.Init.Parity = UART_PARITY_NONE; // 无校验位
  huart.Init.Mode = UART_MODE_TX; // 仅发送模式
  // 更多的初始化配置根据需要设置

  // 初始化 UART
  HAL_UART_Init(&huart);
}

void initializeTimer()
{
  // 初始化定时器句柄
  htim.Instance = TIM2; // 假设使用定时器 TIM2
  htim.Init.Prescaler = 1000 - 1; // 设置预分频值
  htim.Init.Period = 5000 - 1; // 设置定时器周期
  htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim.Init.CounterMode = TIM_COUNTERMODE_UP;

  // 初始化定时器
  HAL_TIM_Base_Init(&htim);
}

void startADCConversion()
{
  // 启动 ADC 转换
  HAL_ADC_Start(&hadc);
}

void sendADCValue(uint16_t adcValue)
{
  // 将 ADC 采样值转换为字符串
  char str[16];
  sprintf(str, "%hu\n", adcValue); // 将采样值格式化为字符串

  // 通过 UART 发送 ADC 采样值
  HAL_UART_Transmit(&huart, (uint8_t*)str, strlen(str), HAL_MAX_DELAY);
}

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

  // 初始化系统时钟和外设时钟
  SystemClock_Config();

  // 初始化 ADC、UART 和定时器
  initializeADC();
  initializeUART();
  initializeTimer();

  // 启动定时器
  HAL_TIM_Base_Start(&htim);

  while (1)
  {
    // 等待定时器溢出中断
    while (__HAL_TIM_GET_FLAG(&htim, TIM_FLAG_UPDATE) == RESET)
    {
      // 等待定时器中断
    }

    // 清除定时器中断标志位
    __HAL_TIM_CLEAR_FLAG(&htim, TIM_FLAG_UPDATE);

    // 在此进行 ADC 采样
    startADCConversion();
    HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
    uint16_t adcValue = HAL_ADC_GetValue(&hadc);

    // 发送 ADC 采样值
    sendADCValue(adcValue);
  }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值