历史上的今天
今天是: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
史海拾趣
|
一、支架: 1)、支架的作用:用来导电和支撑 2)、支架的组成:支架由支架素材经过电镀而形成,由里到外是素材、铜、镍、铜、银这五层所组成。 3)、支架的种类:带杯支架做聚光型,平头支架做大角度散光型的Lamp。 A、2002 ...… 查看全部问答> |
|
本帖最后由 jameswangsynnex 于 2015-3-3 19:59 编辑 转自---高工在线 1月19日消息,有“山寨机之父”之称的联发科与工信部旗下泰尔实验室最近签订战略联盟合约,携手推广自主研发3G标准TD-SCDMA。这是联发科首度参与制定大陆3C技术与标准,此举有 ...… 查看全部问答> |
|
//------------------------------------------------------------------------------------------------- // 作者:[email=wogoyixikexie@gliet]wogoyixikexie@gliet[/email] //论坛账号:gooogleman (经常在CSDN出没) // 版权:桂林电子科 ...… 查看全部问答> |
|
要使这个条件宏定义_POCKET_PC生效, 在EVC工程中如何设置? EVC 中,定义了以下一个条件宏定义,意思是: 当定义了_POCKET_PC时,执行某些代码,没定义时执行另些代码. #ifdef _POCKET_PC ....... #endif ......... 要使这个条件宏定义_POCKET_PC生效, 在EVC工程中如何设置?… 查看全部问答> |
|
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通过串口实现程序的在线升级,主要实现flash自举的程序接收PC端的升级数据,并烧写内部flash。在调用flash_erase()函数时,返回值为0x18,请问在何种情况下可能导致此类问题的发生?… 查看全部问答> |
|
uclinux下s3c4510b,flash为39vf160,如何才能知道flash中空闲地址? 希望能在用户程序中对flash读写数据,可是查看资料后 也不明白代码怎么存放,写了原有数据就启动不了了。uclinux下flash开始地址 FLASH_MEM_BASE=0x01000000,FLASH_SIZE=0x00200000. 而且修改数据前需要擦除,擦除的最小单位是sector吗 ...… 查看全部问答> |
|
如题,现在在一台条码设备上做ERP配套开发,数据库是用ORACLE的,由于不想通过ERP系统会占用用户数,所以想直接连接到ORACLE数据库上面,请问在WINCE上连ORACLE可以通过什么方法!谢谢… 查看全部问答> |
|
数据串转并,用串行的时钟通过DCM产生一个和并行数据同频的时钟,然后用这个时钟读并行数据会不会存在问题,能满足SETUP/HOLDUP要求么。… 查看全部问答> |
|
大家都知道,中国的工业自动化技术在世界上来看还是很落后的,我自己的理解是因为三个原因:第一,可能是教育部门不是很重视,第二,可能是因为门槛比较高(机械的学生可以设计机器人支架,但是控制方面不行,电子的学生控制方面可以,但 ...… 查看全部问答> |




