Página 1 de 2

Probleminha no ADC do STM32F

MensagemEnviado: 20 Fev 2019 23:57
por Guri
Caros colegas, estou com um probleminha que esta torrando minha paciência...e peço ajuda de vocês!

Estou utilizando um STM32F051r8t6, com clock de 48mhz (pll x 12 com cristal de 4mhz). Estou utilizando o mikrocArm.

O que acontece é o seguinte:
Coloquei um potenciômetro de 10k lin, na entrada do ADC ligando a 3v3 e gna.
Eu fiz uma placa para meus testes com ARM e tomei o CUIDADO de ligar corretamente os GNDs e GNAs como manda o figurino de layout nesses casos especificos.

O que esta me tirando o sono é que o AD fica "variando" como um doido sua saída convertida, eu liguei 12 leds num dos portes, PORTB0 á 11, devidamente polarizados por resistores de 1k.

O que pode ser isso, alguém já passou por isso?

Esse trecho é o exemplo da mikroc no help:
O detalhe interessante é que uso a mesma rotina num PIC877A e funciona corretamente, sem esse problema, é como se a conversão fosse abalada por um ruido que instabiliza a conversão final de saída.


cpp code
ADC_Set_Input_Channel(_ADC_CHANNEL_5);               // ADin 
ADC1_Init(); // Init
//------------------------------------------------------
// MAIN
//------------------------------------------------------
while(1) {

GPIOB_ODR=ADC1_Get_Sample(5);
Delay_ms(100);

}

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 03:54
por cfreund
Todos os LEDs? Se for somente os que representam LSB é esperado. Faz uma média da leitura do ADC.

Outra coisa que vai ajudar no seu caso:
Código: Selecionar todos
ADC1->SMPR = (ADC_SMPR_SMP_2 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_0);


Outra coisa: não só VSSA, como também ligar VDDA.

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 08:27
por Guri
Sim, cfreund .


Peço perdão, realmente é como você disse, o ADC esta no modo 12bits (Aliás é possivel lêr apenas o MSB 8 bits superiores?). Não são todos os leds que estão no portB ligados a saída do ADC que oscilam, oscilam apenas os que estão na parte mais baixa, pude notar que são os primeiros 4 bits LSB... :roll:

Esqueci de mencionar, não sei se fiz certo, mas configurei o pino de entrada AD como analógico, tipo assim: GPIO_Analog_Input(&GPIOA_BASE, _GPIO_PINMASK_5); // ADin 5.
Sendo que tanto faz se configurar como entrada digital... :mrgreen:

Vou testar suas dicas cfreund, sou muito grato pela ajuda.

Pesquisando na internet achei esse material muito bom sobre os ADCs ARM STM, http://embedded-lab.com/blog/stm32-adc-2/

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 08:50
por dreher
Guri escreveu:Sim, cfreund .


Peço perdão, realmente é como você disse, o ADC esta no modo 12bits (Aliás é possivel lêr apenas o MSB 8 bits superiores?). Não são todos os leds que estão no portB ligados a saída do ADC que oscilam, oscilam apenas os que estão na parte mais baixa, pude notar que são os primeiros 4 bits LSB... :roll:

Esqueci de mencionar, não sei se fiz certo, mas configurei o pino de entrada AD como analógico, tipo assim: GPIO_Analog_Input(&GPIOA_BASE, _GPIO_PINMASK_5); // ADin 5.
Sendo que tanto faz se configurar como entrada digital... :mrgreen:

Vou testar suas dicas cfreund, sou muito grato pela ajuda.

Pesquisando na internet achei esse material muito bom sobre os ADCs ARM STM, http://embedded-lab.com/blog/stm32-adc-2/

A fonte não tem ruidos?
Alem disso para ler só os 8MSB podes fazer assim: (ADC1_Get_Sample(5))>>4;

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 09:11
por Guri
Segue as conecções para o ADC.

Eu estou tendo erros de compilação...diz que o trecho do código contém erros de declaração. Desculpe minha ignorância, não consigo ver onde estou errando.

Outra informação, estou declarando essa lib: #include <built_in.h>

Obrigado

Sem título-1.jpg

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 09:15
por cfreund
Se puder, compartilha o código q o pessoal da uma força.

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 09:20
por Guri
Até que eu gostaria de postar o código inteiro, mas é enorme, tem 25k de código.

O que está custando eu entender e como configurar corretamente o ADC...

O código que postei acima é o que estou utilizando,

Agradeço a ajuda.

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 09:28
por cfreund
Pela documentação, é isso mesmo. http://download.mikroe.com/documents/co ... ibrary.htm

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 10:13
por dreher
De quanto em quanto tempo voce faz a leitura do ADC?

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 10:33
por cfreund
Não conheço essa lib, mas provavelmente está configurada no modo single shot.

Acredito q a função ADC1_Get_Sample() funcione da seguinte forma:

Configuração dos registradores do ADC;
Selecionado o pino;
Início da conversão;
Loop enquanto aguarda fim da conversão;
Retorno do valor lido;

Logo, ao chamar a função, o CPU vai ficar travado dentro de um loop aguardando o fim da leitura. Se precisar saber o tempo gasto nisso, vai ter q ler como os registradores estão configurados e consultar o Reference Manual.

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 11:50
por pamv
Guri
Você não pensou em imprimir a leitura do ADC na tela do computador? Facilitaria muito para entender onde que está de fato a oscilação

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 13:12
por Guri
dreher, eu já tentei fazer a leitura de todo jeito que imaginei, pensei e fiz também dando um delay de 1 segundo, mas instabilidade continua. É como se houve-se um ruido interferindo na leitura...coisa de doido.

Experimentei, deslocar a direita 4 bits e assim diminuir a resolução para 8 bits, 'melhorou', mas ainda nota-se a instabilidade...pelo que percebi isso ocorre com maior intensidade nos bits mais baixos.

Eu ainda não tentei imprimir as leituras feitas.

Só para entender, eu utilizo um FILTRO anti ruido, esse ruido é devido as características mecânicas de um potencômetro, normalmente essa variação acontece na transição de um bit para o próximo, dependendo da posição do potenciômetro em relação a conversão, pode ser que caia nesse 'buraco' de conversão e o conversor AD, fica tentando ler a grandeza, assim varia entre um bit e outro.

Esse filtro já utilizo a muitos anos em pics e avrs, tanto faz se uso em 8 bits ou 10 bits, funciona perfeitamente.

Os pulos que o AD do STM dá é tão grande e aleatório que o meu filtro não consegue estabilizar, melhora bastante, se comparado sem o uso do filtro.

Eu só sei que estou fazendo alguma coisa errada e queria saber o do porque esse AD faz isso....NOTA: usei um kit discovery e também fiz a minha própria plaquinha com mais capricho.

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 18:27
por pamv
É muito curioso, eu não tenho problema com o ADC, de você conecta-lo diretamente num dos pinos 3.3 V da placa ele continua oscilando?

Re: Probleminha no ADC do STM32F

MensagemEnviado: 21 Fev 2019 21:51
por eletroinf
Buenas pessoal

Eu acho meio impossível deduzir o problema sem ver o código.
coloco aqui um código que utilizo e está funcionando, neste caso eu utilizo os dois conversores (1 e 2), tu pode comentar um deles se não precisar, mas sugiro utilizar para tentar entender o que o seu código está fazendo aí.
Não recomendo a um iniciante utilizar estas bibliotecas prontas. É mais fácil seguir o datasheet, olhando as funções dos registradores e configurando eles da forma desejada.
Boa sorte nesta empreitada!

Obs: Use com um guia, pois eu peguei de um código que faz tempo que não utilizo, portanto posso ter esquecido alguma coisa na inicialização :D
Obs2: Este código funciona no Keil

Código: Selecionar todos
/**********************************************************************************
Configuração do conversor ADC1 e ADC2
ADC1 independent mode
A cada disparo, realizo a leitura "Single convertion mode"
Entradas analógicas: A0 ~A5.
Tconv = Sampling Time + 12.5 cycles - ref. man. p. 224
ADC clock: Source = PCLK2 com resc./2 = 72 MHz/2 = 36 MHz.
ADC presc = 1/4 -> Clock ADC = 36/4 = 9 MHz.
Tconv = [Ts + 12.5] cycles = 7.5 + 12.5 cycles @ 9 MHz = 2.2 us each channel.
**********************************************************************************/
void ADC12_Config(void)
{
        RCC->CFGR |= BIT_13;       //  PCLK2 = HCLK/2 = 72 MHz/2 = clock para TIM1 & ADC.

   // Primeiro configuro os pinos como entrada analógica:
   GPIOA -> CRL &= ~(BIT_23 + BIT_22 + BIT_21 + BIT_20 + BIT_19 + BIT_18 + BIT_17   + BIT_16   // PA5, PA4
   + BIT_15 + BIT_14 + BIT_13 + BIT_12 + BIT_11 + BIT_10 + BIT_9 + BIT_8    // PA3, PA2
   + BIT_7 + BIT_6 + BIT_5 + BIT_4 + BIT_3 + BIT_2 + BIT_1 + BIT_0);            // PA2, PA1 analógicos.
   //GPIOC -> CRL &= ~(BIT_23 + BIT_22 + BIT_21 + BIT_20);      // PC5 analógico.

   RCC->APB2ENR |= (BIT_10 + BIT_9);    // Ligo clock de <ADC2:ADC1>    

   RCC->CFGR |=  BIT_14;      // ADC clock prescaler: PCLK2/CFGR<15:14> = PCLK2/4 = 36/4 = 9 MHz.   
   
   /* Independent mode */
   ADC1 -> CR1 = 0;
   
   ADC2 -> CR1 = 0;

   ADC1 -> CR2 = BIT_0;    // ADC1 ON   
   ADC2 -> CR2 = BIT_0;   // ADC2 ON
   
   delay_ms_0 = 2;
   while(delay_ms_0);
   
   ADC1 -> SQR1 = 0;
   ADC2 -> SQR1 = 0;
   
   ADC1 -> CR2 |= BIT_3;       // Reset calibration ADC1
   ADC2 -> CR2 |= BIT_3;       // Reset calibration ADC2

   ADC1 -> CR2 |= BIT_2;       // Enable calibration ADC1
   ADC2 -> CR2 |= BIT_2;       // Enable calibration ADC2

   while((ADC1->CR2 & BIT_2) || (ADC2 -> CR2 & BIT_2)); // wait calibration complete

   // Sample time selection -  7.5 cycles para cada canal. Canais <A5:A0>
   ADC1 -> SMPR2 = (BIT_15 + BIT_12 + BIT_9 + BIT_6 + BIT_3 + BIT_0);
   ADC2 -> SMPR2 = (BIT_15 + BIT_12 + BIT_9 + BIT_6 + BIT_3 + BIT_0);

   ADC1 -> CR2 |= BIT_0;      // Ligo novamente ADC1 (necessário no Power-on).
   ADC2 -> CR2 |= BIT_0;      // Ligo novamente ADC2 (necessário no Power-on).
   
   ADC1 -> DR;                     // leitura pra limpar flags
   ADC2 -> DR;
   
   delay_ms_0 = 2;
   while(delay_ms_0);         // Tempinho pra iniciar os ADCs.
   
   ADC1 -> SQR3 = 0;   // ch0 -bits <4:0> Select the ADC1 channel to be read
   ADC2 -> SQR3 = 3;   // ADC2 -> ch3
   
   /* Reading ADC
   Select the channel in SQR3 <4:0>
   Set Bit ADC_ON to start the adc read
   Test bit flag EOC in SR
   ADC1 -> SQR3 = ;   // bits <4:0> Select the ADC1 channel to be read
   ADC2 -> SQR3 = ;   // bits <4:0> Select the ADC2 channel to be read
   */

}

Re: Probleminha no ADC do STM32F

MensagemEnviado: 22 Fev 2019 01:34
por cfreund
Guri escreveu:eu já tentei fazer a leitura de todo jeito que imaginei, pensei e fiz também dando um delay de 1 segundo, mas instabilidade continua.


Em vez de ler a cada segundo, faça:
Código: Selecionar todos
int adc_read_channel(int ch)
{
   unsigned int value, times;
   
   ADC1->SMPR = ADC_SMPR_SMP_2 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_0;   // Sampling time: 239.5 ADC clock cycles = 18uS
   
   for (times = 0; times < 100; ++times)
      value += ADC1_Get_Sample(ch);
   
   return value / times;
}


Guri escreveu:Experimentei, deslocar a direita 4 bits e assim diminuir a resolução para 8 bits, 'melhorou', mas ainda nota-se a instabilidade...pelo que percebi isso ocorre com maior intensidade nos bits mais baixos.


No seu caso, nenhuma necessidade de resolução alta, logo diminua-a o máximo possível.