[STM32F4] STM32F4之ADC介绍

[复制链接]
1983|59
 楼主| 初级工程渣 发表于 2023-10-29 01:59 | 显示全部楼层
1.4.9 ADC 规则序列寄存器 3 (ADC_SQR3) 82385653d4bee0f3e5.png
 楼主| 初级工程渣 发表于 2023-10-29 01:59 | 显示全部楼层
 楼主| 初级工程渣 发表于 2023-10-29 01:59 | 显示全部楼层
1.4.10 ADC 注入序列寄存器 (ADC_JSQR) 92439653d4c008db87.png
 楼主| 初级工程渣 发表于 2023-10-29 01:59 | 显示全部楼层
 楼主| 初级工程渣 发表于 2023-10-29 01:59 | 显示全部楼层
1.4.11 ADC 注入数据寄存器 x (ADC_JDRx) (x= 1…4) 80279653d4c1619568.png
 楼主| 初级工程渣 发表于 2023-10-29 01:59 | 显示全部楼层
 楼主| 初级工程渣 发表于 2023-10-29 02:00 | 显示全部楼层
1.4.12 ADC 规则数据寄存器 (ADC_DR)
 楼主| 初级工程渣 发表于 2023-10-29 02:00 | 显示全部楼层
 楼主| 初级工程渣 发表于 2023-10-29 02:00 | 显示全部楼层
1.5 ADC 编写流程
设置 ADC 对应的 GPIO-- 模拟输入
配置 ADC 工作方式 – CR1、 CR2
配置采样周期
配置转换序列个数和转换哪个序列
使能 ADC
编写 AD 转换函数
···使能转换开关
···等待转换完成
···获取数字量
那么下面就以内部温度传感器为例,如下代码所示:
 楼主| 初级工程渣 发表于 2023-10-29 02:00 | 显示全部楼层
  1. ADC_HandleTypeDef hadc1;//ADC句柄

  2. //初始化ADC
  3. void MY_ADC_Init(void)
  4. {   
  5.   hadc1.Instance = ADC1;
  6.   hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;                                //4分频,ADCCLK=PCLK2/4=90/4=22.5MHZ
  7.   hadc1.Init.Resolution = ADC_RESOLUTION_12B;                                                //12位模式
  8.   hadc1.Init.ScanConvMode = DISABLE;                                                                //非扫描模式
  9.   hadc1.Init.ContinuousConvMode = DISABLE;                                                        //关闭连续转换
  10.   hadc1.Init.DiscontinuousConvMode = DISABLE;                                                //禁止不连续采样模式
  11.   hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;        //使用软件触发
  12.   hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;                                        //软件触发
  13.   hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;                                                //右对齐
  14.   hadc1.Init.NbrOfConversion = 1;                                                                        //1个转换在规则序列中 也就是只转换规则序列1
  15.   hadc1.Init.DMAContinuousRequests = DISABLE;                                                //关闭DMA请求
  16.   hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;                                        //关闭EOC中断
  17.   if (HAL_ADC_Init(&hadc1) != HAL_OK)                                                                //初始化  
  18.   {
  19.     Error_Handler();
  20.   }
  21. }

  22. //ADC底层驱动,引脚配置,时钟使能
  23. //此函数会被HAL_ADC_Init()调用
  24. //hadc:ADC句柄
  25. void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
  26. {
  27.         if(adcHandle->Instance==ADC1)
  28.         {
  29.             __HAL_RCC_ADC1_CLK_ENABLE();            //使能ADC1时钟
  30.     }
  31. }

  32. //获得ADC值
  33. uint16_t get_adc(uint32_t ch)   
  34. {
  35.     ADC_ChannelConfTypeDef sConfig = {0};
  36.    
  37.     sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;                                //选择内部温度传感器通道
  38.     sConfig.Rank = 1;                                                                                //1个序列
  39.     sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;                //采样时间
  40.     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)//通道配置
  41.     {
  42.       Error_Handler();
  43.     }
  44.        
  45.     HAL_ADC_Start(&hadc1);                               //开启ADC
  46.        
  47.     HAL_ADC_PollForConversion(&hadc1,10);                //轮询转换
  48.    
  49.         return (uint16_t )HAL_ADC_GetValue(&hadc1);                //返回最近一次ADC1规则组的转换结果
  50. }

  51. //获取指定通道的转换值,取times次,然后平均
  52. //times:获取次数
  53. //返回值:通道ch的cnt次转换结果平均值
  54. uint16_t Get_Adc_Average(uint32_t ch,uint8_t cnt)
  55. {
  56.         uint32_t temp_val=0;
  57.         uint8_t n;
  58.         for(n=0;n<cnt;n++)
  59.         {
  60.                 temp_val+=get_adc(ch);
  61.                 delay_ms(5);
  62.         }
  63.         return temp_val/cnt;
  64. }

  65. //得到温度值
  66. //返回值:温度值(扩大了100倍,单位:℃.)
  67. short Get_Temprate(void)
  68. {
  69.         uint32_t adcx;
  70.         short result;
  71.         double temperate;
  72.         adcx=Get_Adc_Average(ADC_CHANNEL_TEMPSENSOR,10);//读取内部温度传感器通道,10次取平均
  73.         temperate=(float)adcx*(3.3/4096);                //电压值
  74.         temperate=(temperate-0.76)/0.0025 + 25; //转换为温度值
  75.         result=temperate*=100;                                        //扩大100倍.
  76.         return result;
  77. }
童雨竹 发表于 2024-2-9 07:10 | 显示全部楼层

代码量小的时候用来做条件判断
Wordsworth 发表于 2024-2-9 08:13 | 显示全部楼层

在直流电流上叠加了一些小的交流电流分量
公羊子丹 发表于 2024-2-9 10:09 | 显示全部楼层

这是个再正常不过的coding习惯
万图 发表于 2024-2-9 11:12 | 显示全部楼层

宽度则与电感量和电阻量成反比
Uriah 发表于 2024-2-9 12:15 | 显示全部楼层

电流要增大
帛灿灿 发表于 2024-2-9 14:11 | 显示全部楼层

有些信号包含丰富的高频分量
帛灿灿 发表于 2024-2-9 14:11 | 显示全部楼层

有些信号包含丰富的高频分量
Bblythe 发表于 2024-2-9 15:14 | 显示全部楼层

交流电流环路的布线要在其他引线之前布好
周半梅 发表于 2024-2-9 17:10 | 显示全部楼层

对于优秀程序员来说,这不是好代码
Pulitzer 发表于 2024-2-9 18:13 | 显示全部楼层

功率开关或整流环的连接没有直接接到电容的两端
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部