STM8S003单片机内部ADC为12位,A/D转换的各个通道可以执行单次和连续的转换模式。

 单次转换模式的意思就是,ADC每次转换一次数据后,就会停止转换,如果还需要继续转换的话,就需要手动开启第二次转换功能。

 连续转换模式的意思就是每次转换结束后,系统会自动开启第二次转换,不需要手动设置第二次转换的开启,也就是说连续转换模式只需要开启一次。

ADC框图如下:

ADC转换时序图如下:

下面用代码来实现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_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模块的上电完成 至少7usADC_CR1 = ADC_CR1 | 0x01;           //再次将CR1寄存器的最低位置1 使能ADC 并开始转换
}//采集PD3电压值
u16 ReadVol_CH3( void )
{u16 voltage = 0;if( ADC_flag ){ADC_flag = 0;voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据  0--1024ADC_CR1 = ADC_CR1 | 0x01;          //再次将CR1寄存器的最低位置1  启动下一次转换};return voltage;
}
//AD中断服务函数 中断号22
#pragma vector = 24                     // IAR中的中断号,要在STVD中的中断号上加2
__interrupt void ADC_Handle( void )
{ADC_CSR &= ~0x80;                   // 转换结束标志位清零  EOC//默认左对齐 读数据时先读高高8位 再读低8位DATAH = ADC_DRH;                    // 读出ADC结果的高8位DATAL = ADC_DRL;                    // 读出ADC结果的低8位ADC_flag = 1;                       // ADC中断标志 置1
}

在第一次ADC启动时需要一个稳定时间,所以在初始化的时候,需要一定的时间等待ADC稳定,稳定之后就可以开始ADC转换了,这里使用中断来读取转换结果,当ADC转换换成后就会产生一个中断,然后在中断中读取转换的结果,同时设置标志位。程序循环去读取标志位,当标志位为1时,就说明转换完成了,这时候就可以输出转换的结果了。然后将ADC_CR1寄存器的最低位,手动置1,开启下一次转换。

ADC_CR1寄存器如下:

ADON位就是ADC的转换开关,在单次模式下给ADON位写1就可开启转换。

这里只使用了一个通道,通过最上面ADC框图可以看出,一个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_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模块的上电完成 至少7usADC_CR1 = ADC_CR1 | 0x01;           //再次将CR1寄存器的最低位置1 使能ADC 并开始转换
}//采集PD3电压值
u16 ReadVol_CH3( void )
{u16 voltage = 0;//只在程序初始化时调用一次的话,采样速度非常快。//如果每次都调用初始化,速度将会是原来的 1/10ADC_CH_Init( 3 );while( ( ADC_CSR & 0x80 ) == 0 );      //等待转换结束if( ADC_CSR & 0x80 ){DATAH = ADC_DRH;                    // 读出ADC结果的高8位DATAL = ADC_DRL;                    // 读出ADC结果的低8位voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据  0--1024ADC_CR1 = ADC_CR1 | 0x01;          //再次将CR1寄存器的最低位置1  启动下一次转换ADC_CSR &= 0x7F;};return voltage;
}//采集PD2电压值
u16 ReadVol_CH4( void )
{u16 voltage = 0;//只在程序初始化时调用一次的话,采样速度非常快。//如果每次都调用初始化,速度将会是原来的 1/10ADC_CH_Init( 2 );while( ( ADC_CSR & 0x80 ) == 0 );      //等待转换结束if( ADC_CSR & 0x80 ){DATAH = ADC_DRH;                    // 读出ADC结果的高8位DATAL = ADC_DRL;                    // 读出ADC结果的低8位voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据  0--1024ADC_CR1 = ADC_CR1 | 0x01;          //再次将CR1寄存器的最低位置1  启动下一次转换ADC_CSR &= 0x7F;};return voltage;

如果需要转换多个通道,那么在一个通道转换完成之后,就需要重新初始化,进行转换通道的切换。由于切换通道后,ADC需要稳定时间,所以如果是多个通道来回切换采样数据的话,比一个通道单独采样数据就要慢很多,因为切换一次通道就需要等待一段时间让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;SysClkInit();__asm( "sim" );                       //禁止中断LED_GPIO_Init();ADC_CH_Init( 3 );__asm( "rim" );                       //开启中断while( 1 ){LED = !LED;val1 = ReadVol_CH3();}
}

STM8单片机ADC单次采样模式相关推荐

  1. STM8单片机ADC带缓存的连续采样模式

      在上一篇文章中说了STM8的ADC连续采样模式,为了提高采样的精度和速率,STM8单片机还提供了带缓存的连续采样模式,也就是说ADC会连续采集8个数据,放在缓存中,读取数据时可以一次从缓存中读取8 ...

  2. STM8单片机ADC采样功能通过定时器触发

      在使用STM8单片机的ADC功能时,读取ADC数据时一般有两种方式,一种是通常不断地读取采样标志位,来判断ADC采样是否结束,一种是通过中断的方式来通知系统采样是否结束.   有时候采样ADC数据 ...

  3. STM8单片机ADC连续扫描模式

      当STM8单片机使用ADC功能读取多个通道的值时,可以使用连续模式,但是连续模式一次只能采样一个通道的值,那么如果要采样多个通道时怎么办呢?STM8提供了一个多通道连续采样扫描模式.也就是说多个通 ...

  4. STM8单片机ADC模拟看门狗功能实现

      看门狗的功能大家都知道,而这个模拟看门狗又是什么东西呢?   简单的说就是这个模拟看门狗可以实时监控ADC采样的数据,当采样的数据值小于设置的最小值或者大于设置的最大值时,单片机就会触发ADC中断 ...

  5. STM8单片机 ADC模拟看门狗中文资料错误

      在调试stm8单片机的adc模拟看门狗功能时,不管怎么设置ADC_HTR和ADC_LTR寄存器的值,然后通过IAR软件单步调试时观察这两个寄存器的值都不对.   根据中文手册上看,高位寄存器存储的 ...

  6. GDF307配置ADC单次采样

    最近因为项目正在用GD芯片做ADC采样,笔记的同时也分享给大家共勉~ 1.初始化ADC void ADCInit(void) {INT8U i;for(i=0; i<MAX_ADC_NUM; i ...

  7. STM8单片机ADC连续采样模式

     STM8S003单片机内部ADC为12位,A/D转换的各个通道可以执行单次和连续的转换模式.  单次转换模式的意思就是,ADC每次转换一次数据后,就会停止转换,如果还需要继续转换的话,就需要手动开启 ...

  8. stm8单片机例程下载链接

    在这篇文章中将自己上传的资源做一个下载链接的目录方便查找下载 STM8单片机编码器使用示例 STM8单片机ADC连续扫描模式并开启模拟看门狗功能 STM8单片机ADC单次扫描模式并开启模拟看门狗功能 ...

  9. STM32 ADC多通道规则采样和注入采样

    layout: post tags: [STM32] comments: true 文章目录 layout: post tags: [STM32] comments: true 什么是ADC? STM ...

最新文章

  1. 10个必知必会的PyCharm使用技巧!
  2. 2022秋招算法岗卷成人间地狱!高薪惹眼,招录比100:1
  3. Kotlin成为正式的Android编程语言
  4. Oracle.ManagedDataAccess 连接数据库用户名密码错误
  5. arrays中copyof复制两个数组_Java的数组初识和拷贝用法
  6. Easyui 页面访问慢解决方案,GZIP网站压缩加速优化
  7. 流程平台:示例流程 - 主机申请审批流程
  8. 在MAC环境下之以太坊(ethereum)开发环境安装
  9. C语言经典算法100例-021-猴子吃桃问题
  10. Win11右键显示更多选项设置教程
  11. ftp服务器文件无法删除,ftp服务器文件删除
  12. 比原链CEO朗豫:DeFi让用户真正理解区块链,意义重大
  13. ERROR2002(HY000):CantconnecttolocalMySQLserverthroughsocket/tmp/mys
  14. 每天一道面试题--- js 中 this 指针的用法
  15. c语言筛法求一个范围内的素数,运用埃拉托色尼筛法求解一定范围内的素数.docx...
  16. 日语五十音图记忆口诀
  17. 高考数学试题不等关系与不等式|附习题
  18. 英语文章书写规则总结
  19. 正定矩阵的定义与性质
  20. maven的xml配置文件内容

热门文章

  1. PHP年龄计算 取得两个时间戳相差的年龄年月日显示
  2. Android开发环境搭建(eclipse)
  3. Oracle树反向查询的优化(转载)
  4. Java大数据你该学哪个
  5. Nginx前端设置反向代理,后端Apache如何获取访客的真实IP,结合PHP
  6. React Native组件的结构和生命周期
  7. Java Script 学习笔记 -- Ajax
  8. 前端mvc与mvvm
  9. [Prism框架实用分享]如何在主程序中合理的弹出子窗体
  10. HDU 3943 K-th Nya Number(数位DP)