These two days to the external interrupt and the ADC looked down, the personal feeling that the external interruption is not difficult, it is not written down, after all, it is a waste of time to write. ADC is more complex, and if you want to make it possible to use the ADC completely freely, it has to go through many practices. Because I have learned the library function, I would like to look at the data sheet to write a simple register version of the ADC, also encountered a lot of problems, fortunately all resolved.
The focus of this study is written down, and later I do not know what it feels O (∩_∩) o haha ~
1. The analog watchdog feature allows the application to detect if the input voltage exceeds a user-defined high/low threshold.
the input clock of the ADC must not exceed 14MHz, which is generated by the PCLK2 frequency divider .
2. Power up the ADC by setting the Adon bit of the ADC_CR2 register . When the Adon bit is set for the first time, it breaks the ADC from the
Wake-up under electrical condition
3.AD Conversion Mode : Single conversion and continuous conversion (in a single conversion mode, the ADC performs only one conversion.) The mode can be set either by setting the Adon bit of the ADC_CR2 register)
(in continuous conversion mode, the current face ADC converts one end immediately to start another conversion, set in the same register)
4. Scan mode:
This mode is used to scan a set of analog channels.
The scan mode can be selected by setting the scan bit of the ADC_CR1 register. Once this bit is set, the ADC scans all channels selected by the ADC_SQRX register (to the regular channel) or ADC_JSQR (to the injection channel). Perform a one-time conversion on each channel of each group. At the end of each conversion, the next channel in the same group is automatically converted. If the cont bit is set, the conversion does not stop on the last channel of the selection group, but again continues the conversion from the first channel of the selection group.
If the DMA bit is set, after each EOC, the DMA controller transmits the conversion of the rule Group channel to the SRAM. The data injected into the channel conversion is always stored in the ADC_JDRX register.
5. Programmable Channel Sampling time:
The ADC uses several ADC_CLK cycles to sample the input voltage, and the number of sample cycles can be changed through the smp[2:0] bit in the ADC_SMPR1 and ADC_SMPR2 registers . Each channel can be sampled at different times, respectively.
The total conversion time is calculated as follows:
TCONV = Sample Time + 12.5 Cycle Period
6. Dual ADC Mode: (Synchronous injection mode, Sync rule mode, Fast crossover mode, slow crossover mode, alternate trigger mode, standalone mode)
In dual ADC mode, depending on the mode selected in the dualmod[2:0] bit of the ADC1_CR1 register, the start of the conversion can be either an alternating trigger or a synchronous trigger from ADC1 and ADC2.
Note: In dual ADC mode, when the conversion is configured to be triggered by an external event, the user must set it to trigger only the main ADC, which is set from the ADC to the software trigger, which prevents accidental triggering from the conversion . However, the primary and external triggering from the ADC must be activated at the same time.
In dual ADC mode, in order to read from the conversion data on the master data register, the DMA bit must be enabled, even if the DMA transport rule channel data is not used .
Steps to configure a simple ADC program: (Single channel)
0. Turn on the corresponding IO port clock and ADC clock, and divide the ADC in the RCC_CFGR register so that it does not exceed 14M ...
1. In ADC_CR1 Register: Set standalone mode (dualmod[3:0]: Dual mode selection), do not use scan mode, allow to generate EOC interrupts ... The rest is the default.
2. In the ADC_CR2 register: Bit Swstart (start conversion rule channel, set to convert 1), without external event start conversion, bit extsel[2:0] (select Start Rule Channel Group conversion external event, select 111, software trigger), data right alignment No DMA mode, one-time conversion mode, bit Adon (on/off A/D converter)
3.adc_smprx (ADC sampling time Register): Look at the actual situation set on the line (the total conversion time is calculated as follows: TCONV = sampling time + 12.5 cycles)
4.ADC_SQR1 Register: Default 0 is ok (because one channel)
5. In the Interrupt service function, check the EOC bit in the ADC_SR register, 1 with software, and then proceed to the next step.
6. Reading data in the ADC_DR register
Note: To calibrate when initializing the ADC, set the calibration in the ADC_CR2 register
Program:
The Learning library function writes a structure that often modifies the data, so it's much easier to rewrite the other ADC, just modify the value of the struct, but I'm not that good.
Adc.h
#ifndef _adc_h_
#define _adc_h_
typedef enum
{
Disable = 0,
Enable =!disable
}state;
typedef struct
{
unsigned int adc_modesel; Dual mode selection
State Adc_scanmodesel; Whether to turn on scan mode
unsigned int adc_externaltrigconv; External trigger Mode
unsigned int adc_datdalign; Data alignment
State Adc_dmaen; Whether to use DMA
State Adc_continuouscon; Whether to convert continuously
unsigned char Adc_numregularchan; Number of rule conversion channels
}adc_struct;
extern adc_struct Adc_structinit;
unsigned short get_value (unsigned char ch);
void Adc1_chan1_init ();
#endif
Adc.c
#include "adc.h"
#include "stm32f10x.h"
#include "Delay.h"
Adc_struct Adc_structinit =
{
0x0,//Standalone mode
Disable,//Do not turn on scan mode
0x000e0000,//software trigger mode
0x00000000,//right-justified
Disable,//Do not use DMA
Disable,//one-time conversion
1//1 channels
};
void Adc1_chan1_init ()
{
Rcc->apb2enr |= 1 << 9; Turn on the ADC1 clock
Rcc->apb2enr |= 1 << 2; Turn on the Gpioa clock
GPIOA->CRL &= ~ (0xf << 4); Analog input
Rcc->apb2rstr |= 1<<9; ADC Clock Reset
Rcc->apb2rstr &= ~ (1<<9);
Rcc->cfgr &= 0x0000c000; ADC_APB2 6 Divide 72M/6 = 12M
Rcc->cfgr |= 0x00008000;
ADC1->CR1 = 0X00F0FFFF;
ADC1->CR1 |= Adc_structinit.adc_modesel << 16; Standalone mode
ADC1->CR1 |= Adc_structinit.adc_scanmodesel << 8; Turn off scan mode
Adc1->cr2 |= Adc_structinit.adc_externaltrigconv | Software trigger
Adc_structinit.adc_datdalign | Align Right
Adc_structinit.adc_dmaen << 8 | Do not use DMA Adc_structinit.adc_continuouscon <<1; One-time conversion
ADC1->CR2 |= 1 << 20; Use external events to start the conversion (must, also depressed for half a day)
ADC1->SMPR2 |= 3 << 3; Sampling time,
Adc1->cr2 |= 0x1; Turn on the ADC (the data sheet is wrong, you must turn on the ADC before calibration, and I'm depressed for half a day)
ADC1->CR2 |= 1 << 3;
while (Adc1->cr2 & 1<<3); Reset Calibration
ADC1->CR2 |= 1 << 2;
while (Adc1->cr2 & 1<<2); Ad Calibration
}
U16 get_value (U8 ch)
{
U16 value;
ADC1->SQR3 &= 0xffffffe0; //
ADC1->SQR3 |= ch;
Adc1->cr2 |= 1<<22; Turn on rule conversion
while (!) ( ADC1->SR & 1<<1));//wait for the conversion to end
value = ADC1->DR; Read conversion value, clear 0 convert end status bit
return value;
}
Continuous acquisition of n times, averaging to improve accuracy
Http://www.chuxue123.com/forum.php?mod=viewthread&tid=9765&highlight=ADC
Re-learning STM32---(v) ADC