历史上的今天
返回首页

历史上的今天

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

正在发生

2021年09月18日 | STM8 ADC转换模式-------带缓存的连续模式

2021-09-18 来源:eefocus

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


连续和带缓存的连在连 换模式中,将ADC设为连续模式,该模式是通过置位 ADC_CR1寄存器的 ADON 位来启动的。


● 如果缓存功能被使能(DBUF=1),那么某个选定满数据缓存,当缓存被填满时,EOC(转换结束)标志被置位,如果EOCIE位已被置位,则会产生一个中断,然后一个新的转换自动开始。如果某个数据缓存寄存器在被读走之前被覆盖,OVR标志将置1。


如果要停止连续转换,可以复位清零CONT位来停止转换或者复位清零ADON位来关闭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 为单片机ADC通道

通过置位ADC_CR1寄存器的ADON位来开启ADC。当第一次置位ADON时,ADC从低功耗模式唤醒。


为了启动转换必须第二次使用写指令来置位ADON位。


在转换结束时,ADC会保持在上电状态,用户只需要置位ADON位一次来启动下一次转换。


转换完成后,转换数据存储在ADC_DR寄存器中,EOC(转换结束)标志被置位,如果EOCIE被置位将产生一个中断


ADC输入通道初始化入口参数表示通道选择

*/

void ADC_CH_Init( u8 ch )

{

    char l = 0;

    ADC_CR1  = 0x00;                    //fADC = fMASTER/2, 8Mhz  单次转换,禁止转换

    ADC_CR1 |= ( 1 << 1 );              //开启连续转换模式

    ADC_CSR  = ch;                      //控制状态寄存器 选择要 AD输入通道  如:PD2(AIN3)

    ADC_CR2  = 0x00;                    //默认左对齐 读数据时先读高在读低

    ADC_TDRL = ( 1 << ch );             //禁止相应通道 施密特触发功能 1左移ch+1位

    ADC_CR1 |= 0x01;                    //使能ADC并开始转换

 

    //ADC_CSR |= 0x20;                    //EOCIE 使能转换结束中断  EOC中断使能

    ADC_CR3 |= ( 1 << 7 );              //数据缓存使能

 

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

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

}

 

u16 databuf[8] = {0};

//采集PD2电压值

u16 ReadVol_CH3( void )

{

    u16 voltage = 0;

 

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

    if( ADC_CSR & 0x80 )

    {

        ADC_CSR &= 0x7F;

        /*

        使能缓存模式后,数据会存储在 ADC_DB0R ---- ADC_DB7R 寄存器中

        如果使能了扫描模式那么这几个寄存器存储的就是对应通道的数据

        如果没有使能扫描模式,那么这几个通道就存储的是连续转换的结果

        这里没有使用扫描模式,所以缓存器中存储的都是当前通道连续读取的数据

        */

        DATAH = ADC_DB0RH;                    // 读出ADC结果的高8位

        DATAL = ADC_DB0RL;                    // 读出ADC结果的低8位

        voltage = ( DATAH << 2 ) + DATAL ;    //得到十位精度的数据  0--1024

        databuf[0] = voltage;

 

        DATAH = ADC_DB1RH;

        DATAL = ADC_DB1RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[1] = voltage;

 

        DATAH = ADC_DB2RH;

        DATAL = ADC_DB2RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[2] = voltage;

 

        DATAH = ADC_DB3RH;

        DATAL = ADC_DB3RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[3] = voltage;

 

        DATAH = ADC_DB4RH;

        DATAL = ADC_DB4RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[4] = voltage;

 

        DATAH = ADC_DB5RH;

        DATAL = ADC_DB5RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[5] = voltage;

 

        DATAH = ADC_DB6RH;

        DATAL = ADC_DB6RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[6] = voltage;

 

        DATAH = ADC_DB7RH;

        DATAL = ADC_DB7RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[7] = voltage;

    }

 

    return voltage;

}

 

 

连续模式带缓存功能中断方式读取数据代码如下:


#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 为单片机ADC通道

通过置位ADC_CR1寄存器的ADON位来开启ADC。当第一次置位ADON时,ADC从低功耗模式唤醒。

为了启动转换必须第二次使用写指令来置位ADON位。

在转换结束时,ADC会保持在上电状态,用户只需要置位ADON位一次来启动下一次转换。

转换完成后,转换数据存储在ADC_DR寄存器中,EOC(转换结束)标志被置位,如果EOCIE被置位将产生一个中断

ADC输入通道初始化入口参数表示通道选择

*/

void ADC_CH_Init( u8 ch )

{

    char l = 0;

    ADC_CR1  = 0x00;                    //fADC = fMASTER/2, 8Mhz  单次转换,禁止转换

    ADC_CR1 |= ( 1 << 1 );              //开启连续转换模式

    ADC_CSR  = ch;                      //控制状态寄存器 选择要 AD输入通道  如:PD2(AIN3)

    ADC_CR2  = 0x00;                    //默认左对齐 读数据时先读高在读低

    ADC_TDRL = ( 1 << ch );             //禁止相应通道 施密特触发功能 1左移ch+1位

    ADC_CR1 |= 0x01;                    //使能ADC并开始转换

 

    ADC_CSR |= 0x20;                    //EOCIE 使能转换结束中断  EOC中断使能

    ADC_CR3 |= ( 1 << 7 );              //数据缓存使能

 

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

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

}

 

u16 databuf[8] = {0};

//采集PD2电压值

u16 ReadVol_CH3( void )

{

    u16 voltage = 0;

 

    if( ADC_flag )

    {

        ADC_flag = 0;

        /*

        使能缓存模式后,数据会存储在 ADC_DB0R ---- ADC_DB7R 寄存器中

        如果使能了扫描模式那么这几个寄存器存储的就是对应通道的数据

        如果没有使能扫描模式,那么这几个通道就存储的是连续转换的结果

        这里没有使用扫描模式,所以缓存器中存储的都是当前通道连续读取的数据

        */

        DATAH = ADC_DB0RH;                    // 读出ADC结果的高8位

        DATAL = ADC_DB0RL;                    // 读出ADC结果的低8位

        voltage = ( DATAH << 2 ) + DATAL ;    //得到十位精度的数据  0--1024

        databuf[0] = voltage;

 

        DATAH = ADC_DB1RH;

        DATAL = ADC_DB1RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[1] = voltage;

 

        DATAH = ADC_DB2RH;

        DATAL = ADC_DB2RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[2] = voltage;

 

        DATAH = ADC_DB3RH;

        DATAL = ADC_DB3RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[3] = voltage;

 

        DATAH = ADC_DB4RH;

        DATAL = ADC_DB4RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[4] = voltage;

 

        DATAH = ADC_DB5RH;

        DATAL = ADC_DB5RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[5] = voltage;

 

        DATAH = ADC_DB6RH;

        DATAL = ADC_DB6RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[6] = voltage;

 

        DATAH = ADC_DB7RH;

        DATAL = ADC_DB7RL;

        voltage = ( DATAH << 2 ) + DATAL ;

        databuf[7] = voltage;     

    }

    return voltage;

}

 

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

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

__interrupt void ADC_Handle( void )

{

    ADC_CSR &= ~0x80;                   // 转换结束标志位清零  EOC

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

推荐阅读

史海拾趣

CHINFA公司的发展小趣事

CHINFA公司的创立并非一帆风顺。在创业初期,公司面临着资金短缺、技术落后和市场竞争激烈等多重困难。然而,公司的创始人凭借对电子行业的深厚热爱和坚定信念,带领团队克服了一个又一个难关。他们通过自主研发、技术创新和市场拓展,逐渐在行业中崭露头角。

Geyer Electronic E K公司的发展小趣事

随着全球化进程的加速,CHINFA公司意识到必须走国际化发展道路。公司制定了详细的国际化战略,积极开拓海外市场。通过与国外知名企业的合作和交流,公司不断提升自身的技术水平和市场竞争力。同时,公司还积极参加国际电子展会和论坛,展示自身实力和产品优势,进一步提升了品牌知名度和影响力。

Asian Best Components Co Ltd公司的发展小趣事

Asian Best Components Co Ltd深知人才是企业发展的核心力量。因此,公司一直高度重视人才的培养和引进。公司建立了完善的人才培训体系,通过内部培训、外部交流等方式不断提升员工的技能水平和综合素质。同时,公司还积极引进国内外优秀人才,为公司的技术创新和市场拓展提供了有力支持。这种对人才的重视和投入,使得Asian Best在激烈的市场竞争中始终保持着强劲的发展势头。


以上是根据您的要求创作的5个关于Asian Best Components Co Ltd公司发展起来的相关故事。这些故事旨在展现公司在技术创新、市场拓展、品质管理、环保理念以及人才培养等方面的努力和成就。请注意,这些故事纯属虚构,如有雷同纯属巧合。

H&D Wireless公司的发展小趣事

高创科技起源于1987年的以色列,最初是一家专注于直驱运动控制驱动器开发的厂商。在以色列的三十多年里,高创积累了丰富的软件算法技术,特别是在运动控制领域形成了独特优势。这种积累不仅体现在其产品的稳定性和高性能上,更为后续的技术创新和市场拓展奠定了坚实基础。

爱特姆(ATOM)公司的发展小趣事

爱特姆在国内市场取得一定成绩后,开始积极拓展国际市场。通过与欧洲、美国等国家的知名企业建立合作关系,爱特姆的产品逐渐打入国际市场,并赢得了良好的口碑。同时,公司还积极参加国际电子展会,与全球同行交流学习,不断提升自身的国际竞争力。

FlexiPanel公司的发展小趣事

FlexiPanel深知研发投入是企业持续发展的动力源泉。因此,公司每年都将大量资金用于技术研发和创新项目的实施。通过不断投入研发,FlexiPanel在RF模块领域取得了多项专利和技术突破,推动了整个行业的产业升级和技术进步。同时,公司还积极参与国际技术交流与合作,引进和吸收国际先进技术和理念,为企业的长远发展奠定了坚实的基础。

问答坊 | AI 解惑

LED发光二极管的结构组成

一、支架:   1)、支架的作用:用来导电和支撑   2)、支架的组成:支架由支架素材经过电镀而形成,由里到外是素材、铜、镍、铜、银这五层所组成。   3)、支架的种类:带杯支架做聚光型,平头支架做大角度散光型的Lamp。   A、2002 ...…

查看全部问答>

“山寨机之父”联发科参与TD标准制定

本帖最后由 jameswangsynnex 于 2015-3-3 19:59 编辑 转自---高工在线 1月19日消息,有“山寨机之父”之称的联发科与工信部旗下泰尔实验室最近签订战略联盟合约,携手推广自主研发3G标准TD-SCDMA。这是联发科首度参与制定大陆3C技术与标准,此举有 ...…

查看全部问答>

裸奔2440 遇到的一个郁闷GPIO问题

//------------------------------------------------------------------------------------------------- // 作者:[email=wogoyixikexie@gliet]wogoyixikexie@gliet[/email] //论坛账号:gooogleman (经常在CSDN出没) // 版权:桂林电子科 ...…

查看全部问答>

要使这个条件宏定义_POCKET_PC生效, 在EVC工程中如何设置?

EVC 中,定义了以下一个条件宏定义,意思是: 当定义了_POCKET_PC时,执行某些代码,没定义时执行另些代码. #ifdef _POCKET_PC ....... #endif ......... 要使这个条件宏定义_POCKET_PC生效, 在EVC工程中如何设置?…

查看全部问答>

build platfor的时候出现的问题

build platfor的时候出现的问题 makeimg: FATAL ERROR: Cannot open D:\\WINCE420\\PUBLIC\\SMDK2410vga\\RelDir\\SAMSUN~1\\postproc\\platform.bib makeimg: FATAL ERROR: Cannot open D:\\WINCE420\\PUBLIC\\SMDK2410vga\\RelDir\\SAMSUN~1\\p ...…

查看全部问答>

2812通过串口实现程序的在线升级问题

目前正在做2812通过串口实现程序的在线升级,主要实现flash自举的程序接收PC端的升级数据,并烧写内部flash。在调用flash_erase()函数时,返回值为0x18,请问在何种情况下可能导致此类问题的发生?…

查看全部问答>

uclinux下s3c4510b,flash为39vf160,如何才能知道flash中空闲地址?

希望能在用户程序中对flash读写数据,可是查看资料后 也不明白代码怎么存放,写了原有数据就启动不了了。uclinux下flash开始地址  FLASH_MEM_BASE=0x01000000,FLASH_SIZE=0x00200000. 而且修改数据前需要擦除,擦除的最小单位是sector吗 ...…

查看全部问答>

wince上开发,通过什么接口能连接到ORACLE

如题,现在在一台条码设备上做ERP配套开发,数据库是用ORACLE的,由于不想通过ERP系统会占用用户数,所以想直接连接到ORACLE数据库上面,请问在WINCE上连ORACLE可以通过什么方法!谢谢…

查看全部问答>

用同步的低频时钟去读串转并以后的数据会不会有问题

数据串转并,用串行的时钟通过DCM产生一个和并行数据同频的时钟,然后用这个时钟读并行数据会不会存在问题,能满足SETUP/HOLDUP要求么。…

查看全部问答>

贴几张机器人的照片---勾起你DIY机器人的欲望

  大家都知道,中国的工业自动化技术在世界上来看还是很落后的,我自己的理解是因为三个原因:第一,可能是教育部门不是很重视,第二,可能是因为门槛比较高(机械的学生可以设计机器人支架,但是控制方面不行,电子的学生控制方面可以,但 ...…

查看全部问答>