STM8S003/903 使用ADC中断功能

  对使用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值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值