历史上的今天
今天是: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
}
史海拾趣
|
以前从没接触过这类芯片。现在要用啊。但又不会。 谁能告诉下我m2716在Proteus中如何加载数据,还有在现实中用什么把数据烧到它里面去? 不甚感谢啊... … 查看全部问答> |
|
当设备与 Visual Studio 机器没有 ActiveSync 连接,但有一个有效的 TCP 连接时,部署无效。 解决办法:使用单独提供的 Keyman 工具来执行初始的设备设置. 我想请问KEYMAN工具是什么,在哪里可以找到它,或者下到它? 谢谢~… 查看全部问答> |
|
几乎所有的电子设计中都会使用到电阻,我稍微提供问题,你知道的电阻有哪些参数指标呢?你敢不敢说个大家都不知道的指标?这个大家现在用的多了也许再过多少年后就看不到这位了… 查看全部问答> |
|
做了个东西用的DHT11温湿度传感器 显示是用的数码管动态扫描 由于执行驱动函数用的时间比较长就把显示函数放在了定时器中断里面 问题出来了 定时器中断把DHT11驱动函数的时序给打乱了 读出来的数据一直在跳动 乱 我在驱动函 ...… 查看全部问答> |
|
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, ...… 查看全部问答> |




