基于STM32的AD单通道

一、ADC的基本介绍

ADC模拟->数字转换

ADC可以将模拟信号转换为数字信号。

而DAM则是相反,将数字信号转换为模拟信号。

下图为ADC基本结构

 左边是输入通道,16个GPIO口,外加两个内部的通道。

然后进入AD转换器,AD转换器里有两个组,一个是规则组,一个是注入组,规则组最多可以选择16个通道,注入组最多可以选择4个通道,转换的结果可以存放在AD数据寄存器里。

AD数据寄存器中可以存放一个规则组结果,四个注入组结果。转换完成后会有EOC信号,会置一个标志位,通向NVIC。

模拟看门狗用于监测转换结果的范围,如果超出设定的阈值,就通过中断输出控制,向NVIC申请中断。

START触发控制可以选择软件触发和硬件触发。软件触发可以直接使用软件进行触发,即在软件中进行使用库函数;硬件触发主要是来自定时器,也可以用外部中断的引脚。

RCC内部时钟推动ADC逐次比较。

右下角的开关控制在库函数中就是ADC_Cmd(),用于给ADC上电的。

二、ADC的转化时间

ADC转换的步骤:采样->保持->量化->编码

ADC转换的时间即在量化编码之前设置一个采样开关,收集外部电压。当外部电压被存储好后,断开采样开关,再进行AD转换。(在量化编码的过程中,电压始终保持不变。)

所以打开采样开关收集外部电压到断开采样开关进行AD转换的时间就为ADC的转换时间。

本文中使用的ADCCLK = 72MHz / 6 = 12MHz

转换时间:采样时间 + 固定周期(12.5)= 55.5+12.5=68

68/12MHz=5.6us

三、代码部分

AD:

首先是初始化部分

void AD_Init(void)
{
/*GPIO初始化*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//ADC专属通道
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PA0
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
	
/*ADC初始化*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//ADC分频时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//6分频
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);//ADC1通道0 序列1,采样时钟55
	
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//非扫描模式(单通道)
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//同上
ADC_InitStructure.ADC_NbrOfChannel = 1;//同上
ADC_Init(ADC1, &ADC_InitStructure);
	
ADC_Cmd(ADC1, ENABLE);
	
ADC_ResetCalibration(ADC1);//复位校准
while (ADC_GetResetCalibrationStatus(ADC1) == SET);//等待校准完成
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) == SET);
}

然后是获取AD转化值部分

/*读取ADC转换后的数据*/
uint16_t AD_GetValue(void)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //触发转换
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);        //等待转换5.6us
return ADC_GetConversionValue(ADC1);
}

main:

int main(void)
{
	AD_Init();
	OLED_Init();
	OLED_ShowString(1,1,"ADValue:");
	while (1)
	{
	OLED_ShowNum(1,9,AD_GetValue(),4);	
	}
}

四、现象

接线图如下

STM32F103C8T6外接一个电位器和一个OLED显示AD值。

当用螺丝刀向左旋转电位器时,AD值变小;向右则变大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值