历史上的今天
今天是:2025年02月12日(星期三)
2020年02月12日 | STM8S003/903 使用ADC中断功能
2020-02-12 来源:elecfans
对使用STM8S003/903这个片子的ADC中断功能(包括两种情况),记录下自己的理解:
一、单通道使用ADC中断的场合:
如果项目中只需要采集一路模拟量,并且想使用中断方式来获取AD值,那么,设置如下:
void ADC1_Init(void)
{
CLK->PCKENR2 |= CLK_PCKENR2_ADC; //ADC Clock Enable
ADC1->TDRL = 0x02; //禁用对应AD通道的施密特触发器
ADC1->CR2 &= ~ADC1_CR2_ALIGN; //结果左对齐。
/*使能中断的同时一定要同时设定ADC通道号。*/
ADC1->CSR |= ADC1_CSR_EOCIE; //使能ADC中断
ADC1->CSR |= 0x02; //选择通道
ADC1->CR1 |= (0x20 ); //时钟4分频
ADC1->CR1 |= (ADC1_CR1_ADON); //开启ADC1电源
//这里还需要开启全局中断,省略,一般放到main函数的初始化部分开启全局中断。
}
void ADC1_Start(u8 channel)
{
ADC1->CR1 |= ADC1_CR1_ADON; //启动ADC1开始转换
}
@far @interrupt void ADC1_IRQHandler(void)
{
u8 adc_value = 0;
ADC1->CSR &= ~ADC1_CSR_EOC; //结束标志位清零
adc_value = ADC1->DRH;
//在这个中断服务函数中获取数据,你可以取高8位, 也可以把高8位和低8位全部取出来。看你的精度需要。
}
使用思路: 在main函数初始化阶段调用ADC1_Init(),在需要开启ADC采集的时候调用ADC1_Start(),在ADC1_IRQHandler()中断处理函数中,读取AD值。
二、多通道使用的场合:
要在STM8S003/903上使用ADC,特别是多通道又不是连续的通道(因为有时候PCB布线受限制,无法使用连续的ADC通道采集多路模拟量),并且你又需要采用单次转换加中断的方式读取AD值,而不是查询的方式, 那么,这种情况,有点特别的设定,设置如下:
void ADC1_Init(void)
{
CLK->PCKENR2 |= CLK_PCKENR2_ADC; //ADC Clock Enable
ADC1->TDRL = 0x02; //禁用对应AD通道的施密特触发器
ADC1->CR2 &= ~ADC1_CR2_ALIGN; //结果左对齐。
/* 特别的地方:注释掉这两行,不需要在这里设置 */
//ADC1->CSR |= ADC1_CSR_EOCIE; //使能ADC中断
//ADC1->CSR |= 0x02; //选择通道
ADC1->CR1 |= (0x20 ); //时钟4分频
ADC1->CR1 |= (ADC1_CR1_ADON); //开启ADC1电源
//这里还需要开启全局中断,省略,一般放到main函数的初始化部分开启全局中断。
}
void ADC1_Start(u8 channel)
{
/* 特别的地方: 每次启动AD转换的时候设定通道号和开启中断 */
ADC1->CSR = channel; //选择通道
ADC1->CSR |= ADC1_CSR_EOCIE; //使能ADC中断
ADC1->CR1 |= ADC1_CR1_ADON; //启动ADC1开始转换
}
@far @interrupt void ADC1_IRQHandler(void)
{
u8 adc_value = 0;
ADC1->CSR &= ~ADC1_CSR_EOC; //结束标志位清零
adc_value = ADC1->DRH;
//这里获取你的数据,你可以取高8位, 也可以把高8位和低8位全部取出来。看你的精度需要。
if( Enable_ch1_Flag )
{
Enable_ch1_Flag = 0;
//这里读取数据到你的采样数组中。
}
else if( Enable_ch2_Flag )
{
Enable_ch2_Flag = 0;
//这里读取数据到你的采样数组中。
}
else if( Enable_ch3_Flag )
{
Enable_ch3_Flag = 0;
//这里读取数据到你的采样数组中。
}
}
void ADC_Capture(void)
{
static u8 getstep = 0;
switch (getstep )
{
case 0:
ADC1_Start(CH_AD1);
Enable_ch1_Flag = 1;
Enable_ch2_Flag = 0;
Enable_ch3_Flag = 0;
getstep ++;
break;
case 1:
ADC1_Start(CH_AD2);
Enable_ch2_Flag = 1;
Enable_ch1_Flag = 0;
Enable_ch3_Flag = 0;
getstep ++;
break;
case 2:
ADC1_Start(CH_AD3);
Enable_ch3_Flag = 1;
Enable_ch1_Flag = 0;
Enable_ch2_Flag = 0;
getstep ++;
break;
default:
break;
}
}
使用思路: 在main函数初始化阶段调用ADC1_Init(),在一个500us定时器中断中调用ADC_Capture(),在ADC1_IRQHandler()中断处理函数中,读取AD值。
史海拾趣
|
1 步进电机 步进电动机是纯粹的数字控制电动机,它将电脉冲信号转变成角位移,即给一个脉冲,步进电机就转一个角度,因此非常适合单片机控制。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响, ...… 查看全部问答> |
|
1 引言 现今,随着整机尺寸的减小和元器件的高度集成,促进了元器件的小型化、薄型化。由于SAW(Surface Acoustic Wave)器件小型化并且有着出众的滤波功能,它们存许多领域的应用中扮演着非常重要的角包。小型化和多功能化是SAW器件发展的主要动力 ...… 查看全部问答> |
|
概述:步进电机主要是依相数来做分类,而其中又以二相、五相步进电机为目前市场上所广泛采用。二相步进电机每转最细可分割为400等分,五相则可分割为 1000等分, 所以表现出来的特性以五相步进电机较佳、 加减速时间较短、 动态惯性较低。 二相/ ...… 查看全部问答> |
|
本帖最后由 jameswangsynnex 于 2015-3-3 20:02 编辑 针对消费娱乐的家庭网络连接 利用多媒体家庭联网技术,各种多媒体设备 ( 例如电视机、便携式媒体播放器、照相机和蜂窝电话等) 以及数据设备 (例如PC和PDA) 可以在安全的家庭网络环境中共享音 ...… 查看全部问答> |
|
目前我手上有一台导航仪,用的是wince5.0的系统,现在我想在这台导航仪上开发一个程序。 目前的问题是,我无法直接在该导航仪上调试我的程序,只能将程序编译好后再复制到导航仪上运行,这样调试起来非常不方便。 因为我的导航仪目前是只要通过US ...… 查看全部问答> |
|
推荐一本用PowerPC开发通信设备的书,我还是第一次见同类型的书 嵌入式设计及通信设备开发详解——基于MPC82XX处理器 卓越的链接 http://www.amazon.cn/mn/detailApp?qid=1238487283&ref=SR&sr=13-1&uid=168-0888845-7367438&prodid=bkbk941360 当当的链接 http://product.dangdang.com/product.aspx?pro ...… 查看全部问答> |
|
一个非常奇怪的keil c51串口中断问题! 比如我的程序如下: uchar b[10]; #define a4 0x03 void fun1(void) interrupt 4 { fun2(2); } fun2(uchar a2) { while(a2--) { .... } fun3(a4); } void fun3(uchar a3)//这个函数无论有没 ...… 查看全部问答> |




