我是靠谱客的博主 现实期待,最近开发中收集的这篇文章主要介绍STM32 ADC输入采集电压Verf:Vref就是指输入的模拟电压的最大值, 用于比较输入电压, ADC的输入的有效范围:0-Vref, 如果是10bit ADC,Vref=5v, 2^10(1024):5v, 那么ADC的分辨率为5/1024=0.00488v,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
#include "stm32f10x.h" // Device header
#include "stdio.h"
#include "delay.h"
/*********************串口调试输出**********************/
void led()//led PE5初始化
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOE,&GPIO_InitStruct);
}
void CUSART_init()//串口初始化函数
{
GPIO_InitTypeDef GPIO_InitStruct;//GPIO结构体
USART_InitTypeDef USART_InitStruct;//USART结构体
NVIC_InitTypeDef NVIC_InitStruct;//中断结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;//设置RX,TX端口串口使能
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//设置端口浮空输入
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;//设置RX,TX端口串口使能
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
USART_InitStruct.USART_BaudRate=9600;//波特率
USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流设置
USART_InitStruct.USART_Mode=USART_Mode_Tx | USART_Mode_Rx;//设置串口模式
USART_InitStruct.USART_Parity=USART_Parity_No;//不使用奇偶校验
USART_InitStruct.USART_StopBits=USART_StopBits_1;//设置停止位 1
USART_InitStruct.USART_WordLength=USART_WordLength_8b;//传输或接受传输数据位
USART_Init(USART1,&USART_InitStruct);
USART_Cmd(USART1,ENABLE);//使能串口
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启串口接受中断
NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStruct);
}
#define USAERT_REC_LEN 200
unsigned char USART_RX_BUF[USAERT_REC_LEN]; //接受缓冲
unsigned int USART_RX_STA =0; //接受状态标志位
/*
USART_RX_STA 定义为一个 16进制的标志位
接收到 0x8000 为 1000 0000 0000 0000 最高位(第15位)接收到1,表示接受完成
接收到 0x4000 同上第14位接收到1,表示接受到0x0d
0d 表示回车
oa 表示换行
以0d,0a结尾表示接收完成
注意:蓝牙和STM32的波特率必须一致
如需使用蓝牙app与MCU通信将TX接到RX
*/
void USART1_IRQHandler()//串口一中断服务函数
{
unsigned char res; //将接受的数据存放data
if(USART_GetITStatus(USART1,USART_IT_RXNE)!= RESET)//接受的数据以0x0d,0x0a结尾
{
res=USART_ReceiveData(USART1);//读取接受数据
if((USART_RX_STA&0x8000)==0)//接受未完成
{
if(USART_RX_STA&0x4000)//接收到0x0d
{
if(res != 0x0a)//如果未接受到0x0a
{
USART_RX_STA=0;
}
else
{
USART_RX_STA|=0x8000;//接收完成
}
}
else//如果未接受到0x0d
{
if(res==0x0d)//接收到了
{
USART_RX_STA|=0x4000;
}
else
{
USART_RX_BUF[USART_RX_STA&0x3ffff]=res;// 0011 1111 1111 1111,储存数据个数
USART_RX_STA++;//接受到的有效数据个数+1
GPIO_SetBits(GPIOE,GPIO_Pin_6);//关闭led
if(res== 0x45)//HC-05接收到0x45这个数据
{
GPIO_SetBits(GPIOE,GPIO_Pin_5);//关闭led
}
if(USART_RX_STA>(USAERT_REC_LEN-1))//接收数据出错,重新开始接受
{
USART_RX_STA=0;
}
}
}
}
USART_SendData(USART1,res);//将储存的数据发送出去
}
}
// 发送数据
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (unsigned char) ch);// USART1 可以换成 USART2 等
while (!(USART1->SR & USART_FLAG_TXE));
return (ch);
}
// 接收数据
int GetKey (void) {
while (!(USART1->SR & USART_FLAG_RXNE));
return ((int)(USART1->DR & 0x1FF));
}
/****************************ADC转换********************************************/
void Adc_cfg()
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode =DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
// ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
}
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}
u16 Count_AdcVal(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc(ch);
Delay_ms(5);
}
return temp_val/times;;
}
int main()
{
float temp;
u16 value;
Adc_cfg();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
CUSART_init();
led();
GPIO_ResetBits(GPIOE,GPIO_Pin_5);
printf("Set OK!n");
while(1)
{
Delay_ms(500);
value=Count_AdcVal(ADC_Channel_1,20);
temp=(float)value * 3.3/4096;
printf("%2.2ft",temp);
Delay_ms(500);
}
}
接线:ADC1电压采集端口PA1
坑:程序无问题,如遇到PA1接GND不为0V,只需将Verf接至3.3V,作为芯片的外部参考基准输入。把这两者连接,就是使用Vref作为参考基准
Verf:Vref就是指输入的模拟电压的最大值, 用于比较输入电压, ADC的输入的有效范围:0-Vref, 如果是10bit ADC,Vref=5v, 2^10(1024):5v, 那么ADC的分辨率为5/1024=0.00488v
最后
以上就是现实期待为你收集整理的STM32 ADC输入采集电压Verf:Vref就是指输入的模拟电压的最大值, 用于比较输入电压, ADC的输入的有效范围:0-Vref, 如果是10bit ADC,Vref=5v, 2^10(1024):5v, 那么ADC的分辨率为5/1024=0.00488v的全部内容,希望文章能够帮你解决STM32 ADC输入采集电压Verf:Vref就是指输入的模拟电压的最大值, 用于比较输入电压, ADC的输入的有效范围:0-Vref, 如果是10bit ADC,Vref=5v, 2^10(1024):5v, 那么ADC的分辨率为5/1024=0.00488v所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复