STM32F ADC/PWM 12 bits

Software e Hardware para uC STM

Moderadores: andre_luis, 51

STM32F ADC/PWM 12 bits

Mensagempor vtrx » 11 Mar 2021 15:42

Alguém pode tira uma dúvida minha?
O ADC do STM32f103 é de 12 bits,isso ocupa dois bytes,o PWM é de 16 bits,dois bytes.
Analisando alguns códigos na Net encontrei;
Result = (ADC_GetConversionValue(ADC1)>>2);
,segundo consta o deslocamento é para usar 10 bits.
Se eu utilizar uma saida PWM diretamente para reproduzir a entrada ananlógica(TIM2->CCR1 = Result;),o 'audio' é reproduzido,mas se eu utilizar diretamente a variável Result com o resultado da conversão,o audio não é reproduzido,tenho que dividir por 2,3 etc.
Se o PWM usa um registrador de 16 bits e o ADC retorna um valor de 12 bits,porque não reproduz diretamente,tipo Result = (ADC_GetConversionValue(ADC1)); ?
Alguem pode me explicar?
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: STM32F ADC/PWM 12 bits

Mensagempor eletroinf » 11 Mar 2021 17:18

"o pwm é de 16 bits"

Isso depende. Tu configura quantos bits é quando define o módulo do contador. Qual é o valor de seu módulo do contador?
"De cada um segundo sua capacidade a cada um segundo sua necessidade."
Avatar do usuário
eletroinf
Word
 
Mensagens: 948
Registrado em: 12 Out 2006 14:59
Localização: Santa Maria - RS

Re: STM32F ADC/PWM 12 bits

Mensagempor vtrx » 11 Mar 2021 17:32

Código: Selecionar todos
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    // Timer freq = timer_clock / ((TIM_Prescaler+1) * (TIM_Period+1))
    // Timer freq = 72MHz / ((1+1) * (1023+1) = 35.15kHz
    TIM_TimeBaseInitStruct.TIM_Prescaler = 1;
//    TIM_TimeBaseInitStruct.TIM_Period = 1023;
    TIM_TimeBaseInitStruct.TIM_Period = 800;//44khz   
    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
    TIM_Cmd(TIM2, ENABLE);

    // Step 2: Initialize PWM
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStruct.TIM_Pulse = 0;
    TIM_OC1Init(TIM2, &TIM_OCInitStruct);
    TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);

    // Step 3: Initialize TIM3 for timer interrupt
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    // Timer freq = timer_clock / ((TIM_Prescaler+1) * (TIM_Period+1))
    // Timer freq = 72MHz / ((1+1) * (1023+1) = 35.15kHz
    TIM_TimeBaseInitStruct.TIM_Prescaler = 1;
    TIM_TimeBaseInitStruct.TIM_Period = 800;//44.100
//    TIM_TimeBaseInitStruct.TIM_Period = 407;//88.200khz
//    TIM_TimeBaseInitStruct.TIM_Period = 1601;//22.050khz
    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
    // Enable TIM3 interrupt
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM3, ENABLE);
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: STM32F ADC/PWM 12 bits

Mensagempor eletroinf » 11 Mar 2021 19:10

Nesse caso
Código: Selecionar todos
TIM_TimeBaseInitStruct.TIM_Period = 800;

O seu limite de configuração de pwm é 800.
Então a configuração do duty cycle deve estar entre 0 e 800. Veja que nem chega a 10 bit.
"De cada um segundo sua capacidade a cada um segundo sua necessidade."
Avatar do usuário
eletroinf
Word
 
Mensagens: 948
Registrado em: 12 Out 2006 14:59
Localização: Santa Maria - RS

Re: STM32F ADC/PWM 12 bits

Mensagempor vtrx » 11 Mar 2021 19:48

Então se for aumentar o período a frequência PWM vai baixar obrigatoriamente se quiser aumentar a resolução?
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: STM32F ADC/PWM 12 bits

Mensagempor eletroinf » 11 Mar 2021 20:02

Exatamente.
"De cada um segundo sua capacidade a cada um segundo sua necessidade."
Avatar do usuário
eletroinf
Word
 
Mensagens: 948
Registrado em: 12 Out 2006 14:59
Localização: Santa Maria - RS

Re: STM32F ADC/PWM 12 bits

Mensagempor vtrx » 11 Mar 2021 20:07

Neste caso a solução seria um DAC dedicado?
E se o processador tivesse um clock maior?
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: STM32F ADC/PWM 12 bits

Mensagempor eletroinf » 11 Mar 2021 20:24

Funciona assim.
Tu tem o clock que alimenta o timer, geralmente é o clock da CPU podendo ser dividido pelo prescale (que pode ser configurado 1:1).
Vamos supor que tu esteja com o stm32f103 com a CPU @ 72 MHz.
Bom, vamos supor que tu queira uma resolução de 12 bit no PWM.
Bom 2^12 são 4096. Isto é, para ir de 0 a 4095 (que são 4096 steps) alimentado por 72 MHz, tu vai ter um sinal de saída de:
72 MHz/4096 = 17578,125 Hz
Entendido até aqui? Cada bit de resolução é obtido por uma contagem de pulso do clock que alimenta o Timer.
Agora, se tu quer uma frequência fixa que tu escolheu e a partir daí quer obter o valor do registrador de Período, é só mudar as variáveis da mesma conta.
Supondo que tu queiras 44 kHz de saída no PWM a partir dos 72 MHz:
Periodo = 72 MHz/44 kHz = 1636,36 -> 1636 (11 bits mas não ocupando todo o valor possível, que seria 2048)

Então basta configurar o prescale 1:1, e o período do timer (registrador de reload) em 1636.
O contador do PWM inicia em zero, com o pino pwm em zero; Quando a contagem atinge o valor definido no registrador comparador, o pino de pwm de saída vai para nível 1 e a contagem continua até chegar no valor de período, no caso 1636, situação em que o contador volta a zero e o pino de saída é zerado, recomeçando o processo.

Expliquei de forma sucinta e de cabeça, não olhei exatamente os nomes dos registradores e os detalhes, mas funciona assim.
Pode ver que se aumentar o clock da CPU aumenta a resolução de saída, em bits, para a mesma frequência do pwm.

Espero que ajude.
Abraço
"De cada um segundo sua capacidade a cada um segundo sua necessidade."
Avatar do usuário
eletroinf
Word
 
Mensagens: 948
Registrado em: 12 Out 2006 14:59
Localização: Santa Maria - RS

Re: STM32F ADC/PWM 12 bits

Mensagempor vtrx » 12 Mar 2021 15:53

Legal sua explicação.
Baseado nela,'melhorei' a resolução do seguinte modo;
1-TIM_Prescaler = 0 e TIM_TimeBaseInitStruct.TIM_Period = 2047;
2-Inicializei outro timer para(ADC),TIM_Prescaler = 0;e TIM_Period = 2047;
No momento não estou no laboratório para medir,mas esta funcionando como esperado,usando o valor do ADC dividido por 2(ADC_GetConversionValue(ADC1)>>1)
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: STM32F ADC/PWM 12 bits

Mensagempor vtrx » 14 Mar 2021 10:01

Não encontrei referencia se o ADC setup deste micro tem a opção de 8 bits de resolução no ADC.
Ele é de 12 bits,vou ter que deslocar bits para reduzir para 8?
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: STM32F ADC/PWM 12 bits

Mensagempor vtrx » 23 Mar 2021 23:07

Gastando tempo aqui um pouco,com um STM que tem DAC,o 'pipoco' de fundo sumiu...
Não sei se é por causa do DAC ou é pela frequência de 168mhz.
O problema agora é acertar o circuito de entrada pois esta distorcendo com volume de entrada a 100%(PC),tenho que reduzir a 50%.
Chiado ainda fica se aumentar muito o volume na saída sem sinal,mas pelo menos os estalos sumiram.
Minha opinião rápida aqui é que entre uma saída PWM ou DAC,pelo menos para áudio,não vi vantagem no DAC interno do micro,a não ser usar os 12 bits de resolução.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: STM32F ADC/PWM 12 bits

Mensagempor KrafT » 24 Mar 2021 08:06

Parabéns pela aula, Eletroinf. Confesso que fiquei muito feliz em ver conteúdo no AMS51 e não apenas propaganda de links para uma página concorrente.
"..."Come to the edge," he said. And so they came. And he pushed them. And they flew."― Guillaume Apollinaire
Avatar do usuário
KrafT
Dword
 
Mensagens: 2228
Registrado em: 11 Out 2006 14:15
Localização: Blumenau -SC

Re: STM32F ADC/PWM 12 bits

Mensagempor eletroinf » 24 Mar 2021 09:25

Pelo jeito que tu descreveu esse pipoco me faz acreditar que é um detalhe na configuração do PWM. Teria de ver com o osciloscópio ou salvar os valores do duty e visualizar.

Pra usar somente 8 bit, faz um RRF quando lê o valor do ADC, e tá resolvido, algo tipo:

valor_8_bit = ADC_RES >>4;

considerando ADC_RES como sendo o registrador com o resultado da conversão AD, de 12 bit.
"De cada um segundo sua capacidade a cada um segundo sua necessidade."
Avatar do usuário
eletroinf
Word
 
Mensagens: 948
Registrado em: 12 Out 2006 14:59
Localização: Santa Maria - RS

Re: STM32F ADC/PWM 12 bits

Mensagempor vtrx » 24 Mar 2021 18:40

eletroinf escreveu:Pelo jeito que tu descreveu esse pipoco me faz acreditar que é um detalhe na configuração do PWM. Teria de ver com o osciloscópio ou salvar os valores do duty e visualizar.

Pra usar somente 8 bit, faz um RRF quando lê o valor do ADC, e tá resolvido, algo tipo:

valor_8_bit = ADC_RES >>4;

considerando ADC_RES como sendo o registrador com o resultado da conversão AD, de 12 bit.

Brigadão de novo.
Fiz o upgrade do circuito,com o STM32F407,reescrevi os códigos e agora esta razoável,ADC/DAC 12bits com resultado satisfatório a 44.100khz.
No primeiro teste,usei como entrada(ADC)um pino que era compartilhado com um hardware da placa,por isso o som baixo e distorcido se eu aumentasse o sinal,vindo do PC,isso não acontecia com o outro hardware(STM32F103),tive que baixar o manual do kit e procurar o diagrama para saber como usar todos os pinos e verificar qual é compartilhado.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: STM32F ADC/PWM 12 bits

Mensagempor Guri » 26 Mar 2021 14:19

eletroinf escreveu:Funciona assim.
Tu tem o clock que alimenta o timer, geralmente é o clock da CPU podendo ser dividido pelo prescale (que pode ser configurado 1:1).
Vamos supor que tu esteja com o stm32f103 com a CPU @ 72 MHz.
Bom, vamos supor que tu queira uma resolução de 12 bit no PWM.
Bom 2^12 são 4096. Isto é, para ir de 0 a 4095 (que são 4096 steps) alimentado por 72 MHz, tu vai ter um sinal de saída de:
72 MHz/4096 = 17578,125 Hz
Entendido até aqui? Cada bit de resolução é obtido por uma contagem de pulso do clock que alimenta o Timer.
Agora, se tu quer uma frequência fixa que tu escolheu e a partir daí quer obter o valor do registrador de Período, é só mudar as variáveis da mesma conta.
Supondo que tu queiras 44 kHz de saída no PWM a partir dos 72 MHz:
Periodo = 72 MHz/44 kHz = 1636,36 -> 1636 (11 bits mas não ocupando todo o valor possível, que seria 2048)

Então basta configurar o prescale 1:1, e o período do timer (registrador de reload) em 1636.
O contador do PWM inicia em zero, com o pino pwm em zero; Quando a contagem atinge o valor definido no registrador comparador, o pino de pwm de saída vai para nível 1 e a contagem continua até chegar no valor de período, no caso 1636, situação em que o contador volta a zero e o pino de saída é zerado, recomeçando o processo.

Expliquei de forma sucinta e de cabeça, não olhei exatamente os nomes dos registradores e os detalhes, mas funciona assim.
Pode ver que se aumentar o clock da CPU aumenta a resolução de saída, em bits, para a mesma frequência do pwm.

Espero que ajude.
Abraço


Que aula...parabéns Eletroinf :roll:
DEUS SEJA LOUVADO
GURI (VonNilmam)
Guri
Byte
 
Mensagens: 457
Registrado em: 25 Abr 2010 09:05
Localização: Minas Gerais

Próximo

Voltar para STMicroelectronics

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x