STM8 ADC conversion mode-------single scan mode

Publisher:满足的36号Latest update time:2021-09-18 Source: eefocusKeywords:STM8 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

The STM8 microcontroller ADC supports five conversion modes: single mode, continuous mode, continuous mode with buffer, single scan mode, and continuous scan mode.


Single scan mode


This mode is used to convert a series of analog channels from AIN0 to AIN1, where 'n' is the channel number in the ADC_CSR register. It is started by setting the ADON bit while the CONT bit is cleared.


Note: When using the scan mode, you cannot set the I/O ports corresponding to the channels between AIN0 and AINn to output status, because the ADC multiplexer has disabled the output modules of these I/O ports.


For single scan mode, the conversion starts from AIN0 channel and the result data is stored in the data buffer register ADC_DBxR. When the last channel (channel 'n') is converted, the EOC (end of conversion) flag is set and an interrupt is generated when the EOCIE bit is set.


The conversion result values ​​of each channel can be read from the buffer register. If a data buffer register is overwritten before being read, the OVR flag will be set to 1. (See 24.5.5)


Do not clear the SCAN bit while a conversion sequence is in progress; single scan mode can be stopped immediately by clearing the ADON bit.


To start a new SCAN scan conversion, this can be achieved by clearing the EOC bit in the ADC_CR1 register and setting the ADON bit.


When reading the sampling results, you can do so by querying or by interrupting.


Single scan mode reads data code by querying:


#include "adc.h"

#include "main.h"

#include "led.h"

 

_Bool ADC_flag = 0; //ADC conversion success flag

 

u16 ADC_DB[10] = {0};

u16 adc_data[5] = {0};

 

//AD channel pin initialization

void ADC_GPIO_Init( void )

{

    PD_DDR &= ~( 1 << 2 ); //PD2 is set as input

    PD_CR1 &= ~( 1 << 2 ); //PD2 is set to floating input

 

    PD_DDR &= ~( 1 << 3 ); //PD3 is set as input

    PD_CR1 &= ~( 1 << 3 ); //PD3 is set to floating input

 

    PC_DDR &= ~( 1 << 4 ); // PC4 is set as input

    PC_CR1 &= ~( 1 << 4 ); //PC4 is set to floating input

}

 

//Set to single scan mode

//ch is the ADC channel that continuously converts the data of AIN0---AINch channel

void ADC_CH_Init( u8 ch )

{

    char l = 0;

 

    ADC_GPIO_Init();

    

    ADC_CR1 &= ~( 7 << 4 ); //Prescaler 2

    ADC_CR2 &= ~( 1 << 6 ); //Do not use external trigger

    //Disable the Schmitt trigger of AIN2 AIN4 to reduce IO static power consumption. If the Schmitt mode of the channels on PD5 and PD6 is disabled, the serial port will be unable to send and receive data!

    ADC_TDRL |= ( 1 << 2 );

    ADC_TDRL |= ( 1 << 4 );

 

    ADC_CR1 &= ~( 1 << 1 ); //single conversion

    ADC_CSR |= 0x04; //Configure the channel with the largest number

    ADC_CR2 |= ( 1 << 3 ); //right-align

 

    ADC_CR1 |= ( 1 << 0 ); //Turn on ADC

    ADC_CR2 |= ( 1 << 1 ); // SCAN = 1 to turn on scan mode

 

      //When the ADON bit is set for the first time, the ADC wakes up from low power mode. To start the conversion, the ADON bit of the ADC_CR1 register must be set a second time using the write instruction.

    for( l = 0; l < 10; l++ ); //Delay to ensure that the ADC module is powered on for at least 7us

    ADC_CR1 |= ( 1 << 0 ); //Set the lowest bit of the CR1 register to 1 again to enable ADC and start conversion

}

 

u16 ain2_val = 0,ain3_val = 0,ain4_val = 0;

//Read the sampled voltage value

u16 ReadVol_CHx( void )

{

    u16 voltage = 0;

    u16 temph = 0;

    u8 templ = 0;

    while( 1 )

    {

 

        LED = !LED; //The program takes 15us to run one circle    

        ADC_CR1 |= 0x01; //Start a conversion

        while( ( ADC_CSR & 0x80 ) == 0 ); //Wait for the conversion to end

        ADC_CSR &= ~( 1 << 7 ); // Clear the conversion end flag EOC

 

        //Read the value of AIN2

        templ = ADC_DB2RL;

        temph = ADC_DB2RH;

        temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

        ain2_val = temph;

        

        //Read the value of AIN3

        templ = ADC_DB3RL;

        temph = ADC_DB3RH;

        temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

        ain3_val = temph;

 

 

        //Read the value of AIN4

        templ = ADC_DB4RL;

        temph = ADC_DB4RH;

        temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

        ain4_val = temph;

    }

    return voltage;

}

Single scan mode reads data code through interruption:


#include "adc.h"

#include "main.h"

#include "led.h"

 

_Bool ADC_flag = 0; //ADC conversion success flag

 

u16 ADC_DB[10] = {0};

u16 adc_data[5] = {0};

 

//AD channel pin initialization

void ADC_GPIO_Init( void )

{

    PD_DDR &= ~( 1 << 2 ); //PD2 is set as input

    PD_CR1 &= ~( 1 << 2 ); //PD2 is set to floating input

 

    PD_DDR &= ~( 1 << 3 ); //PD3 is set as input

    PD_CR1 &= ~( 1 << 3 ); //PD3 is set to floating input

 

    PC_DDR &= ~( 1 << 4 ); // PC4 is set as input

    PC_CR1 &= ~( 1 << 4 ); //PC4 is set to floating input

}

 

//Set to single scan mode

//ch is the ADC channel that continuously converts the data of AIN0---AINch channel

void ADC_CH_Init( u8 ch )

{

    char l = 0;

    ADC_GPIO_Init();

 

    ADC_CR1 &= ~( 7 << 4 ); //Prescaler 2

    ADC_CR2 &= ~( 1 << 6 ); //Do not use external trigger

    //Disable the Schmitt trigger of AIN2 AIN4 to reduce IO static power consumption. If the Schmitt mode of the channels on PD5 and PD6 is disabled, the serial port will be unable to send and receive data!

    ADC_TDRL |= ( 1 << 2 );

    ADC_TDRL |= ( 1 << 4 );

 

    ADC_CR1 &= ~( 1 << 1 ); //single conversion

    ADC_CSR |= 0x04; //Configure the channel with the largest number

    ADC_CR2 |= ( 1 << 3 ); //right-align

 

    ADC_CR1 |= ( 1 << 0 ); //Turn on ADC

    ADC_CR2 |= ( 1 << 1 ); // SCAN = 1 to turn on scan mode

 

    ADC_CSR |= ( 1 << 5 ); //EOCIE enable conversion end interrupt

 

    //When the ADON bit is set for the first time, the ADC wakes up from low power mode. To start the conversion, the ADON bit of the ADC_CR1 register must be set a second time using the write instruction.

    for( l = 0; l < 10; l++ ); //Delay to ensure that the ADC module is powered on for at least 7us

    ADC_CR1 |= ( 1 << 0 ); //Set the lowest bit of the CR1 register to 1 again to enable ADC and start conversion

}

 

//AD interrupt service function interrupt number 22

#pragma vector = 24 // The interrupt number in IAR needs to be added to the interrupt number in STVD by 2

__interrupt void ADC_Handle( void )

{

    ADC_CSR &= ~( 1 << 7 ); // Clear the conversion end flag EOC

 

    //Single channel scanning mode, the conversion result is stored in the ADC_DBxR register

    LED = !LED; //The program takes 20us to run one circle

 

    //Read the value of AIN2

    templ = ADC_DB2RL;

    temph = ADC_DB2RH;

    temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

    ain2_val = temph;

 

    //Read the value of AIN3

    templ = ADC_DB3RL;

    temph = ADC_DB3RH;

    temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

    ain3_val = temph;

 

    //Read the value of AIN4

    templ = ADC_DB4RL;

    temph = ADC_DB4RH;

    temph = ( u16 )( templ | ( u16 )( temph << ( u16 )8 ) );

    ain4_val = temph;

 

    ADC_CR1 |= 0x01; //Start a conversion

    ADC_flag = 1; // ADC interrupt flag is set to 1

}

Keywords:STM8 Reference address:STM8 ADC conversion mode-------single scan mode

Previous article:STM8 ADC conversion mode ------- continuous scan mode
Next article:STM8 ADC conversion mode ------- continuous mode with cache

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号