历史上的今天
今天是:2024年09月16日(星期一)
2021年09月16日 | STM8单片机ADC连续采样模式
2021-09-16 来源:eefocus
STM8S003单片机内部ADC为12位,A/D转换的各个通道可以执行单次和连续的转换模式。
单次转换模式的意思就是,ADC每次转换一次数据后,就会停止转换,如果还需要继续转换的话,就需要手动开启第二次转换功能。
连续转换模式的意思就是每次转换结束后,系统会自动开启第二次转换,不需要手动设置第二次转换的开启,也就是说连续转换模式只需要开启一次。
ADC框图如下:

ADC连续模式转换时序图如下:

通过时序图可以看出,在第2次转换完成后,第一次采样的结果才会输出,也就是结果输出比采样滞后了一个周期。
下面用代码来实现ADC的连续转换模式:
#include "adc.h"
#include "main.h"
u16 DATAH = 0; //ADC转换值高8位
u16 DATAL = 0; //ADC转换值低8位
_Bool ADC_flag = 0; //ADC转换成功标志
//AD通道引脚初始化
void ADC_GPIO_Init( void )
{
PD_DDR &= ~( 1 << 3 ); //PD3 设置为输入 电流
PD_CR1 &= ~( 1 << 3 ); //PD3 设置为悬空输入
}
//ch 为单片机的对应管脚
void ADC_CH_Init( u8 ch )
{
char l = 0;
ADC_CR1 = 0x00; //fADC = fMASTER/2, 8Mhz 单次转换,禁止转换
ADC_CR1 |= ( 1 << 1 ); //开启连续转换模式
ADC_CSR = ch + 1; //控制状态寄存器 选择要 AD输入通道 如:PD2(AIN3)
ADC_CR2 = 0x00; //默认左对齐 读数据时先读高在读低
ADC_TDRL = ( 1 << ( ch + 1 ) ); //禁止相应通道 施密特触发功能 1左移ch+1位
ADC_CR1 |= 0x01; //使能ADC并开始转换
//ADC_CSR |= 0x20; //EOCIE 使能转换结束中断 EOC中断使能
for( l = 0; l < 100; l++ ); //延时,保证ADC模块的上电完成 至少7us
ADC_CR1 = ADC_CR1 | 0x01; //再次将CR1寄存器的最低位置1 使能ADC 并开始转换
}
//采集PD3电压值
u16 ReadVol_CH3( void )
{
u16 voltage = 0;
if( ADC_CSR & 0x80 )
{
DATAH = ADC_DRH; // 读出ADC结果的高8位
DATAL = ADC_DRL; // 读出ADC结果的低8位
voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据 0--1024
ADC_CSR &= 0x7F;
};
return voltage;
}
连续转换模式,只需要开启一次转换,然后一直等待数据转换结束,读取数据就行。由于连续转换模转换速度和快,使用中断的话,系统中断太频繁,影响其他代码执行。所以可以不需要中断去读取数据,需要数据的时候直接判断转换结束标志位去读取数据就行。
ADC_CSR寄存器如下:

当ADC转换结束后ADC_CSR寄存器的EOC位就会置1,读取完采样结果后需要手动将EOC位清零。
由于连续转换模式在初始化之后只会转换当前通道,如果要切换到其他通道需要重新初始化ADC。
在主程序中直接调用通道读取函数就行。
#include "iostm8s103F3.h"
#include "led.h"
#include "adc.h"
#include "stdio.h"
void SysClkInit( void )
{
CLK_SWR = 0xe1; //HSI为主时钟源 16MHz CPU时钟频率
CLK_CKDIVR = 0x00; //CPU时钟0分频,系统时钟0分频
}
void main( void )
{
u16 val1 = 0;
u16 i=0;
u16 value[450]={0};
SysClkInit();
__asm( "sim" ); //禁止中断
LED_GPIO_Init();
ADC_CH_Init( 3 );
__asm( "rim" ); //开启中断
while( 1 )
{
LED = !LED;
for(i=0;i<450;i++)
{
val1 = ReadVol_CH3();
value[i]=val1;
}
i=0;
}
}
在主函数中连续读取450次采样的数据存储在数组中。
下一篇:STM8单片机ADC单次采样模式
史海拾趣
|
新手提问,请勿取笑,呵呵。 S3C2410在管脚复用的时候有这样一段代码: //set GPG1 as EINT9 for CS8900A value = INREG32(&pOalPortRegs->GPGCON); OUTREG32(&pOalPortRegs->GPGCON,(value & ~(3… 查看全部问答> |
|
产品最初正常工作,内核和应用程序都好的。过了一段时间后启动异常。 步骤是开机Bootloader启动,启动时加载了LOGO界面填充了液晶的显示缓冲区,后来就停在这里了。 我可以按照原来的方式烧内核,更换了画面也可以显示。 重烧了BOOTLOADER后也没 ...… 查看全部问答> |
|
在应用程序里如何查询某个USB连在哪一个USB controller上 在具有多个USB controller和多个USB设备的情况下, 如何查询这些USB设备连接在哪个USB controller上。 设备管理器中,如果选择“依连接排序设备”,就可以看到所 有设备的Device Tree,VC里有什么API或者什么方法可以获得 类似的信息吗? 请高 ...… 查看全部问答> |
|
看看有没有问题,第一次玩STM32,没有什么经验,硬件是按照st-link制作的,做了一些修改(st-link本来也是一块开发板)。准备自己做JTAG下载工具或者调试工具,呵呵,如果搞的定的话。PCB还没铺地,其他都OK了。发现一个错误,应该BOOT1接地,BO ...… 查看全部问答> |
|
μC/OS-II实时性能测试指标 衡量嵌入式实时操作系统的好坏一般主要参考以下主要性能指标参数: 任务切换时间、中断响应时间、任务响应时间、任务创建/删除时间、交替信号量时间、取得/释放信号量时间、交替消息队列传输时间等。本文仅对前2个 ...… 查看全部问答> |




