分析


在电机驱动电路中串入一个 0.02Ω、2W 的采样电阻,将电流信号
转换成电压信号,再经过隔离运放放大 8 倍后差分输出,使用普通运放将差分输出转换成单端输
出给 STM32 的 ADC 采样通道。

从上图中我们可以知道是一个负反馈电路

反馈:将输出信号的一·部分或全部通过反馈网络引回到输入端的过程

反馈网络:一般是阻容元件

看是否存在反馈:结构,输入端与输出端有没有一个反馈网络就是有没有阻容元件连接

反馈的极性:采用瞬时极性法



负反馈对放大倍数起到了限制作用,也增大了放大电路的稳定性,


相同端子,极性相反所以是负反馈

那么根据虚短和虚断可以知道 Up=Un,p 点和 n 点
没有电流到运放的 5 脚和 6 脚,可以得:


R61 与后面的电容组成 RC 滤波电路,R61 上流过的电流很小,压降也小,可以忽略不计,Vo
等于 Vcurrent_adc。

RC 滤波电路:低通滤波器

将(1)式和(2)式整理可得:



电压采样电路

电源电压采样电路,在电源电压上并联 R18 和 R19、R59 的串联电阻,R19
两端的电压作为隔离运放的输入,再经过隔离器件后差分输出,使用普通运放将差分输
出转换成单端输出,连接到 STM32 的 ADC 采样通道。隔离运放的输入电压为 Vi,则
有:Vi/R19=POWER/(R18+R59+R19),带入电阻值可得:Vi=POWER/37,通过上一节中电流
采样电流的计算方法可以计算得到 POWER_ADC=POWER/37+1.24,不同的是,电压检测部
分的隔离器件是没有进行放大的


vi=POWER/37

ADC

ADC 的输入电压范围为: 0~3.3V

最大的时钟的和典形值,最大36Mhz,fpclk2=APB2

我们这里4分频,84/4 =21Mhz,这个是ADC的采样时钟


DMA Requests 一定要开启因为要使用DMA

这里选择左对齐,为了放在16位(半字)数据的高12位,满量程就是 FFF,数据左对齐后就是 FFF0


要选择软件触发

每个Rank

sampling Time(采样时间)
假如选择的是56周期

(56 + 12) * 21/1 = 3.23us 一次采样时间

这里是3个周期 3+12 =15

这里就是(3 + 12) * 21/1 =一次采样时间,采集5000的话就 * 一次采样时间

后开启DMA


流固定的,选择半字

ADC 为什么使用半字,因为ADC只用了16位

然后模式选择循环模式

代码生成


__IO uint16_t ADC_ConvertedValue;
static uint16_t adc_buff[ADC_NUM_MAX];    // 电压采集缓冲区
static uint16_t vbus_adc_mean = 0;        // 电源电压 ACD 采样结果平均值
static uint32_t adc_mean_sum = 0;        // 平均值累加
static uint32_t adc_mean_count = 0;      // 累加计数void MX_ADC1_Init(void)
{ADC_ChannelConfTypeDef sConfig = {0};/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */hadc1.Instance = ADC1;hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;hadc1.Init.Resolution = ADC_RESOLUTION_12B;hadc1.Init.ScanConvMode = ENABLE;hadc1.Init.ContinuousConvMode = ENABLE;hadc1.Init.DiscontinuousConvMode = DISABLE;hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;hadc1.Init.DataAlign = ADC_DATAALIGN_LEFT;hadc1.Init.NbrOfConversion = 2;hadc1.Init.DMAContinuousRequests = ENABLE;hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;if (HAL_ADC_Init(&hadc1) != HAL_OK){Error_Handler();}/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */sConfig.Channel = ADC_CHANNEL_9;sConfig.Rank = 1;sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){Error_Handler();}/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */sConfig.Channel = ADC_CHANNEL_8;sConfig.Rank = 2;if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){Error_Handler();}}

要开ADC中断
DMA

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(adcHandle->Instance==ADC1){/* USER CODE BEGIN ADC1_MspInit 0 *//* USER CODE END ADC1_MspInit 0 *//* ADC1 clock enable */__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();/**ADC1 GPIO Configuration    PB0     ------> ADC1_IN8PB1     ------> ADC1_IN9 */GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);/* ADC1 DMA Init *//* ADC1 Init */hdma_adc1.Instance = DMA2_Stream0;hdma_adc1.Init.Channel = DMA_CHANNEL_0;hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;hdma_adc1.Init.Mode = DMA_CIRCULAR;hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;if (HAL_DMA_Init(&hdma_adc1) != HAL_OK){Error_Handler();}__HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);/* ADC1 interrupt Init */HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);HAL_NVIC_EnableIRQ(ADC_IRQn);/* USER CODE BEGIN ADC1_MspInit 1 *//* USER CODE END ADC1_MspInit 1 */}
}
init后不要忘了要开启
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&adc_buff, ADC_NUM_MAX);

#define ADC_NUM_MAX 2048 // ADC 转换结果缓冲区最大值
这里ADC_NUM_MAX 1024 + 1024 存放电流和电压

读电流和电压

后在ADC中断回调函数中写

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{uint32_t adc_mean = 0;HAL_ADC_Stop_DMA(hadc);       // 停止 ADC 采样,处理完一次数据在继续采样/* 计算电流通道采样的平均值 */for(uint32_t count = 0; count < ADC_NUM_MAX; count+=2){adc_mean += (uint32_t)adc_buff[count];}adc_mean_sum += adc_mean / (ADC_NUM_MAX / 2);    // 累加电压adc_mean_count++;#if 1adc_mean = 0;/* 计算电压通道采样的平均值 */for(uint32_t count = 1; count < ADC_NUM_MAX; count+=2){adc_mean += (uint32_t)adc_buff[count];}vbus_adc_mean = adc_mean / (ADC_NUM_MAX / 2);    // 保存平均值#elsevbus_adc_mean = adc_buff[1];
#endifHAL_ADC_Start_DMA(&hadc1, (uint32_t*)&adc_buff, ADC_NUM_MAX);    // 开始 ADC 采样
}

获取电流值

int32_t get_curr_val(void)
{static uint8_t flag = 0;static uint32_t adc_offset = 0;    // 偏置电压int16_t curr_adc_mean = 0;         // 电流 ACD 采样结果平均值curr_adc_mean = adc_mean_sum / adc_mean_count;    // 保存平均值adc_mean_count = 0;adc_mean_sum = 0;if (flag < 17){adc_offset = curr_adc_mean;    // 多次记录偏置电压,待系统稳定偏置电压才为有效值flag += 1;}if(curr_adc_mean>=adc_offset){curr_adc_mean -= adc_offset;                     // 减去偏置电压}else{curr_adc_mean=0;}float vdc = GET_ADC_VDC_VAL(curr_adc_mean);      // 获取电压值return GET_ADC_CURR_VAL(vdc);
}

#define VREF 3.3f // 参考电压,理论上是3.3,可通过实际测量得3.258
#define GET_ADC_VDC_VAL(val) ((float)val/(float)65536.0*VREF) // 得到电压值

#define GET_ADC_CURR_VAL(val) (((float)val)/(float)8.0/(float)0.02*(float)1000.0)
// 得到电流值,电压放大8倍,0.02是采样电阻,单位mA。

#define GET_VBUS_VAL(val) (((float)val-(float)1.24) * (float)37.0) // 电压最大值(测量电压是电源电压的1/37)

读取电压

/*** @brief  获取电源电压值* @param  无* @retval 转换得到的电流值*/
float get_vbus_val(void)
{float vdc = GET_ADC_VDC_VAL(vbus_adc_mean);      // 获取电压值return GET_VBUS_VAL(vdc);
}

电机学习笔记 ADC dma 电流电压采集相关推荐

  1. 嵌入式学习笔记——ADC模数转换器

    ADC模数转换器 前言 ADC介绍 ADC概述 ADC的数量 ADC的特性 ADC框图 芯片外部框图 芯片内部框图 转换部分框图 状态输出部分 条件触发框图 寄存器介绍 编程思路 模式选择 规则通道的 ...

  2. STM32F4 ADC+DMA单通道采集

    背景:对锂电池电压进行采集,由于电池电压为12V,已经提前对12V进行分压,保证ADC采集电压的范围为0~3.3V.对电池电压的采集不用太过频繁,循环模式下的ADC+DMA对一直采集电压浪费资源.于是 ...

  3. 新唐芯片学习笔记——ADC

    新唐芯片学习笔记--ADC 概述 NuMicro®NUC029xAN 包含一个12位逐次逼近型模数转换器(SAR A/D转换器) ,包含8个输入通道:NuMicro®NUC029FAE 包含一个10位 ...

  4. 虹科多功能电流电压采集方案

    01电流电压采集基础概念和应用 电流采集.电压采集.电能充电量测试和功率测试在不同领域都有着广泛的应用 ▲汽车电子:电池管理系统BMS.发动机控制系统.车身电子系统 ▲航空航天:飞行控制系统,航空电源 ...

  5. STM8学习笔记---ADC多通道采样

    STM8S003单片机ADC采样通道总共有5个,从AIN2---AIN6,多通道采样时需要将ADC转换设置为单次转换模式,每次切换采样通道后,需要重新初始化 ADC,采样结果在中断中读取. IO口初始 ...

  6. 【GD32F427开发板试用】INA226完成电流电压采集

    本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:จุ๊บ冰语 前言 本次有幸参与并通过了极术社区组织的[GD32F427开发板试用]活动 ...

  7. stm32学习笔记---ADC电压采集

    1.  ①电压输入范围 ADC 输入范围为:VREF- ≤ VIN ≤ VREF+.由 VREF-.VREF+ .VDDA .VSSA.这四个外部 引脚决定. 我们在设计原理图的时候一般把 VSSA ...

  8. 学习笔记:INA219电流采集方案实现

    本篇为第二篇,主要介绍INA219模块的使用. 一. 模块各地址简单介绍 1.设备地址 模块上有两个点A1和A0,可以接Vs+,GND,SDA,SCL,总共有4*4=16种接法,对应图中的SLAVE ...

  9. 电路邱关源学习笔记——1.2电流和电压的参考方向

    电路中主要的物理量有电压.电流.电荷.磁链.能量.电功率等.在线性电路分析中人们主要关心的物理量是电流.电压.功率. 1.电流的参考方向  i(t)=limΔ

最新文章

  1. jQuery11 data() : 数据缓存
  2. editorconfig常用配置
  3. fiddler设置https抓包
  4. 改善用户体验之Alert提示效果
  5. oracle数据泵导入很慢,impdp导入效率的问题
  6. 1、Flutter_初体验_创建第一个应用_AndroidStudio_windows
  7. 图片压缩软件_简单易用的图片压缩软件gt;给图片减肥
  8. border:0 none,border:none;,border:0;三者之间的区别
  9. 地图测量面积工具app_【第288期】GPS工具箱(GPS精准定位工具)
  10. windos读写ext3工具_“ ext2fsd” Windows系统工具,用于读写ext2 / 3/4文件系统
  11. 【资源分享】Dll Injector(DLL注入器)
  12. 搜狗站群代码之搜狗批量推送工具
  13. 计算机常用英语词汇 短语,四级英语常用词汇短语
  14. OpenStack报错:MessagingTimeout: Timed out waiting for a reply to message ID
  15. 在ubuntu中添加widows启动项的简单方法
  16. 债券价格和到期收益率的关系_债券价格与到期收益率之间的关系.PPT
  17. Embedding Propagation: Smoother Manifold for Few-Shot Classification ECCV 2020
  18. 苹果圆圈怎么设置_苹果手机白色圆圈怎么弄
  19. 【面试题001】最强java八股文
  20. mysql判断纯数字_MYSQL中判断字符串是否为纯数字

热门文章

  1. vb用txt打开html文件,VB打开记事本程序源码,即用VB调用记事本,或用记事本打开一个txt文本文件。...
  2. Python 摄像头实时识别数字
  3. Skimage图像处理教程5)形态学运算
  4. android多国语言翻译工具,一键生成28国家翻译6666翻车了
  5. 商标右上角TM是什么意思
  6. 【阅读笔记】联邦学习实战——联邦学习医疗健康应用案例
  7. SV 绿皮书 浅碎记
  8. 辞暮尔尔烟火年年,朝朝暮暮岁岁平安。(2022年度总结)
  9. 2021-11-25 2021年压力管道巡检维护新版试题及压力管道巡检维护免费试题
  10. oracle max decode竖表改横表