历史上的今天
返回首页

历史上的今天

今天是:2024年09月18日(星期三)

正在发生

2021年09月18日 | STM8 ADC转换模式-------单次扫描模式

2021-09-18 来源:eefocus

STM8单片机ADC支持5种转换模式:单次模式,连续模式,带缓存的连续模式,单次扫描模式,连续扫描模式。


单次扫描模式


该模式是用来转换从AIN0到 之间的一连串模拟通道,‘n’是在 ADC_CSR寄存器的换的通道编号。CONT 位以被清零时通过置位 ADON 位来启动。


注意:当使用扫描模式时,不可以将 AIN0 到 AINn 之间通道对应的 I/O 口设为输出状态,因为 ADC 的多路选择器已经将这些 I/O 口的输出模块禁用了。


对于单次扫描模式,转换是从AIN0通道开始的,而且结果数据被存储在数据缓冲寄存器ADC_DBxR 中,当最后一个通道(通道‘n’)被转换完成后,EOC(转换结束)标志被置位,当EOCIE 位已被置位时将产生一个中断。


可以从缓冲寄存器中读取各个通道的转换结果值。如果某个数据缓存寄存器在被读走之前被覆盖,OVR标志将置1。(见24.5.5)


转换序列正在进行过程中不要清零SCAN位;单次扫描模式可通过清零ADON位来立即停止。


为了开启一次新SCAN扫描转换,可以通过对ADC_CR1寄存器的EOC位清零和ADON位置位来实现。


读取采样结果的时候可以通过查询的方式也可以通过中断的方式去读取。


单次扫描模式通过查询方式读取数据代码:


#include "adc.h"

#include "main.h"

#include "led.h"

 

_Bool ADC_flag = 0;                     //ADC转换成功标志

 

u16 ADC_DB[10] = {0};

u16 adc_data[5] = {0};

 

//AD通道引脚初始化

void ADC_GPIO_Init( void )

{

    PD_DDR &= ~( 1 << 2 );              //PD2 设置为输入

    PD_CR1 &= ~( 1 << 2 );              //PD2 设置为悬空输入

 

    PD_DDR &= ~( 1 << 3 );              //PD3 设置为输入

    PD_CR1 &= ~( 1 << 3 );              //PD3 设置为悬空输入

 

    PC_DDR &= ~( 1 << 4 );              //PC4 设置为输入

    PC_CR1 &= ~( 1 << 4 );              //PC4设置为悬空输入

}

 

//设置为 单次扫描模式

//ch 为ADC通道 连续转换AIN0---AINch 通道的数据

void ADC_CH_Init( u8 ch )

{

    char l = 0;

 

    ADC_GPIO_Init();

    

    ADC_CR1 &= ~( 7 << 4 );   //预分频 2

    ADC_CR2 &= ~( 1 << 6 );   //不使用外部触发

    //禁止 AIN2 AIN4 的施密特触发器,降低 IO 静态功耗  PD5,PD6 上的通道如果施密特方式禁用会导致串口无法收发数据!

    ADC_TDRL |= ( 1 << 2 );

    ADC_TDRL |= ( 1 << 4 );

 

    ADC_CR1 &= ~( 1 << 1 );   //单次转换

    ADC_CSR |= 0x04;          //配置通道号最大的那个

    ADC_CR2 |= ( 1 << 3 );    //右对齐

 

    ADC_CR1 |= ( 1 << 0 );    //开启 ADC

    ADC_CR2 |= ( 1 << 1 );    // SCAN = 1 开启扫描模式

 

      //当首次置位ADON位时,ADC从低功耗模式唤醒。为了启动转换必须第二次使用写指令来置位ADC_CR1寄存器的ADON位。

    for( l = 0; l < 10; l++ );  //延时,保证ADC模块的上电完成 至少7us

    ADC_CR1 |= ( 1 << 0 );      //再次将CR1寄存器的最低位置1 使能ADC 并开始转换

}

 

u16 ain2_val = 0,ain3_val = 0,ain4_val = 0;

//读取采样电压值

u16 ReadVol_CHx( void )

{

    u16 voltage = 0;

    u16 temph = 0;

    u8 templ = 0;

    while( 1 )

    {

 

        LED = !LED;             //程序运行一圈耗时 15us    

        ADC_CR1 |= 0x01;                        //开启一次转换

        while( ( ADC_CSR & 0x80 ) == 0 );      //等待转换结束

        ADC_CSR &= ~( 1 << 7 );               // 转换结束标志位清零  EOC

 

        //读取 AIN2 的值

        templ = ADC_DB2RL;

        temph = ADC_DB2RH;

        temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

        ain2_val =  temph;

        

        //读取 AIN3 的值

        templ = ADC_DB3RL;

        temph = ADC_DB3RH;

        temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

        ain3_val =  temph;

 

 

        //读取 AIN4 的值

        templ = ADC_DB4RL;

        temph = ADC_DB4RH;

        temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

        ain4_val =  temph;

    }

    return voltage;

}

单次扫描模式通过中断方式读取数据代码:


#include "adc.h"

#include "main.h"

#include "led.h"

 

_Bool ADC_flag = 0;                     //ADC转换成功标志

 

u16 ADC_DB[10] = {0};

u16 adc_data[5] = {0};

 

//AD通道引脚初始化

void ADC_GPIO_Init( void )

{

    PD_DDR &= ~( 1 << 2 );              //PD2 设置为输入

    PD_CR1 &= ~( 1 << 2 );              //PD2 设置为悬空输入

 

    PD_DDR &= ~( 1 << 3 );              //PD3 设置为输入

    PD_CR1 &= ~( 1 << 3 );              //PD3 设置为悬空输入

 

    PC_DDR &= ~( 1 << 4 );              //PC4 设置为输入

    PC_CR1 &= ~( 1 << 4 );              //PC4设置为悬空输入

}

 

//设置为 单次扫描模式

//ch 为ADC通道 连续转换AIN0---AINch 通道的数据

void ADC_CH_Init( u8 ch )

{

    char l = 0;

    ADC_GPIO_Init();

 

    ADC_CR1 &= ~( 7 << 4 );   //预分频 2

    ADC_CR2 &= ~( 1 << 6 );   //不使用外部触发

    //禁止 AIN2 AIN4 的施密特触发器,降低 IO 静态功耗  PD5,PD6 上的通道如果施密特方式禁用会导致串口无法收发数据!

    ADC_TDRL |= ( 1 << 2 );

    ADC_TDRL |= ( 1 << 4 );

 

    ADC_CR1 &= ~( 1 << 1 );   //单次转换

    ADC_CSR |= 0x04;          //配置通道号最大的那个

    ADC_CR2 |= ( 1 << 3 );    //右对齐

 

    ADC_CR1 |= ( 1 << 0 );    //开启 ADC

    ADC_CR2 |= ( 1 << 1 );    // SCAN = 1 开启扫描模式

 

    ADC_CSR |= ( 1 << 5 );    //EOCIE 使能转换结束中断

 

    //当首次置位ADON位时,ADC从低功耗模式唤醒。为了启动转换必须第二次使用写指令来置位ADC_CR1寄存器的ADON位。

    for( l = 0; l < 10; l++ );  //延时,保证ADC模块的上电完成 至少7us

    ADC_CR1 |= ( 1 << 0 );      //再次将CR1寄存器的最低位置1 使能ADC 并开始转换

}

 

//AD中断服务函数 中断号22

#pragma vector = 24                     // IAR中的中断号,要在STVD中的中断号上加2

__interrupt void ADC_Handle( void )

{

    ADC_CSR &= ~( 1 << 7 );               // 转换结束标志位清零  EOC

 

    //单通道扫描模式,转换结果存储在 ADC_DBxR 寄存器中

    LED = !LED;             //程序运行一圈耗时 20us

 

    //读取 AIN2 的值

    templ = ADC_DB2RL;

    temph = ADC_DB2RH;

    temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

    ain2_val =  temph;

 

    //读取 AIN3 的值

    templ = ADC_DB3RL;

    temph = ADC_DB3RH;

    temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

    ain3_val =  temph;

 

    //读取 AIN4 的值

    templ = ADC_DB4RL;

    temph = ADC_DB4RH;

    temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

    ain4_val =  temph;

 

    ADC_CR1 |= 0x01;                        //开启一次转换

    ADC_flag = 1;                       // ADC中断标志 置1

}

推荐阅读

史海拾趣

永丰盈(CST)公司的发展小趣事

作为一家有社会责任感的企业,CST始终关注环境保护和社会公益事业。公司严格执行环保法规,积极推广绿色生产理念,努力减少生产过程中的污染排放。此外,CST还积极参与社会公益活动,为当地的教育、文化等事业做出了积极贡献。这些举措进一步提升了CST的企业形象和社会声誉。

3L Electronic Corporation公司的发展小趣事

3L Electronic Corporation,自XXXX年在台北创立以来,凭借创始人的远见卓识和团队的努力,逐渐在电子行业崭露头角。初期,公司主要生产电子零组件,凭借着精湛的工艺和稳定的质量,赢得了客户的信赖。随着市场的扩大,公司逐渐拓展到电子产品修理和国际贸易等领域,为后续的快速发展奠定了坚实基础。

绿宝石(BERYL)公司的发展小趣事

绿宝石公司自创立之初,便致力于电子材料领域的研发。某年,公司研发团队成功开发了一种具有优异性能的绿宝石电子材料,这种材料在高频、高温等极端环境下仍能保持稳定性能,为电子行业带来了革命性的变革。随着这一技术的广泛应用,绿宝石公司在行业内逐渐树立了技术领先的形象,市场份额稳步上升。

Anaheim Automation公司的发展小趣事

1994年,在韩国这片科技热土上,AMOTECH公司应运而生。创立之初,公司便立志于在电子行业中占据一席之地。创始团队凭借对技术的深刻理解和敏锐的市场洞察,决定专注于金属氧化物压敏电阻(MOV)的研发与生产。初期的发展并非一帆风顺,但团队凭借坚定的信念和不懈的努力,逐步在市场中建立了良好的口碑。

Digital Voice Systems Inc公司的发展小趣事

Digital Voice Systems, Inc.(DVSI)于1988年成立,当时正值数字通信技术的兴起阶段。公司创始人凭借对语音编解码技术的深刻理解和前瞻性的市场洞察力,决定投身于这一领域。他们开发出了具有专利保护的基于鲁棒性多带激励模型(MBE Model)的低码率语音压缩算法,如IMBE和AMBE编解码系统。这些算法在当时的市场上独树一帜,为DVSI赢得了第一桶金。

在创立初期,DVSI面临着资金、技术、市场等多方面的挑战。然而,他们凭借着坚定的信念和不懈的努力,逐步克服了这些困难。他们不断投入研发,优化算法,提高产品的性能和稳定性;同时,他们积极开拓市场,与各大通信设备制造商建立合作关系,将产品推向市场。

随着时间的推移,DVSI的产品逐渐在市场上获得了认可。他们的编解码系统被广泛应用于移动通信、卫星通信、军事通信等领域,为客户提供了高效、稳定的语音通信解决方案。DVSI也因此逐渐崭露头角,成为了电子行业中一颗耀眼的明星。

故事二至五框架概述

  1. 技术创新与突破:DVSI在语音编解码技术方面的持续创新,如推出新一代的高效压缩算法,进一步提升了产品的竞争力。
  2. 市场拓展与国际化:随着公司实力的增强,DVSI开始拓展国际市场,与全球多家知名企业建立合作关系,实现了国际化发展。
  3. 合作与竞争:在电子行业中,DVSI与其他企业的合作与竞争并存。他们通过合作共赢的方式,共同推动行业的发展;同时,也面临着来自竞争对手的挑战和竞争压力。
  4. 企业文化与团队建设:DVSI注重企业文化建设,倡导创新、协作、共赢的价值观。他们注重团队建设,吸引了一批优秀人才加入公司,为公司的发展提供了有力的人才保障。

以上故事和框架概述仅供参考,您可以根据这些线索进一步挖掘和编写关于DVSI公司的故事。

德索五金(dosinconn)公司的发展小趣事

问答坊 | AI 解惑

菜鸟求救啊....关于m2716的用法...

以前从没接触过这类芯片。现在要用啊。但又不会。 谁能告诉下我m2716在Proteus中如何加载数据,还有在现实中用什么把数据烧到它里面去? 不甚感谢啊... …

查看全部问答>

mc55模块上电20秒后自动关机问题

将mc55模块/IGT引脚置低电平后,mc55模块上电开机,但20秒后mc55模块会自动关机.每次都是这样,找不到原因,请各位指教.谢谢…

查看全部问答>

我想请问KEYMAN工具是个什么?

当设备与 Visual Studio 机器没有 ActiveSync 连接,但有一个有效的 TCP 连接时,部署无效。 解决办法:使用单独提供的 Keyman 工具来执行初始的设备设置. 我想请问KEYMAN工具是什么,在哪里可以找到它,或者下到它? 谢谢~…

查看全部问答>

请问一下接近开关 常开加常闭是什么意思。

我就知道接近开关有常开,和常闭,怎么还有一个一开一闭的,这个一开一闭算起什么作用呢?…

查看全部问答>

【一起学习器件指标】你敢不敢说个大家不知道的电阻指标

几乎所有的电子设计中都会使用到电阻,我稍微提供问题,你知道的电阻有哪些参数指标呢?你敢不敢说个大家都不知道的指标?这个大家现在用的多了也许再过多少年后就看不到这位了…

查看全部问答>

关于定时器中断打断芯片驱动函数时序的问题???!!!

做了个东西用的DHT11温湿度传感器  显示是用的数码管动态扫描 由于执行驱动函数用的时间比较长就把显示函数放在了定时器中断里面  问题出来了 定时器中断把DHT11驱动函数的时序给打乱了 读出来的数据一直在跳动 乱 我在驱动函 ...…

查看全部问答>

求助~~急

哪位大哥知道51单片机中读秒指示电路的工作原理?求解答…

查看全部问答>

我的C2000无法仿真了.问题已解决。

Error connecting to the target: (Error -151 @ 0x0) One of the FTDI driver functions used during the connect returned bad status or an error. The cause may one or more of: invalid emulator serial number, blank emulator EEPROM, ...…

查看全部问答>