智能硬件知识

news2024/12/23 9:13:21

第二章

在这里插入图片描述

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

第五章

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

第六章

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

第七章

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

第八章

在这里插入图片描述

第九章

在这里插入图片描述

第十章

在这里插入图片描述

考点

条件编译

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);
  }
}

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

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

相关文章

关于数据中心存储智能运维的思考

随着互联网和大数据的快速发展&#xff0c;数据中心存储的重要性也日益凸显。在本文中&#xff0c;将深入探讨数据中心存储智能运维的历史变迁、当前的发展状态和未来的运维趋势。 数据中心存储运维的历史变迁可以分为以下几个阶段&#xff1a; 人工运维阶段 最初&#xff0c…

深度学习基本理论上篇:(MLP/激活函数/softmax/损失函数/梯度/梯度下降/学习率/反向传播)、深度学习面试

1、MLP、FCN、DNN三者的关系&#xff1f; 多层感知器MLP&#xff0c;全连接网络&#xff0c;DNN三者的关系&#xff1f;三者是不是同一个概念&#xff1f; FCN&#xff1a;Fully Connected Neural Network&#xff0c;全连接神经网络&#xff0c;也称为密集连接神经网络&#…

前端开发怎么解决前端安全性的问题? - 易智编译EaseEditing

前端安全性是保护前端应用程序免受恶意攻击和数据泄露的重要方面。以下是一些解决前端安全性问题的关键方法&#xff1a; 输入验证与过滤&#xff1a; 对所有用户输入进行验证和过滤&#xff0c;防止恶意用户通过注入攻击等手段破坏应用程序或获取敏感信息。 跨站点脚本&#…

Android笔记:在原生App中嵌入Flutter

首先有一个可以运行的原生项目 第一步&#xff1a;新建Flutter module Terminal进入到项目根目录&#xff0c;执行flutter create -t module ‘module名字’例如&#xff1a;flutter create -t module flutter-native 执行完毕&#xff0c;就会发现项目目录下生成了一个modu…

【核磁共振成像】单射成像和高速脉冲序列

目录 一、提高成像速度的手段二、平面回波成像(EPI)序列三、常用或基本EPI序列四、EPI变型序列五、渐开平面螺旋(spiral)扫描序列六、RARE序列七、GRASE序列八、STEAM序列 一、提高成像速度的手段 MRI扫描时间可表示为   其中Nex为激发次数&#xff0c;NpE1和NpE2是两个相位…

kubernetes--技术文档-真--集群搭建-三台服务器一主二从(非高可用)附属文档-使用不同运行商服务器-搭建公网集群

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;版本&#xff01;&#xff01;&#xff01;&#xff01; 使用公网初始化 Kubernetes 需要 Kubernetes 版本 1.19 或更高版本。在早期的版本中&#xff0c;Kubernetes 还不支持公网初始化。因此&#xff0c;请确保…

【C++】visualstudio环境安装

记录了部分安装步骤&#xff0c;可能有点不全&#xff0c;参考下&#xff0c;需要的磁盘空间差不多20GB&#xff1b; 下载 https://visualstudio.microsoft.com/zh-hans/vs/ 下载完成&#xff1a; 双击进入安装状态&#xff1a; 根据自己的需求勾选安装项&#xff1a; 选择…

RNN+LSTM正弦sin信号预测 完整代码数据视频教程

视频讲解:RNN+LSTM正弦sin信号预测_哔哩哔哩_bilibili 效果演示: 数据展示: 完整代码: import torch import torch.nn as nn import torch.optim as optim import numpy as np import matplotlib.pyplot as plt import pandas as pd from sklearn.preprocessing import…

使用Locust进行接口性能测试:安装、命令参数解析与示例解读

“ Locust是一款开源的Python性能测试工具&#xff0c;它可以模拟大量并发用户对网站或者其他接口进行压力测试 一、Locust简介与安装 1. 使用pip安装Locust&#xff1a; pip3 install locust2. 通过GitHub克隆项目并安装&#xff08;推荐Python 3&#xff09;&#xff1a; …

常见js中判断== true/false总结

常见js中判断为true/false总结 false 0 输出true&#xff1b;因为在做判断的时候&#xff0c;两者中有boolean&#xff08;布尔类型&#xff09;&#xff0c;会把boolean先转化为number&#xff08;数字类型&#xff09;&#xff0c;false为0&#xff0c;true是1。也就是等价于…

二、10.文件系统

硬盘是低速设备&#xff0c;其读写单位是扇区&#xff0c;为了避免频繁访问硬盘&#xff0c;操作系统不会有了一扇区数据就去读写一次磁盘&#xff0c;往往等数据积攒到“足够大小”时才一次性访问硬盘&#xff0c;这足够大小的数据就是块&#xff0c;硬盘读写单位是扇区&#…

交叉熵--损失函数

目录 交叉熵&#xff08;Cross Entropy&#xff09; 【预备知识】 【信息量】 【信息熵】 【相对熵】 【交叉熵】 交叉熵&#xff08;Cross Entropy&#xff09; 是Shannon信息论中一个重要概念&#xff0c; 主要用于度量两个概率分布间的差异性信息。 语言模型的性能…

FlashAttention算法详解

这篇文章的目的是详细的解释Flash Attention&#xff0c;为什么要解释FlashAttention呢&#xff1f;因为FlashAttention 是一种重新排序注意力计算的算法&#xff0c;它无需任何近似即可加速注意力计算并减少内存占用。所以作为目前LLM的模型加速它是一个非常好的解决方案&…

ThreadLocal深度解析

简介 在并发编程中&#xff0c;导致并发bug的问题都会归结于对共享变量的操作不当。多个线程同时读写同一共享变量存在并发问题&#xff0c;我们可以利用写时复制、不变性来突破对原数据的写操作&#xff0c;没有写就没有并发问题&#xff0c;而本篇文章所介绍的技术是突破共享…

基于swing的销售管理系统java仓库库存信息jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 基于swing的销售管理系统 系统有1权限&#xff1a;管…

spring依赖注入详解(上)

一、Bean销毁的过程 如果bean销毁时会执行的场景 1、设置DestroyMethodName为(inferred) // 先把DestroyMethodName设置为(inferred) Component public class TestBeanPostProcessor implements MergedBeanDefinitionPostProcessor {Overridepublic void postProcessMergedBe…

Hive(一)

一、DDL 1、数据库操作 1&#xff09;、创建数据库 语法&#xff1a; CREATE DATABASE [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPERTIES (property_nameproperty_value, ...)]; 案例&#xff1a; &#xff08;1&…

vue element-ui 菜单管理使用图标选择器组件

目录 &#x1f31f;前言&#x1f31f;安装&#x1f31f;main.js配置&#x1f31f;页面使用&#x1f31f;效果展示 &#x1f31f;前言 哈喽小伙伴们&#xff0c;本文为大家介绍一下 VueElementUI 中图标选择器组件的使用方法&#xff1b;一起来看下吧。 &#x1f31f;安装 np…

RN 尝鲜之旅

React Native 一直没使用过&#xff0c;闲来无事&#xff0c;还是尝鲜了一下下。 目前还没有出新手村&#xff0c;所以写的东西不一定具有任何参考价值&#xff0c;见谅。 关于 RN 的一些说明 RN 与 R RN 与 R 的区别&#xff1a;来自掘金的一篇文章 RN 与 R 不一样&#xf…

报道 | 9月国际运筹优化会议汇总

封面图来源&#xff1a; https://www.pexels.com/zh-cn/photo/1181406/ 九月召开会议汇总&#xff1a; The 96th meeting of the EURO Working Group on Multiple Criteria Decision Aiding (EWG-MCDA) Location: Paris, France Important dates: Conference: September 202…