STM8S003单片机ADC采样通道总共有5个,从AIN2---AIN6,多通道采样时需要将ADC转换设置为单次转换模式,每次切换采样通道后,需要重新初始化 ADC,采样结果在中断中读取。
IO口初始化代码
//AD通道引脚初始化
void ADC_GPIO_Init( void )
{
PD_DDR &= ~( 1 << 2 ); //PD2 设置为输入 AIN3
PD_CR1 &= ~( 1 << 2 ); //PD2 设置为悬空输入
PD_DDR &= ~( 1 << 3 ); //PD3 设置为输入 AIN4
PD_CR1 &= ~( 1 << 3 ); //PD3 设置为悬空输入
PC_DDR &= ~( 1 << 4 ); //PC4 设置为输入 AIN2
PC_CR1 &= ~( 1 << 4 ); //PC4 设置为悬空输入
PD_DDR &= ~( 1 << 5 ); //PD5 设置为输入 AIN5
PD_CR1 &= ~( 1 << 5 ); //PD5 设置为悬空输入
PD_DDR &= ~( 1 << 6 ); //PD6 设置为输入 AIN6
PD_CR1 &= ~( 1 << 6 ); //PD6 设置为悬空输入
}
将ADC的IO口都设置为输入模式,悬空输入。
下来初始化ADC功能
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模块的上电完成 至少7us
ADC_CR1 = ADC_CR1 | 0x01; //再次将CR1寄存器的最低位置1 使能ADC 并开始转换
}
将ADC设置为单次转换模式,每次转换时需要手动将CR1寄存器最低位置1.
在中断中读取转换成功后的数据。
#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
}
中断中将转换后的采样值存储在DATAH,和DATAL中,并置位采样结束标志位ADC_flag,采样函数判断标志位为1时,就去读取ADC采样值。
采样值读取函数:
//采集PC4电压值 AIN2
u16 ReadVol_CH2( void )
{
u16 voltage = 0;
ADC_CH_Init( 1 );
while( ADC_flag == 0 );
if( ADC_flag )
{
ADC_flag = 0;
voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据 0--1024
//ADC_CR1 = ADC_CR1 | 0x01; // 再次将CR1寄存器的最低位置1 启动下一次转换
};
return voltage;
}
单片机有些引脚的功能需要通过选项字开启,通过ST Visual Programmer软件设置选项字方法如下:

在AFR7中,将选项字中将PC4设置为AIN2功能。
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 << 2 ); //PD2 设置为输入 AIN3
PD_CR1 &= ~( 1 << 2 ); //PD2 设置为悬空输入
PD_DDR &= ~( 1 << 3 ); //PD3 设置为输入 AIN4
PD_CR1 &= ~( 1 << 3 ); //PD3 设置为悬空输入
PC_DDR &= ~( 1 << 4 ); //PC4 设置为输入 AIN2
PC_CR1 &= ~( 1 << 4 ); //PC4 设置为悬空输入
PD_DDR &= ~( 1 << 5 ); //PD5 设置为输入 AIN5
PD_CR1 &= ~( 1 << 5 ); //PD5 设置为悬空输入
PD_DDR &= ~( 1 << 6 ); //PD6 设置为输入 AIN6
PD_CR1 &= ~( 1 << 6 ); //PD6 设置为悬空输入
}
//ADC输入通道初始化入口参数表示通道选择
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模块的上电完成 至少7us
ADC_CR1 = ADC_CR1 | 0x01; //再次将CR1寄存器的最低位置1 使能ADC 并开始转换
}
//采集PC4电压值 AIN2
u16 ReadVol_CH2( void )
{
u16 voltage = 0;
ADC_CH_Init( 1 );
while( ADC_flag == 0 );
if( ADC_flag )
{
ADC_flag = 0;
voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据 0--1024
//ADC_CR1 = ADC_CR1 | 0x01; // 再次将CR1寄存器的最低位置1 启动下一次转换
};
return voltage;
}
//采集PD2电压值 AIN3
u16 ReadVol_CH3( void )
{
u16 voltage = 0;
ADC_CH_Init( 2 );
while( ADC_flag == 0 );
if( ADC_flag )
{
ADC_flag = 0;
voltage = ( DATAH << 2 ) + DATAL ;
//ADC_CR1 = ADC_CR1 | 0x01; //当通道不需要切换时,只需初始化一次,以后每次读取完数据后,需要手动开启下一次转换
};
return voltage;
}
//采集PD3电压值 AIN4
u16 ReadVol_CH4( void )
{
u16 voltage = 0;
ADC_CH_Init( 3 );
while( ADC_flag == 0 );
if( ADC_flag )
{
ADC_flag = 0;
voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据 0--1024
//ADC_CR1 = ADC_CR1 | 0x01; // 再次将CR1寄存器的最低位置1 启动下一次转换
};
return voltage;
}
//采集PD5电压值 AIN5
u16 ReadVol_CH5( void )
{
u16 voltage = 0;
ADC_CH_Init( 4 );
if( ADC_flag )
{
ADC_flag = 0;
voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据 0--1024
//ADC_CR1 = ADC_CR1 | 0x01; //再次将CR1寄存器的最低位置1 启动下一次转换
};
return voltage;
}
//采集PD6电压值 AIN6
u16 ReadVol_CH6( void )
{
u16 voltage = 0;
ADC_CH_Init( 5 );
if( ADC_flag )
{
ADC_flag = 0;
voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据 0--1024
//ADC_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位
上一篇:STM8学习笔记---Modbus通信协议简单移植
下一篇:STM8单片机ADC模拟看门狗功能实现
推荐阅读
史海拾趣
在电子行业的初期,CANDD公司凭借其创始人对半导体技术的深入研究,成功开发出了一款具有划时代意义的芯片。这款芯片不仅性能卓越,而且成本远低于市场上的同类产品。凭借这一技术突破,CANDD公司迅速在行业内崭露头角,吸引了大量投资者的关注。随着产品销量的不断增长,公司逐渐扩大了生产规模,并在全球范围内建立了销售网络。
为了进一步提升竞争力,Alan Industries Inc.积极寻求与其他企业的战略合作。公司与多家知名供应商建立了长期稳定的合作关系,确保了原材料的稳定供应和成本控制。同时,公司还通过并购和投资等方式,整合了产业链上下游资源,形成了完整的产业生态圈。这些战略举措使得公司在市场竞争中更具优势,实现了快速发展。
在2015年的微软室内定位大赛中,Decawave的UWB技术大放异彩。公司凭借其高精度、低误差的UWB定位解决方案,在激烈的竞争中脱颖而出,荣获最佳无线电定位解决方案奖。这一荣誉不仅证明了Decawave在UWB技术领域的领先地位,也为其在市场上的推广和应用奠定了坚实的基础。
作为一家技术驱动的公司,Decawave始终将创新作为公司发展的核心动力。公司不断投入研发资源,推动UWB技术的升级和演进。通过不断的技术创新和产品升级,Decawave的UWB技术不断取得新的突破和进展,为电子行业的发展注入了新的活力。同时,公司也积极关注市场动态和客户需求的变化,不断调整和优化其产品和解决方案,以更好地满足客户的需求和期望。
|
:这要看摄像头本身的电路设计而定,如有些以COMS为基础的摄像头使用上一般都比以CCD为基础的摄像头寿命要短;COMS的摄像头有些甚至使用几个月便告终正寝,而CCD摄像头若配合品质优良的供电器皆可持续通电使用几个月,甚至数年都没什么问题。 ...… 查看全部问答∨ |
本人设计的工业仪表,遇到这样的问题:输入信号0-20MV。当用手触摸输入端子的时候,显示值会波动,这是什么干扰(好象是串模干扰),如何解决?注明:信号是经过了2个模拟开关(CD4051),由OP07放大 再采样。… 查看全部问答∨ |
|
我们是一群平凡的硬件工程师,平均做嵌入式硬件开发10多年了,在外企工作的同时对单片机爱好者进行系统的单片机嵌入式硬件培训,我们相信成功只属于努力的人! 只要有你们的支持我们就会成功.只要你努力了,你也一样会成功。无论学生多少,不管学生 ...… 查看全部问答∨ |
KernelIoControl的第一个参数IOCTL_HAL_RELEASE_SYSINTR与IOCTL_HAL_REQUEST_SYSINTR有什么区别: 即 KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pHardwareContext->dwSysintrSDMMC, sizeof(DWORD), NULL, 0, NULL)与 KernelIoControl(IOCTL_ ...… 查看全部问答∨ |
|
ARM&WINCE 多通道数据采集驱动实现思路(求高手指点) 本人要编一个多通道数据采集的驱动程序,硬件采用S3C2410A,操作系统是wince,开发工具是PB。第一次接触这些东西,思路有些乱: 数据采集的频率由S3C2410A自带的PWM Timer实现,通过设置PMW寄存器的预分频值、分频值、TC ...… 查看全部问答∨ |
刚有机会接触一个做DSP开发的公司,遇到许多不明白的问题,想来请教一下这里的高手。 他们的产品大多数用的TI的DSP芯片。他们的程序在eclipse里开发,却不在那里调试,全部要到DOS环境下编译运行,要做许多的make文件,看得头很晕。开发出的程序却 ...… 查看全部问答∨ |
|
s3c2451的wince6.0的block0img.nb0生成不能用问题 我在wince6.0上遇到这样问题的:s3c2450在VS2005中编译出来的blockimg0.nb0不能使用,请问有没有遇到这样的问题呀? 我怀疑是.bib文件中设置的问题,可修改也没什么实质性的变化?… 查看全部问答∨ |





VI-27WIU






京公网安备 11010802033920号