历史上的今天
返回首页

历史上的今天

今天是:2025年08月13日(星期三)

正在发生

2019年08月13日 | STM32-(29):ADC模数转换(实验)

2019-08-13 来源:eefocus

ADC的重要寄存器介绍

在这里插入图片描述
AWDEN:在规则通道上开启模拟看门狗
该位由软件设置和清除。
0:在规则通道上禁用模拟看门狗
1:在规则通道上使用模拟看门狗

DUALMOD[3:0]:双模式选择
软件使用这些位选择操作模式
在这里插入图片描述
SCAN:扫描模式
该位由软件设置和清除,用于开启或关闭扫描模式。在扫描模式中,由ADC_SQRx或ADC_JSQRx寄存器选中的通道被转换。
0:关闭扫描模式
1:使用扫描模式
注:如果分别设置了EOCIE或JEOCIE位,只在最后一个通道转换完毕才会产生EOC或JEOC中断。

JEOCIE:允许产生注入通道转换结束中断
该位由软件设置和清除,用于禁止或允许所有注入通道转换结束后产生中断。
0:禁止JEOC中断
1:允许JEOC中断。当硬件设置JEOC位时产生中断。

EOCIE:允许产生EOC中断
该位由软件设置和清除,用于禁止或允许转换结束后产生中断。
0:禁止EOC中断
1:允许EOC中断。当硬件设置EOC位时产生中断。

AWDCH[4:0]:模拟看门狗通道选择位
在这里插入图片描述
注意:STM32的内部参照电压VREFINT和ADCx_IN17相连接,它的作用是相当于一个标准电压测量点,内部参照电压VREFINT只能出现在主ADC1中使用。
在这里插入图片描述
ADCON 位用于开关 AD 转换器。而 CONT 位用于设置是否进行连续转换,我们使用单次转换,所以 CONT 位必须为0。 CAL 和 RSTCAL 用于 AD 校准 。ALIGN用于设置数据对齐,我们使用右对齐,该位设置为0。

EXTSEL [2:0] 用于选择启动规则转换组转换的外部事件。
在这里插入图片描述
使用的是软件触发(SWSTART),所以设罝这3个位为111,ADC_CR2的SWSTART位用于开始规则通道的转换,我们每次转换(单次转换模式下)都需要向该位写1。TSVREFE为用于使能温度传感器和 Vref.

在这里插入图片描述

时间计算

对于毎个要转换的通道,采样时间建议尽量长一点,以获得较高的准确度,但是这样会降低ADC的转换速率,ADC的转换时间可以由下式计算:
Tcovn=采样时间+12.5个周期(12.5是量化周期,固定的,采用逐次逼近)
其中:Tcovn为总转换时间, 采样时间是根据毎个通道的SMP位的设置来决定的.例如,当ADCCLK=14Mhz的时候,并设置 1.5个周期的采样时间,则得到:Tcovn=l.5+12.5=14个周期=1 us. 采样越慢,精度越高,因为抗干扰能力越强。

在这里插入图片描述
ADC_SQR2、3是定义余下的转换

在这里插入图片描述
规则序列中的AD转化结果都被存在这个寄存器里面,而注入通道的转换结果被保存在ADC_JDRx里面。
该寄存器的数据可以通过 ADC_CR2的ALIGN 位设置左对齐还是右对齐,在读取数据的时候要注意。

在这里插入图片描述
在这里插入图片描述

实验

单次转换出电压数据,JP2跳到滑动电阻端,测量数据显示在数码管上。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
** ADC2连接的是CPU上的PC5,输入通道15(IN15)**

简析:右下角的ADC2 是外部给的信号,JP2连接到滑动变阻器一端时,可以通过改变滑动变阻器的位置,改变出来的电压。R36的作用是限流,防止外部给的信号电流过大。VIN2是外部测量使用的,用于校对电压值是否准确。

ADC1扩展

在这里插入图片描述
ADC1与ADC2相比多了一个U5 数字电位器,可以将外部电压按比例降低,这样就可以测量更宽范围的电压。

代码:

main.c

/* Includes ------------------------------------------------------------------*/

#include "stm32f10x_lib.h"   //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。

#include

 

void Delay_Ms(u16 time);

void RCC_Configuration(void);

void GPIO_Configuration(void);

void NVIC_Configuration(void);


extern void ADC_Configuration(void);

extern u16 Test_ConversionResult(void);

extern void SMG_Init(void);

extern void NumbTube_Display(u32 data,u8 radix_point);


/* Private functions ---------------------------------------------------------*/ 

/*******************************************************************************

* Function Name  : main

* Description    : Main program.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

int main(void)

{

#ifdef DEBUG

  debug();

#endif


u32 ConversionValue;

  RCC_Configuration();    //使能外设时钟

NVIC_Configuration();

SMG_Init(); //数码管初始化

ADC_Configuration(); //ADC初始化

 // GPIO_Configuration();   //初始化GPIO管脚


  while (1)

  {

ConversionValue = (u32)Test_ConversionResult();


//ConversionValue = ConversionValue * 1000; 

NumbTube_Display(ConversionValue,4); //在数码管中显示,第二个参数4是指位数

  }

}


/*******************************************************************************

* Function Name  : Delay_Ms

* Description    : delay 1 ms.

* Input          : time (ms)

* Output         : None

* Return         : None

*******************************************************************************/

void Delay_Ms(u16 time)  //延时函数

u16 i,j;

for(i=0;i  for(j=1000;j>0;j--);

}


/*******************************************************************************

* Function Name  : RCC_Configuration

* Description    : Configures the different system clocks.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void RCC_Configuration(void) 

{

//=============================== 使用内部RC晶振 ===================================

    /*   

RCC_HSICmd(ENABLE);//使能内部高速晶振 ;

  RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);//选择内部高速时钟作为系统时钟SYSCLOCK=8MHZ

RCC_HCLKConfig(RCC_SYSCLK_Div1);//选择HCLK时钟源为系统时钟SYYSCLOCK

  RCC_PCLK1Config(RCC_HCLK_Div4);//APB1时钟为2M 

  RCC_PCLK2Config(RCC_HCLK_Div4);//APB2时钟为2M

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);//使能APB2外设GPIOB时钟

*/


//==========================使用外部RC晶振========================================

  RCC_DeInit(); //初始化为缺省状态

  RCC_HSEConfig(RCC_HSE_ON);  //高速时钟使能

  while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);  //等待高速时钟使能就绪


    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer 

    FLASH_SetLatency(FLASH_Latency_2);   // Flash 2 wait state 

    RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK 

    RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK 

    RCC_PCLK1Config(RCC_HCLK_Div2);   // PCLK1 = HCLK/2 

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // PLLCLK = 8MHz * 9 = 72 MHz  

    RCC_PLLCmd(ENABLE);   // Enable PLL 

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // Wait till PLL is ready 


    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);   // Select PLL as system clock source 

    while(RCC_GetSYSCLKSource() != 0x08); // Wait till PLL is used as system clock source 


//====================================================================================

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); // 使能APB2外设GPIOC时钟

}


/*******************************************************************************

* Function Name  : GPIO_Configuration

* Description    : 初始化GPIO外设

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void GPIO_Configuration(void)

{


  GPIO_InitTypeDef GPIO_InitStructure; // 声明一个结构体变量

    //==========为结构体成员填入相应的值============

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管脚频率为50MHZ

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //模式为推挽输出

  GPIO_Init(GPIOA, &GPIO_InitStructure);    //初始化GPIOB寄存器

}


void NVIC_Configuration(void)

{

   

#ifdef  VECT_TAB_RAM  

  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 

#else

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   

#endif

}


ADC.c

#include"stm32f10x_lib.h"


/***********************************************************

* 函数名称:void ADC_Configuration(void)

* 功能描述:ADC模数转换

* 入口参数:无

* 出口参数:无

***********************************************************/

void ADC_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

ADC_InitTypeDef ADC_InitStructure;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);   //开启ADC1的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);  //开启GPIOC的时钟

  

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PC5

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;  //配置成模拟输入

GPIO_Init(GPIOC,&GPIO_InitStructure);


ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式

ADC_InitStructure.ADC_ScanConvMode = ENABLE; //连续多通道模式

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换模式

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不受外界决定,设为软件触发

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐

ADC_InitStructure.ADC_NbrOfChannel = 1; //扫描通道数1

ADC_Init(ADC1,&ADC_InitStructure);

ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 1, ADC_SampleTime_55Cycles5);

//ADC1,   设定指定ADC的规则组通道15,顺序排在第一个,也只有一个,采样周期为55.5个周期

//ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 2, ADC_SampleTime_1Cycles5);//ADC1,

ADC_Cmd(ADC1,ENABLE); //使能指定ADC

ADC_SoftwareStartConvCmd(ADC1,ENABLE); //使能指定ADC的软件装换启动功能。


}

/***********************************************************

* 函数名称:u16 Test_ConversionResult(void)

* 功能描述:测试ADC转换的结果,通过数码管显示ADC采样的值

* 入口参数:无

* 出口参数: conresult

ADC转换的结果

***********************************************************/

u16 Test_ConversionResult(void)

{

u32 conresult=0;

u16 value;

if(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==SET)  //如果EOC置1,等于SET,说明转换完成

{

conresult = (u32)ADC_GetConversionValue(ADC1); //返回最近一次ADC组的转换结果

//2(12)=4096    VDD3.3v=3300mv  (右对齐,存储结果为12位,2的12次方为4096,均分3.3V)


conresult = conresult * 3300;

conresult = conresult / 4096; //先乘后除不容易丧失精度

}

ADC_ClearITPendingBit(ADC1,ADC_IT_EOC); //清除ADC的中断

return((u16)conresult);

}

相关固件函数:
在这里插入图片描述

推荐阅读

史海拾趣

Gould Fiber Optics公司的发展小趣事
可能是电源插头未插好、保险丝熔断、输入电压异常或电源内部元件损坏。
亿佰特(EBYTE)公司的发展小趣事

亿佰特始终坚持以质量为核心的发展理念。公司建立了严格的质量控制体系,从原材料采购到生产制造,再到产品检验,每一个环节都严格把关。通过精细化的管理,亿佰特确保了产品的优良品质。同时,公司还注重售后服务,为客户提供全方位的支持。正是凭借卓越的品质和优质的服务,亿佰特赢得了客户的信赖和市场的认可。

Celduc Relais公司的发展小趣事

Celduc Relais公司自创立之初,便以技术创新为核心驱动力。在公司的早期发展阶段,研发团队成功开发了一款具有颠覆性的继电器产品,该产品在性能、稳定性和寿命等方面均达到了行业领先水平。这一突破性的技术创新不仅为公司赢得了市场的广泛认可,也为后续的产品线扩展和技术升级奠定了坚实基础。

FTDI公司的发展小趣事

Celduc Relais公司注重企业文化的建设,倡导创新、协作、责任和卓越的核心价值观。公司通过举办各类文化活动、培训和学习等方式,提升员工的凝聚力和归属感。同时,公司还建立了完善的激励机制,鼓励员工积极创新、追求卓越。这一举措为公司的发展提供了强大的文化支撑和人才保障。

这五个故事只是Celduc Relais公司发展历程中的冰山一角,但它们足以展现出公司在技术创新、市场拓展、质量管理、环保理念和企业文化建设等方面的努力和成就。正是这些因素的共同作用,使得Celduc Relais公司在电子行业中脱颖而出,成为一家备受尊敬的企业。

EICHHOFF公司的发展小趣事

EICHHOFF公司成立于XX世纪XX年代,当时由创始人XXX在德国的一个小镇上开设了一个小型的电子元件加工厂。由于XXX对电子技术的热爱和对市场需求的敏锐洞察,他专注于生产高质量的连接器和其他电子组件。在初创阶段,EICHHOFF的产品主要供应给当地的电子制造商和维修店。随着口碑的逐渐传播和产品质量的不断提升,公司开始接到来自更广泛地区的订单。

为了应对不断增长的市场需求,EICHHOFF公司逐步扩大了生产规模,并引入了先进的生产设备和技术。同时,公司也注重人才培养和团队建设,吸引了一批有才华的工程师和技术人员加入。这些努力使得EICHHOFF在电子行业中逐渐崭露头角。

BURGESS公司的发展小趣事

BURGESS一直以其专业的服务和优质的管理而著称。它非常重视客户的需求和体验,为每一个拥有超级游艇的客户提供量身定制的服务方案。无论是游艇的销售、采购、租赁还是技术顾问和经营管理,BURGESS都能提供全面而专业的服务。这种对细节的关注和对质量的追求,使得BURGESS赢得了众多高端客户的信任和青睐,连美国总统特朗普的超级游艇都是由BURGESS负责管理的。

尽管无法提供BURGESS在电子行业的发展故事,但以上关于其在游艇经纪行业的几个重要发展事实,充分展示了BURGESS的卓越实力和专业水平。如需更多关于BURGESS的信息,建议查阅其官方网站或相关新闻报道。

问答坊 | AI 解惑

以7805为例 如何测量直流稳压器的最大输出电流

图中,7805的输入1脚接12V外加电源,3脚输出5V电压,这个用万用表的电压档一测就知道了,但是它的输出电流最大是多少呢? 答案是输出电流随负载的变化而变化,可是电流不能无限小和无限大吧?所以输出电流必定有个最小值和最大值。     ...…

查看全部问答>

高人请指点

#include #define uchar unsigned char uchar code  seg7[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar second ,minute,hour,count,m,num,num1,i,s,f; void delay() delay1s()         { ...…

查看全部问答>

我的VS2005怎么了?新建工程不行,打开工程不行(只限智能设备工程),报这样的错误"从用户数据存储中检索信息时出错。XML文档必须包含一个顶层元素".好怪!

我的VS2005怎么了?新建工程不行,打开工程不行(只限智能设备工程),报这样的错误\"从用户数据存储中检索信息时出错。XML文档必须包含一个顶层元素\".好怪!…

查看全部问答>

VISTA系统下安装 Tornado2.0后,运行时总出现 gdb error,是什么原因?

  运行Tornado时,总弹出好几个错误的对话框,标题为 gdb error!   内容为:Failed to register COM Server. Error code = ox8002801c   将对话框点掉之后 Tornado 就启动起来了,运行还算正常,但每次一启动就出 ...…

查看全部问答>

各位达人救救小弟则个

要求做一个动画控件。功能描述如下: 根据调用者的要求,决定图片显示的快慢,以及多少张图片循环显示以实现动画功能,同时根据图片要能自我缩放以匹配控件大小。控件大小由调用者决定! 有没有谁写过啊?各位达人救救我啊…

查看全部问答>

大学新生报名IT培训,职业规划从入学开始

本报讯: 日前,记者从国内著名的IT培训公司北大青鸟APTECH获悉,进入9月份以来,在一些城市出现了大量刚入学大学新生前来咨询职业培训,甚至已有人报名参加相关课程培训,在某些培训中心,这类刚入学大学新生在本阶段招生中已占到相当比例。IT职业 ...…

查看全部问答>

CS8900不能初始化,请高手指点一下

有谁做过TI的430以太网,就是easyweb那个解决方案,我的cs8900A始终不能初始化,在这个循环里跳不出来: do Write8900(ADD_PORT, PP_SelfST); // set register while (!(Read8900(DATA_PORT) & INIT_DONE)); // wait un ...…

查看全部问答>

短消息为什么没有提示音了?

RT?我觉得还是有提示音的好,这样一上线就能知道有消息了!~…

查看全部问答>

【MSP430共享】 MC430F224例程:Keys+LED演示

【例  程】://基于MC430F224开发板实验例程//软件:IAR Embedded Workbench Version: 3.42A//编写:微控设计网 www.Microcontrol.cn DC//目标板: MC430F224开发板 V1.0#include \"msp430x22x4.h\"//初级用户要习惯采用宏定义,以方便的编写 ...…

查看全部问答>

用msp430读写24c512程序

用msp430读写24c512程序 /*************************************************************文件名:msp430f169i2c.c*整体描述:MSP430F169单片机硬件IIC软件,字节方式,主方式* IIC接口:P3.3=SCL,P3.1=SDA;(开漏输出)* 相应寄存器:地址寄存器 I2C ...…

查看全部问答>