STM32只能采集0-3.3V的数据,如果需要采集0-5V和4-20mA的数据需要在电路中进行相关设计:
0-5V采集电路
4-20mA采集电路
本文主要讲述4-20mA采集电路采集
电路输入4-20mA,作用在120欧姆电路(后面面是电压跟随电路,并联),对应输入电压0.48~2.4V
STM32103ZET6为例,内部ADC采集12bit,0-3.3V对应采集到12bit的0-4095数值,则采集的电流对应大约为0.48/3.3*4059~2.4/3.3*4095-->595~2978数值
假如我们是采集的0-6Mpa的压力,那么简单的换算为:文章来源:https://www.toymoban.com/news/detail-848801.html
(采集的数值-595)*6000000/(2978-595)=采集的压力(pa)文章来源地址https://www.toymoban.com/news/detail-848801.html
代码如下:代码需要将GPIO和ADC和DMA根据自己的电路接口简单配置即可
ADC.c代码,两个函数分别是ADC+DMA初始化代码和ADC采集一次代码
#include "stm32f10x.h" // Device header
#include "Serial1.h"
extern uint16_t AD_Value[4];//压力变送器Kpa4095*6000//温度℃4095*200
extern uint16_t AD_ValueTrasition[4][20];
void AD_Init(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div8);//ADCCLK=APB2/8=14MHz
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
GPIO_InitTypeDef GPIO_InitStructureADC;
GPIO_InitStructureADC.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStructureADC.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructureADC.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructureADC);
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_13Cycles5);//采集总转换时间=采样时间+12.5ADC周期=13.5+12.5=26个周期
ADC_RegularChannelConfig(ADC1,ADC_Channel_11,2,ADC_SampleTime_13Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_13,3,ADC_SampleTime_13Cycles5);//一个ADC周期14MHz=1/14 us每周期=26/14 us≈1.9us
ADC_RegularChannelConfig(ADC1,ADC_Channel_14,4,ADC_SampleTime_13Cycles5);//1.9*4=7.6us
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//连续转换开启/单次转换;
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//是否使用硬件触发;目前该程序使用软件触发
ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//独立模式,ADC1单独使用,不和ADC2等一起使用
ADC_InitStructure.ADC_NbrOfChannel=4;//非扫描模式下该参数无效,用于重装载扫描序列数
ADC_InitStructure.ADC_ScanConvMode=ENABLE;//扫描模式(多通道)/非扫描模式(单通道),指扫描序列
ADC_Init(ADC1,&ADC_InitStructure);
//如果需要配置看门狗,有几个参数需要配置阈值和监测通道。
//如果需要配置中断,则需要在中断输出控制中用ITConfig函数开启对应的中断输出,然后配置NVIC的优先级
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_BufferSize=4;//缓冲区大小,传输计数器次数,0-65535,2个ADC通道所以传输2次
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//传输方向;外设站点作为源
DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//是否使用软件触发(软件触发和计数器自动重装循环模式不能同时使用,会不能停止)
DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)AD_Value;//存储器站点的起始地址,stm32中地址都是32bit,AD_Value是我们存储转移的地址
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//存储器站点的数据宽度
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//存储器站点是否自增,数组地址会自增
DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)&ADC1->DR;//外设站点的起始地址,一般使用SARM的话是系统分配,使用变量名获取地址
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//外设站点的数据宽度,Byte-8bit-uint8_t、HalfWord-16bit-uint16_t、Word-32bit-uint32_t;(ADC外设是12bit数据,具体的DMA数据转移对齐,可以看DMA数据宽度对齐方式大小端表格)
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设站点是否自增,ADC开启DMA后数据直接转移到DMA,所以不自增
DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//传输模式,是否使用自动重装,自动重装和软件触发不能同时使用(不可控),Normal正常模式,Circular循环模式
DMA_InitStructure.DMA_Priority=DMA_Priority_High;//优先级
DMA_Init(DMA1_Channel1,&DMA_InitStructure);//DMA1,使用软件触发时通道可以任意选择,硬件要根据手册中实际电路选择;目前使用ADC1-13、14触发DMA
//开启,如果使用的硬件触发,要在对应外设调用XXX_DMACmd(),开启触发信号输出,如果使用DMA中断,则使用DMA_ITConfit(),然后在NVIC配置响应的中断通道,然后写中断函数
DMA_Cmd(DMA1_Channel1,ENABLE);
//开启ADC到DMA触发输出
ADC_DMACmd(ADC1,ENABLE);
//开启ADC。可以软件触发也可以硬件触发。
ADC_Cmd(ADC1,ENABLE);
//进行ADC校准
ADC_ResetCalibration(ADC1);//ADC1复位校准
while(ADC_GetResetCalibrationStatus(ADC1)){//获取复位校准状态;等待复位校准完成
;
}
ADC_StartCalibration(ADC1);//开始校准
while(ADC_GetCalibrationStatus(ADC1)){//获取开始校准状态;等待校准完成
;
}
}
void AD_Once(void){
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件开始ADC转换
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC==RESET)){;}
ADC_SoftwareStartConvCmd(ADC1,DISABLE);//软件停止ADC转换
}
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "ADC.h"
#include "MySPI1.h"
#include "Serial1.h"
//需要将该文件中的USE_STDPERIPH_DRIVER定义在define的设置里 这样才能使用外设库
//若是导入了头文件需要设置头文件包含路径
extern uint16_t MAX31855KASA_In_Temp,MAX31855KASA_Out_Temp;
extern uint16_t AD_Value[4];
extern uint16_t AD_ValueTrasition[4][20];
uint8_t SendData[30];
int main(void){
Serial_Init();
MySPI_Init();
AD_Init();
while(1){
Delay_ms(1);
AD_Transition();
Serial_printf("%s","压力Kp为:");
Serial_printf("%d",AD_Value[2]);
Serial_printf("%s","\r\n");
Serial_printf("%s","温度为:");
Serial_printf("%d",AD_Value[3]);
Serial_printf("%s","\r\n");
Delay_ms(500);
}
}
到了这里,关于STM32采集4-20mA传感器,以及ADC+DMA出现的问题及解决的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!