Ir ao conteúdo
  • Cadastre-se
classd2008

PWM 100 Khz com ATTINY

Recommended Posts

Olá amigos. Sou programador de PC e sempre programei PIC em BASIC (PROTON-IDE). Estou desenvolvendo um projeto e queria usar um ATTiny85 para fazer um amplificador. A ideia é fazer a leitura ADC de audio e gerar um PWM normal com 100Khz e outra saída PWM invertida com 100Khz também. Alguém poderia me passar um exemplo ou um código de como fazer isso em BASCOM ou mesmo no ARDUINO? Este vídeo mostra mais ou menos como fazer o que eu quero, mas não consigo subir a frequência para 100Khz ou mais. Muito obrigado. http://www.youtube.com/watch?v=__ECzxnvEg8

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@classd2008,

 

Se voce vai usar as duas saídas, significa que você quer utilizar o Timer1, portanto não poderá usar um oscilador externo e vai ter de trabalhar com o clock interno a 8 Mhz. Não dá para atingir nem a metade dos 100 Khz !

 

Existem alguns Atttiny feitos para gerarem altas frequências de PWM, na faixa de 250 kHZ. Use um desses !

 

Eu até consegui gerar frequencias acima de 100 Khz com Avrs comuns, mas para isso tive de diminuir muito os bits do PWM. Creio que com 5 bits dá para fazer essa frequência, mas vai perder muita qualidade, ok ?

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Paulo  @aphawk muito obrigado pela resposta. Sim a ideia é gerar esta frequência com oscilador interno. E como seria gerar esta frequência de 100 Khz a 5 bits. Um exemplo seria muito bom se você me passasse. Uma outra coisa é. será que com o ATTiny841 eu conseguiria esta frequência com mais qualidade?


Como seria para aplicar esta tabela em BASCOM?

post-767323-0-67406600-1432219189_thumb.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sugiro procurar no seu compilador uma maneira de acessar os registros internos do seu mc. Além á claro de dar uma lidinha no datasheet. Mas isso é óbvio demais então espero que nem tenha lido este comentário.

 

Agora sério ... legal seu projeto! você quer fazer algo como um amplificador classe D? Se sim, o conversor ad tem velocidade pra medir sinais audíveis de frequencia +- alta?

Me fez lembrar que certa feita fiz um oscliloscópio com pic mas não consegui mostrar direito no display gráfico sinais de freq maiores que 5Khz devido a limitação da velocidade da conversão. Se o conversor ad do seu trabalhar rapidinho, quem sabe num futuro tento algo com ele.  A qualquer momento dou uma olhada no d.s. do bixo...

 

abç

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isadora a ideia é essa mesmo. Usando um IRS20957 e fazer o amplificador ClassD em FullBridge, já que este drive requer somente uma entrada PWM. Então usaria 2 Drives e um ATTinyXXX, com uma saída PWM normal e a outra invertida. Mas como não sou programador AVR preciso desse código de exemplo para fazer as alterações necessárias. Queria usar o BASCOM pois programa em BASIC seria mais fácil entender. Se puder me ajudar eu agradeço muito.

Compartilhar este post


Link para o post
Compartilhar em outros sites

A maneira de gerar várias frequências altas sacrificando a resolução do PWM está bem demonstrada aqui :

 

http://mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=11809&highlight=1mhz+pwm&sid=a9a5efc0a24091fa213ac54dc75b9ef9

 

Mas o que vai te resolver mesmo todos os problemas é usar um Attiny861, vai conseguir fácil 250 Khz no PWM de 8 bits....

 

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

olá amigo. Há alguns anos fiz um projetinho (que virou) com attiny26 em c pra medir corrente & tensão. O legal é que ele tem ampop 20x. Usei pra medir corrente (tensão num shunt) com sucesso e relativa precisão. Infelizmente basic foi a 1ª linguagem que tive contato la pelos idos dos 1980´s. Como estava me causando pouca adrenalina, migrei pro c e ... resumindo, veja uma função read_adc() que bolei em c pro attiny261

unsigned int read_adc(unsigned char ch){unsigned char dl;dl=20;ADCSRA=0x87;ADMUX=ADC_VREF_256 | ch;  //ref= 2.56V interno// delay_ms needed for the stabilization of the ADC input voltagewhile(dl--);// Start the AD conversionADCSRA|=0x40;// Wait for the AD conversion to completewhile (!ADCSRA_Bit4);//while (!ADCSR_Bit4); //attiny26ADCSRA|=0x10;return ADC;//(unsigned int)ADCH*256+(unsigned int)ADCL;}

Como prometido, dei uma olhadela no d.s. do seu mc, notei que pode atender seus requisitos (o ad dele é bem rápido) no entanto preferi não me aprofundar muito ok? Mas num é difícil não! Dá uma olhadela na nomenclatura dos registros e bits. Pode haver semelhança ao fonte acima.

pwm a alta frequencia=ok. o problema seria o conversor analogico-digital corresponder. Essencialmente você vai ter que setar o duty cicle com o valor que capturou do ad

Crie uma função setduty()

Seu programa se resumiria a (depois de inicializar o hw claro)

for (; setduty(read_adc(0)); //p.ex.

Sorry, just in c. Mas pode não lhe ser totalmente inútil

Como vai usar um canal só, talvez não precise do "delay_ms  for the stabilization of the ADC input voltage". De fato ele atrapalharia

 

Existem ci´s pra amplificador classe d sabia? mas já sei... adrenalina....

abç

Compartilhar este post


Link para o post
Compartilhar em outros sites

$regfile = "ATtiny85.DAT"$crystal = 8000000Config Portb = OutputPortb = &B00001110Config Timer0 = Pwm , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down , Prescale = 1Enable Timer0Enable InterruptsTccr0a.wgm01 = 1 'set fast mode'50% Dute-cicle pino 5Pwm0a = 127'50% Dute-cicle pino 6 invertidoPwm0b = 127DoLoopEnd

O máximo que consigo com esse código é 4 khz, não sobe.

$regfile = "ATtiny85.DAT"$crystal = 8000000Config Portb = OutputPortb = &B00001110Config Timer0 = Pwm , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down , Prescale = 1Enable Timer0Enable InterruptsTccr0a.wgm01 = 1 'set fast mode'50% Dute-cicle pino 5Pwm0a = 127'50% Dute-cicle pino 6 invertidoPwm0b = 127DoLoopEnd

O máximo que consigo com esse código é 4 khz, não sobe.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@classd2008,

 

com este código :

$regfile = "attiny85.dat"$crystal = 8000000$hwstack = 40$swstack = 16$framesize = 32Config Portb = OutputPortb = &B00001110Config Timer0 = Pwm , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down , Prescale = 1Enable Timer0Enable InterruptsTccr0a.wgm01 = 1 'set fast mode'50% Dute-cicle pino 5Pwm0a = 127'50% Dute-cicle pino 6 invertidoPwm0b = 127DoLoopEnd

Consigo 31.250 Hz ......

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

No meu osciloscópio esta dando somente 3.790 hz, onde esta o erro? Estou programando com USBAsp 2.0 e rodando com 5V sem cristal... cristal interno de 8Mhz.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@classd2008,

 

Não se desespere porque é bem simples .....

 

Se voce não acertou os Fuses na hora de gravar e o seu Attiny é novinho de fábrica, ele vem configurado para DIVIDIR O CLOCK POR 8 ......!!

 

Então na verdade o seu clock real é 1 Mhz, meu amigo !

 

Corrija esse Fuse e regrave que vai funcionar direitinho .....

 

Se tiver dúvida em como fazer isso, baixe o meu tutorial que tem bastante explicação sobre isso :

 

http://forum.clubedohardware.com.br/topic/937085-tutorial-de-projetos-com-avr-design-programa%C3%A7%C3%A3o-em-basic-e-simula%C3%A7%C3%A3o-no-proteus/#entry5252683

 

Paulo

 

 

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

paulo veja este código, foi feito no Arduino - Usando ARDUINO ISP para gravar no attiny85. Ele gerou 500Khz, mas o problema é que não consigo gerar o outro pwm em outra porta nem a pau. Será que quando esta setado para o clock em PLL ele só funciona com um PWM?

static void setup_clock( void ){  /*Examine Page 33*/  CLKPR = 0x80;	//*Setup CLKPCE to be receptive*/ Decimal = 128  CLKPR = 0x00;	//*No scalar*/ Decimal = 0  //Maximum clock speeds!  //PLLCSR = (1<<PCKE) | (1<<PLLE);  PLLCSR = _BV(PLLE) | _BV( PCKE );  OSCCAL = 0xff;}void setup(){    setup_clock();    pinMode(0, OUTPUT);            // Enable PWM output pin  pinMode(4, OUTPUT);            // Enable PWM output pin  DDRB &= _BV(2); //Sound input  DDRB |= _BV(3) | _BV(4); //Speaker    TCCR1 = _BV(CS10); //Use high speed PCK.  GTCCR = _BV(PWM1B) | _BV(COM1B0);  //Make sure PLLE is already selected.    OCR1B = 127;  }void loop() { }

Compartilhar este post


Link para o post
Compartilhar em outros sites

@classd2008,

 

Olha, pelo datasheet voce pode habilitar um modo compatível com o Attiny15 e com isso pode atingir frequências 3 vezes maiores com 8 bits ou 6 vezes com 7 nits ou 12 vezes com 6 bits.

 

E pode também conseguir nas duas saídas !!! 

 

Mas é meio confusa a explicação de como programar isso. Sugiro ler bem essa parte do datasheet, e verificar se deu certo usando a simulação do Proteus.

 

Infelizmente não posso te ajudar em nada nesse código do Arduíno, pois só entendo Basic e Assember ....

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não vou com a cara do arduíno mas este codigo em c dele eu comentaria +- assim

(só pra constar, nunca tive contato com este mc)

static void setup_clock( void ){/*Examine Page 33*/CLKPR = 0x80;    //bit 7 de CLKPR em 1 e depois em...CLKPR = 0x00;    //...zero//Maximum clock speeds!//PLLCSR = (1<<PCKE) | (1<<PLLE); //baseando nesta informação...PLLCSR = _BV(PLLE) | _BV( PCKE );//faz com que os bits PLLE e PCKE fiquem em 1. Dê uma olhada na função _BV() que provavelmente só seta bitsOSCCAL = 0xff; // provavelmente um valor de calibração}void setup(){setup_clock(); //vai ter que dar uma olhada no funçãopinMode(0, OUTPUT); // Enable PWM output pin (!)pinMode(4, OUTPUT); // Enable PWM output pin (!)DDRB &= _BV(2); //Sound input //baseando no que vi acima faz o bit 3 de DDRB=0 tornando-o entrada - um TRIS do pic ao contrárioDDRB |= _BV(3) | _BV(4); //Speaker //o mesmo com bits 3 e 4 como saídaTCCR1 = _BV(CS10); //Use high speed PCK. //seta o bit CS10 de TCCR1GTCCR = _BV(PWM1B) | _BV(COM1B0); //seta os bits PWM1B e COM1B0 de GTCCR//Make sure PLLE is already selected.OCR1B = 127; //"pra ter certeza que o PLLE está selecionado" }

Não sei se percebeu mas uma lida no d.s. é imprescindível pra tornar o sistema entendível com razoável clareza. Vai ter que quase que literalmente pegar bit a bit com uma pinça, colocar no microscópio, estudá-lo, conhecê-lo e devolver.

 

voce pode fazer rápido ou direito mas nunca os dois ao mesmo tempo

 

abç

Compartilhar este post


Link para o post
Compartilhar em outros sites

Paulo - Isadora

O código em BASCOM ficou assim e funcinou perfeitamente.

O problema é que ainda preciso de mais uma onda igual a essa invertida.

Depois o resto se tornaria mais fácil, pois é só fazer a leitura ADC e colocar no Dute-cicle dos 2 PWMs.

Mas ta valendo de mais a ajuda ai pessoal... pra mim que não entendo nada de AVR, acho que a coisa começou a andar.

$regfile = "attiny85.dat"$crystal = 8000000$hwstack = 32$swstack = 32$framesize = 32Clkpr = 128'Decimal ou 0x80 HexClkpr = 0'Decimal ou 0x00 HexPllcsr = Bits(plle , Pcke )Osccal = 255'Decimal ou 0xff HexConfig Portb.4 = OutputTccr1 = Bits(cs10)Gtccr = Bits(pwm1b , Com1b0)Ocr1b = 127End

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sugiro também usar o PLL interno para multiplicar o clock x4 ou x8 (32 ou 64MHz)

Configure o registrador interno e os fuses CKSEL:

 

post-387879-0-14929500-1432336566.jpg

 

post-387879-0-91213800-1432336715_thumb.

 

post-387879-0-77954200-1432336952_thumb.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@classd2008,

Sim, testei aqui e funcionou direitinho !
 

ATUALIZAÇÃO : havia escrito que não dava para obter a saida simétrica no modo PWM , mas tem sim como, está no próximo post meu, logo abaixo

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isso mesmo Paulo, só agora percebi que tenho que usar um ATTiny diferente, vou comprar o ATtiny461. Uma pergunta um pouco que inusitada, tenho um ATTiny de 14 pinos SMD numa placa aqui alimentado com 15V. Porque isso? Acho que o modelo dele é ATTiny841, pois as marcações estão bem fraquinhas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@classd2008,

 

Arre .... CONSEGUI !!!!

 

Bom, primeiro, tem de trabalhar no modo normal, isto é, NÃO MUDE OS FUSES PARA O MODO DE COMPATIBILIDADE ATTINY15 !!!!

Segundo, não mude os fuses para o modo PLL, isto é, deixe o oscilador ser o RC interno de 8 Mhz.

 

 

Segundo, este é o código que gera 250 Khz, se quiser gerar 125 é só fazer aquela mudança na tabela que você postou.:

$regfile = "attiny85.dat"$crystal = 8000000$hwstack = 32$swstack = 32$framesize = 32Set Pllcsr.plleWaitus 100Reset Pllcsr.lsmWhile Pllcsr.plock = 0 : WendSet Pllcsr.pckeTccr1 = &B0001_0001Gtccr = &B0101_0000Ocr1c = 255Ocr1b = 127                                                 'Duty cycleConfig Portb.4 = OutputConfig Portb.3 = OutputEnd

Mudando o valor de Ocr1b voce faz o PWM variar de acordo,e a sua saida complementar está em Portb.3 ok ?

 

Bom uso !

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Simplesmente show de bola Paulo, agora só falta fazer a leitura ADC para alternar o dute-cicle de 50% + variação na entrada adc até no máximo PWM, pois assim posso conseguir através do microcontrolador até fazer um LIMITER de audio se for o caso. Limitando o PWM onde eu quiser.

Será que consigo uma boa resolução no ADC?

Paulo você tem uma e-mail para eu enviar o esquema elétrico do amplificador que eu estou fazendo? Acho que você vai gostar...

Compartilhar este post


Link para o post
Compartilhar em outros sites

@classd2008,

Opa, eu também quero ver o que você está "inventando" hehehe !

A resolução do ADC é de 10 bits, e na prática é muito difícil conseguirmos usar toda esta resolução, pois um ruido de cerca de 1 milivolt na entrada já afeta a leitura em mais de um bit....

Sobre o Adc, o ideal seria voce fazer um sampling rate de no mínimo uns 44 Khz. Mas veja, com 10 bits conseguirá apenas 15K samples, então teremos de baixar para 8 bits, o que te dará cerca de 60 K samples / segundo. Em tese, isto permitiria uma qualidade muito boa para uma faixa ampla até 30 Khz de frequência de áudio.

Mas se for para buscar a melhor qualidade possível, por exemplo para a voz humana, aí o ideal seria manter os 10 bits, o que permite a maior qualidade possível até 7,5 Khz de frequência de áudio.

Terá de fazer um compromisso com esse processador.

Sobre o seu amplificador, que tal abrir um tópico na área de Eletrônica, para que mais pessoas possam dar suas idéias, e também poder contribuir para o software ? Sempre é bom escutar mais opiniões e também poderá ajudar muito mais pessoas do que ficar uma conversa apenas entre nós dois, ok ?

Este Fórum sempre funcionou desta maneira, difundindo o conhecimento para todos !

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde a todos. Estou procurando uma forma rápida e fácil para fazer um gerador de alta tensão, utilizando um Attiny85 digispark como oscilador. Aparentemente este tópico me parece adequado para perguntar se alguém sabe se é possível e como seria. Acredito que variar uma das saídas pwm entre 50Khz e 150Khz resolveria a questão, porém sou leigo no assunto. Alguém poderia me ajudar? O valor dos componentes certamente precisam sofrer alterações. 

Antecipadamente agradeço.

Proj1.png

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×