打印

【连载】STM8L051F3_11_ADC应用

[复制链接]
1024|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
caijie001|  楼主 | 2018-5-24 18:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本文介绍STM8L051F3的ADC相关知识。内容分为以下几部分:
  • ADC简介
  • ADC单通道软件触发采样
1、STM8L的ADC基础知识ADC(Analog-to-Digital Converter):模拟-数字转换,就是把模拟信号转换为数字信号。STM8L051F3的ADC可以执行在单次或连续模式,主要特点如下:
  • 可配置的转换精度(最高12位)
  • 众多模拟通道
  • 两个内部通道连接到温度传感器和内部参考电压
  • 可配置单次或连续转换
  • 可预分频ADC时钟
  • 模拟看门狗
  • 在转换结束、看门狗或溢出时间可独立产生中断
  • 多通道转换(扫描模式)
  • 数据完整性
  • DMA功能
  • 施密特触发器禁止功能
  • 转换时间在系统时钟=16MHz时可达1us
  • 电压范围在8V~3.6V:
    • 最大的转换率在4V~3.6V中获得
    • 8V~2.4V时,ADC处于低速模式
    • 低于8V时ADC功能无法保障
ADC开-关控制。ADC可以设置ADC_CR1寄存器的ADON位上电,当ADON位被设置,ADC会从掉电模式下唤醒。ADC转换应该发生在在上电唤醒后最大空闲时间前。当ADON位被复位,ADC将停止转换并进入掉电模式。
单次转换模式。在这个模式下,在ADC_SQRx寄存器中只能选择一个输入通道(如果有多个通道被选择,最高的通道有效),然后ADC_SQR1寄存器的DMAOFF位必须设置(禁止DMA),输入通道转换后就会停止,转换后的值保存在ADC_DR数据寄存器,在转换完成之后可以产生一个(EOC)中断。两次转换的时间必须小于ADC最大空闲延迟(tIDLE)
连续转换模式。在这个模式下,ADC转换完成后不会停止,而是继续进入下一个所选的通道序列,转换持续到CONT位和ADON位被设置和转换结果经过DMA发送到RAM或EEPROM。只有每次所选的通道序列转换完成后EOC中断才会产生,每个通道转换的结果不能从ADC_DR寄存器中读取。为了保存每个通道的转换结果在存储器(RAM或EEPROM)中,DMA必须使用在外设到内存模式,如果在转换过程中CONT位被复位,那么当前选择的通道序列在最后一个选择通道转换完后结束转换,然后ADC停止。
通道选择(扫描模式)。该模式在连续模式下自动工作,也可以通过复位ADC_SQR1寄存器DMAOFF位来工作在单次转换模式。在该模式下,将选择的通道序列(如单次模式)转换完成后经过DMA把数据发送到内存中。在so秒模式下选择通道或者通道的顺序相关的寄存器有三个:ADC_SQR1、ADC_SQR2和ADC_SQR3。
ADC还有时钟配置、模拟看门狗、中断、数据完整性、DMA传送、分辨率配置、数据对齐、可编程的采样时间,施密特触发器、内部的温度传感器、内部的参考电压、低功耗模式、中断等内容,用户可以参考官方手册RM0031的第14章。ADC模块的框图如下所示:


2、ADC单通道软件触发采样2.1 ADC配置本小节介绍如何配置ADC1的通道22(PD0)为单次转换模式模式,软件触发,并把在ADC1上采集的数据在OLED上显示出来。使用的例程:STM8L051F3_11_ADC。在单次模式下ADC1的配置步骤为(非中断模式):
1)打开ADC1外设时钟
2)初始化ADC1通道22的IO口(配置为浮空输入模式)
3)初始化ADC1:单次转换模式,分辨率12位,ADC时钟2分频
4)配置ADC1采样时间
5)打开ADC1通道22
6)使能ADC1
ADC1采样控制步骤如下:
1)启动ADC1转换
2)等待转换结束
3)读取ADC1采样值
2.2 例程介绍ADC1的配置与采样函数都在adc.c文件实现:
ADC1配置函数:
void ADC1_Config(void)
{
  //打开ADC1外设的时钟
  CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);
  //配置ADC1的GPIO为浮空输入模式
  GPIO_Init(ADC_IN22_GPIO_PORT, ADC_IN22_GPIO_PINS, GPIO_Mode_In_FL_No_IT);
  //初始化ADC1,单次转换模式,12位分辨率,ADC时钟2分频
  ADC_Init(ADC1, ADC_ConversionMode_Single, ADC_Resolution_12Bit, ADC_Prescaler_2);
  //配置ADC采样时间,384个时钟周期
  ADC_SamplingTimeConfig(ADC1, ADC_Group_SlowChannels, ADC_SamplingTime_384Cycles);
  //打开ADC1的22通道
  ADC_ChannelCmd(ADC1, ADC_Channel_22, ENABLE);
  //使能ADC1
  ADC_Cmd(ADC1, ENABLE);
}
ADC1采样函数:
uint16_t Read_ADC_Value(void)
{
  uint16_t temp;
  //启动一次ADC转换
  ADC_SoftwareStartConv(ADC1);
  //等待转换结束
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)== RESET);
  //读取ADC值
  temp = ADC_GetConversionValue(ADC1);
  //返回ADC值
return temp;
}
在主函数中,每300ms采样移植,把采样的ADC值与计算后的值在OLED上显示出来,主函数如下:
void main(void)
{
  uint32_t ADC_Value;
  uint32_t Vol_Value;
  LED_Init();   //初始化LED
  IIC_Init();   //IIC初始化
  ADC1_Config();     //初始化ADC
  OLED_Init();  //OLED初始化
  OLED_Clear(); //OLED清屏
  OLED_ShowString(16, 0, "D-VALUE:");
  OLED_ShowString(16, 2, "V-VALUE:");
while(1)
{
    ADC_Value = Read_ADC_Value();       //读取ADC值
    Vol_Value =(ADC_Value * 3300 / 4096);      //转换为电压值,单位mV
    OLED_ShowNum(80, 0,ADC_Value, 4, 16);       //OELD显示ADC值
    OLED_ShowNum(80, 2,(uint16_t)Vol_Value, 4, 16);     //OLED显示电压值
    GPIO_ToggleBits(LED1_GPIO_PORT, LED1_GPIO_PINS);    //改变LED1状态
    delay_ms(300);      //延迟
}
}
使用ST-LINK把程序下载到开发板,LED1闪烁,把PD0口用杜邦线接到VCC可以看到OLED上显示D-VALUE::4096(可能会有一点误差),V-VALUE:3300(可能会有一点误差)。把PD0口用杜邦线接到GND可以看到OLED上显示D-VALUE::0(可能会有一点误差),V-VALUE:0(可能会有一点误差)。注:OLED采用的是技新0.96寸OLED(4PIN),可参考第九章内容。



相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:21ic公开课专区:http://open.21ic.com/ 21ic资料下载中心:http://dl.21ic.com/ 21ic项目外包中心:http://project.21ic.com/ 杰杰欢迎大家有空常来赛事专区逛逛

131

主题

3790

帖子

63

粉丝