1. Capacidade do produto da série do microcontrolador STM32F10xxx
- Produtos pequenos referem -se aos microcontroladores STM32F101xx, STM32F102xx e STM32F103xx com capacidades de memória flash entre 16K e 32K bytes .
- Os produtos de média densidade referem -se aos microcontroladores STM32F101xx, STM32F102xx e STM32F103xx com capacidades de memória flash entre 64K e 128K bytes .
- Os produtos de alta densidade referem -se aos microcontroladores STM32F101xx e STM32F103xx com capacidades de memória flash entre 256K e 512K bytes .
- Os produtos interconectados referem-se aos microcontroladores STM32F105xx e STM32F107xx.
2. Introdução ao ADC
Confira o manual de referência oficial STM32F10xxx da ST , o ADC de 12 bits é um conversor analógico-digital de aproximação sucessiva. Possui até 18 canais e pode medir 16 fontes externas e 2 internas . A conversão A/D de cada canal pode ser realizada em modo único, contínuo, de varredura ou descontínuo . O resultado do ADC pode ser armazenado em um registrador de dados de 16 bits alinhado à esquerda ou à direita .
Um recurso de watchdog analógico permite que o aplicativo detecte se a tensão de entrada excede um limite alto/baixo definido pelo usuário.
O clock de entrada do ADC não deve exceder 14MHz, que é gerado pela divisão da frequência de PCLK2.
3. Principais características do ADC
- resolução de 12 bits
- Interrupção no final da conversão, final da conversão injetada e evento de watchdog analógico
- Modos de conversão simples e contínua
- Modo de varredura automática do canal 0 ao canal n
- auto-calibração
- Alinhamento de dados com consistência de dados incorporados
- O intervalo de amostragem pode ser programado individualmente por canal
- Tanto as transições de regra quanto as transições de injeção têm opções de acionamento externo
- modo intermitente
- Modo duplo (dispositivos com 2 ou mais ADCs)
- Tempo de conversão ADC:
─STM32F103xx produtos aprimorados: 1μs quando clock é 56MHz (1,17μs quando clock é 72MHz)
─ STM32F101xx produtos básicos: 1μs quando clock é 28MHz (1,55μs quando clock é 36MHz)
─ STM32F102xxProdutos do tipo USB: clock 1,2μs a 48MHz
─ Produtos STM32F105xx e STM32F107xx: 1μs em clock de 56MHz (1,17μs em clock de 72MHz) - Requisitos de alimentação ADC: 2,4 V a 3,6 V
- Faixa de entrada ADC: VREF- ≤ VIN ≤ VREF+
- Uma solicitação de DMA é gerada durante a conversão regular do canal.
4. A diferença entre canais regulares e canais de injeção
STRT Sinalizador de início de canal regular (Sinalizador de início de canal regular)
JSTRT: Sinalizador de início de canal injetado (Sinalizador de início de canal injetado)
Ao aprender ADC, não entendi por que os canais ADC são divididos em canais regulares e canais de injeção? Essa regra e injeção não são apenas difíceis de lembrar, mas também difíceis de falar, e seu significado é ainda mais intrigante. Consulte o manual de referência em inglês para saber que o canal Regular em inglês é traduzido como canal regular e o canal injetado é traduzido como canal de injeção. Bem, na verdade, o pensamento dos estrangeiros é realmente um pouco diferente do nosso. O significado que você quer expressar é traduzido sem rodeios em duas palavras: regra e injeção devido às diferenças de cultura e idioma. Bem, o nome é apenas para melhor expressão . Ao descrever algo, assim como Zhang San e Li Si, o significado de sua aplicação é muito maior do que o significado do nome. Você não precisa prestar muita atenção a isso. Se você se sentir contundente, chame-o de Regular e injetado!
Depois de entender a vida passada e presente do nome, vamos discutir o significado de sua expressão, aqui cito as opiniões de internautas que considero melhores. Link original: http://bbs.ednchina.com/BLOG_ARTICLE_225912.HTM
-------------------------------------Linha divisória----------- --------------------------------------------
Insights dos internautas:
Cada módulo ADC do STM32 pode alternar para diferentes canais de entrada e converter através do multiplexador analógico interno. O STM32 adicionou especialmente uma variedade de modos de conversão de grupo, que podem ser automaticamente amostrados e convertidos um por um para vários canais analógicos após serem definidos pelo programa.
Existem 2 maneiras de dividir grupos de transformação: grupo de canais regulares e grupo de canais de injeção. Normalmente, um máximo de 16 canais podem ser organizados em um grupo de canais regular e um máximo de 4 canais podem ser organizados em um grupo de canais de injeção.
Ao realizar uma conversão de varredura de grupo de canais regular, a conversão que injeta o grupo de canais pode ser habilitada se houver processamento adicional.
Uma analogia inadequada é que a conversão do grupo de canais regular é como a execução normal do programa, e a conversão do grupo de canais de injeção é como um manipulador de interrupção fora da execução normal do programa.
Outro exemplo que não é necessariamente usado:
se você colocar 5 sondas de temperatura no quintal de casa e 3 sondas de temperatura dentro de casa; você precisa monitorar a temperatura externa o tempo todo, mas ocasionalmente você quer verificar a temperatura interna; Então você pode usar o grupo de canais regular para percorrer 5 sondas externas e exibir os resultados da conversão AD, quando você quiser ver a temperatura interna, inicie o grupo de conversão de injeção (3 sondas internas) com um botão e exiba temporariamente a temperatura interna, quando você colocar Depois este botão estiver ativado, o sistema retornará ao grupo de canais normal para continuar a detectar a temperatura externa.
Em termos de design do sistema, o processo de medição e exibição da temperatura interna interrompe o processo de medição e exibição da temperatura externa, mas no design do programa, diferentes grupos de conversão podem ser configurados na fase de inicialização e a configuração do cíclico a conversão não precisa ser alterada durante a operação do sistema. Obtenha o resultado de que as duas tarefas não interferem uma na outra e alternam rapidamente. Pode-se imaginar que se não houver divisão de grupos de regras e grupos de injeção, ao pressionar o botão, é necessário reconfigurar os canais de varredura do ciclo AD, e então é necessário configurar novamente os canais de varredura do ciclo AD após liberar o botão.
O exemplo acima não pode refletir totalmente os benefícios dessa distinção (grupo de regras e grupo de injeção) devido à sua velocidade lenta, mas em aplicações industriais há muitas sondas de detecção e monitoramento que precisam ser processadas mais rapidamente, portanto, agrupar conversões de AD simplificará os eventos. processar e aumentar a velocidade de processamento de eventos.
-------------------------------------Linha divisória----------- --------------------------------------------
5. A Blue Bridge Cup inspeciona os pontos ADC
Placa de competição embarcada CT117E (no caso de não utilizar a versão estendida), pode-se observar no diagrama esquemático do circuito do CT117Ev1.1 que o pino de aquisição de tensão PB0 do ADC ajusta a tensão no circuito divisor de tensão através do potenciômetro R37 .
Confira o Datasheet de stm32f103rbt6
(1) Distribuição geral de recursos
(2) Distribuição de recursos ADC
PC0~PC3
PA0~PA3
PA4~PA7; PC4~PC5; PB0~PB1 (desta vez, o pino PB0 é usado!)
6. Entenda o modo ADC de configuração
(1) Vamos começar com a função da biblioteca STM32 e dar uma olhada em
ADC_InitTypeDef ADC_InitStructure;
typedef struct
{
uint32_t ADC_Mode; /*!< Configures the ADC to operate in independent or
dual mode.
This parameter can be a value of @ref ADC_mode */
FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion is performed in
Scan (multichannels) or Single (one channel) mode.
This parameter can be set to ENABLE or DISABLE */
FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in
Continuous or Single mode.
This parameter can be set to ENABLE or DISABLE. */
uint32_t ADC_ExternalTrigConv; /*!< Defines the external trigger used to start the analog
to digital conversion of regular channels. This parameter
can be a value of @ref ADC_external_trigger_sources_for_regular_channels_conversion */
uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment is left or right.
This parameter can be a value of @ref ADC_data_align */
uint8_t ADC_NbrOfChannel; /*!< Specifies the number of ADC channels that will be converted
using the sequencer for regular channel group.
This parameter must range from 1 to 16. */
}ADC_InitTypeDef;
7. Configure o modelo ADC
Etapas para configurar o ADC:
1. Configure os pinos GPIO relacionados ao ADC, como coleta de sinais de tensão, os pinos GPIO são configurados como entradas analógicas.
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
2. Configuração do ADC
-
Modo ADC (modo independente, modo de varredura, modo de conversão contínua)
ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; /* 连续转换模式---不难理解---就是不停地采集---一次接一次 */
-
fazer sem usar um gatilho externo? (ADC_ExternalTrigConv); Triggers são divididos em triggers externos, como interrupções e temporizadores. Gatilho de software -> use função dedicada.
-
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
-
O alinhamento dos dados coletados pelo ADC e o número de canais convertidos
-
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//采集的数据右对齐---方便计算 ADC_InitStructure.ADC_NbrOfChannel = 1; //总共需要转换的通道个数 ADC_Init(ADC1, &ADC_InitStructure);
-
To ADC_Init(ADC1, &ADC_InitStructure); Nesta etapa, inicializamos a estrutura DC_InitStructure que trabalhamos duro para configurar.
Resumo do erro: Eu encapsulei as várias configurações de inicialização do ADC em uma função, o que não é um problema, mas nomeei essa função como ADC_Init() e ocorreu um erro, pois esse nome de função foi usado, ADC_Init(ADC1 , &ADC_InitStructure); então mudou para adc_Init()
/* ADC1 regular channel_8 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_13Cycles5);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
8. Código do programa
Função de implementação: AD amostra a tensão no PB0 a cada 100ms e calcula o valor da tensão (retém 2 casas decimais) e o exibe na linha Line1 do LCD.
Blog de referência : https://blog.csdn.net/Zach_z/article/ detalhes /80548423
(1) arquivo ADC.c
/* PB0———ADC_IN8 / TIM3_CH3 */
#include "ADC.h"
void adc_Init()
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOB,ENABLE);
/*配置ADC相应的GPIO,这里配置PB0(ADC_IN8)作为模拟输入------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* ADC1 configuration -----------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //连续转换模式---不难理解---就是不停地采集---一次接一次
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
/* 不使用外部触发转换---触发分为外部触发---比如中断与定时器。
软件触发---后面有专用函数 */
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//采集的数据右对齐---方便计算
ADC_InitStructure.ADC_NbrOfChannel = 1; //总共需要转换的通道个数
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel_8 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_13Cycles5);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
u16 get_adc()
{
u16 value;
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
value = ADC_GetConversionValue(ADC1);
return value;
}
(2) arquivo main.c
#include "stm32f10x.h"
#include "stdio.h"
#include "ADC.h"
void Delay_ms(unsigned int ms)
{
unsigned int i,j;
for(i=0; i<ms; i++)
{
for(j=0; j<8450; j++) ;
}
}
int main()
{
u16 adc_value;
u8 str[20];
STM3210B_LCD_Init();
Delay_ms(100);
LCD_SetTextColor(White);
LCD_SetBackColor(Black);
LCD_ClearLine(Line0);
adc_Init();
while(1)
{
adc_value=get_adc();
sprintf(str," PB0: %.2f V",(float)adc_value/4096*3.3);
LCD_DisplayStringLine(Line1, str);
Delay_ms(100);
}
}