STM32CubeMX系列05——ADC(轮询、中断、DMA)

查看数: 1333 | 评论数: 52 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2022-11-23 12:18

正文摘要:

所用硬件正点原子Mini板,主控 STM32F103RCT6.用到的外设:串口1(PA9、PA10)任意几个GPIO口(这里用PA1、PA2、PA3,对应ADC通道1、2、3)。

回复

Uriah 发表于 2024-10-21 18:23

对于标准PCB设计,c形孔的最小直径为0.5mm,

使用特权

评论回复
万图 发表于 2024-10-21 17:20

是因为它作用是起到抑制,多应用于开关电源电路中

使用特权

评论回复
公羊子丹 发表于 2024-10-21 16:17

根据电荷守恒:Qinitial=Qfinal

使用特权

评论回复
Clyde011 发表于 2024-10-21 15:24

这样可以获得更光滑的表面。

使用特权

评论回复
Wordsworth 发表于 2024-10-21 14:21

得到不同测试条件下的输出电流和电压值,分析数据并进行比较

使用特权

评论回复
童雨竹 发表于 2024-10-21 13:18

模块电源灌封操作之所以重要,主要是由于其涉及到模块电源的防护及热设计

使用特权

评论回复
Pulitzer 发表于 2024-10-21 11:22

这种技术称为板对板焊接

使用特权

评论回复
周半梅 发表于 2024-10-21 10:19

这种电路结构的特点是:由四只相同的开关管接成电桥结构驱动脉冲变压器原边。

使用特权

评论回复
Bblythe 发表于 2024-10-21 08:23

镀半孔或c形孔是在板的边缘上镀半个半孔的一半。

使用特权

评论回复
帛灿灿 发表于 2024-10-21 07:20

它是由两个尺寸相同、匝数相同的线圈对称地绕制在同一个铁氧体环形磁芯

使用特权

评论回复
SHOPQQ 发表于 2022-11-23 14:29
多通道DMA和单通道DMA配置基本相同,只需注意存储AD转换结果的数组,如果有两个通道,数组长度为2,则每个通道的值分别对应数组的每一位;如果数组长度为2的整数倍,如10,则数组内[0] [2] [4] [6] [8]的值对应其中一个通道的AD值,即存储了连续采集5次的AD值,这样可以用多个AD值求平均值。

使用特权

评论回复
SHOPQQ 发表于 2022-11-23 14:24
注意
用到 DMA 的外设,MX_DMA_Init(); 一定要在外设初始化前面,比如这里的 MX_ADC1_Init(); 。

使用特权

评论回复
SHOPQQ 发表于 2022-11-23 14:24
第四步:编写 main.c 代码
/* USER CODE BEGIN PFP */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
        if(hadc == &hadc1)
        {
                // 使用DMA其实也会运行到这里,也可以将结果在这里输出。
                // 当然此函数也可以不写。
        }
}
/* USER CODE END PFP */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
        uint16_t adc_value[3] = {0};
  /* USER CODE END 1 */

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  
  /* Configure the system clock */
  SystemClock_Config();
  
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  
  /* USER CODE BEGIN WHILE */
        HAL_ADCEx_Calibration_Start(&hadc1);
        // enable DMA通道
        // 参数:ADC1、目标缓冲区地址、从ADC外围设备传输到内存的数据长度
        /*
         * 此处有个大坑,经过测试,DMA中断非常容易进(具体的不知道)
         *
         * 如果ADC采样周期短的话,一直在执行中断,
         * 导致无法执行主程序,因此会卡死在这个函数里面出不去。
         *
         * 因此,ADC的采用周期需要长一点。
         */
        HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_value, 3);
       
  while (1)
  {
        printf("-------------------- \r\n");
        printf("adc value[0]:%f \r\n", adc_value[0]/4096.0*3.3);
        printf("adc value[1]:%f \r\n", adc_value[1]/4096.0*3.3);
        printf("adc value[2]:%f \r\n", adc_value[2]/4096.0*3.3);
        HAL_Delay(1000);
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

使用特权

评论回复
SHOPQQ 发表于 2022-11-23 14:23
第二步:点击生成代码
第三步:串口重定向,在usart.c中添加如下代码、
// 需要调用stdio.h文件
#include <stdio.h>
//取消ARM的半主机工作模式
#pragma import(__use_no_semihosting)//标准库需要的支持函数                 
struct __FILE
{
        int handle;
};
FILE __stdout;      
void _sys_exit(int x) //定义_sys_exit()以避免使用半主机模式
{
        x = x;
}

int fputc(int ch, FILE *f)
{  
        HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
        return ch;
}

使用特权

评论回复
SHOPQQ 发表于 2022-11-23 14:18
HAL_ADCEx_Calibration_Start(&hadc1);
const uint8_t kNbrOfPin = 3;
  while (1)
  {
        for(int i = 0; i < kNbrOfPin; i++)
        {
                HAL_ADC_Start(&hadc1);
                HAL_ADC_PollForConversion(&hadc1, 100);
                float value = 0;
                uint32_t state = HAL_ADC_GetState(&hadc1);
                if (( state & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
                {
                        value = HAL_ADC_GetValue(&hadc1);
                        printf("adc value [%d]:%f\r\n", i,value/4096.0*3.3);
                }
                else
                {
                        printf("adc state[%d]:%d\r\n", i, state);
                }
        }
        HAL_ADC_Stop(&hadc1);
        HAL_Delay(200);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

使用特权

评论回复
SHOPQQ 发表于 2022-11-23 14:15
第四步:编写 main.c 代码

使用特权

评论回复