模拟技术
本文介绍STM8L051F3的ADC相关知识。内容分为以下几部分:
ADC(Analog-to-Digital Converter):模拟-数字转换,就是把模拟信号转换为数字信号。STM8L051F3的ADC可以执行在单次或连续模式,主要特点如下:
ADC开-关控制。ADC可以设置ADC_CR1寄存器的ADON位上电,当ADON位被设置,ADC会从掉电模式下唤醒。ADC转换应该发生在在上电唤醒后最大空闲时间前。当ADON位被复位,ADC将停止转换并进入掉电模式。
单次转换模式。在这个模式下,在ADC_SQRx寄存器中只能选择一个输入通道(如果有多个通道被选择,最高的通道有效),然后ADC_SQR1寄存器的DMAOFF位必须设置(禁止DMA),输入通道转换后就会停止,转换后的值保存在ADC_DR数据寄存器,在转换完成之后可以产生一个(EOC)中断。两次转换的时间必须小于ADC最大空闲延迟(t IDLE )
连续转换模式。在这个模式下,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模块的框图如下所示:
本小节介绍如何配置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采样值
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),可参考第九章内容。
全部0条评论
快来发表一下你的评论吧 !