Ir ao conteúdo

Posts recomendados

Postado

Pessoal, preciso aumentar a frequência do PWM do Attiny85 para 100khz, achei esse código abaixo que faz varias alterações de Fuse pelo que entendi, e consegue aumentar até 400khz, com isso fica fácil selecionar a frequencia e o Duty cicle, mas fica tudo fixo, não consigo modular o Dute Cicle por exemplo com uma entrada analógica, parece que o código mata outras funcões. Alguem podeira ajudar? já precisaram de fazer isso?

Obrigado.

 

//#include <avr/io.h>
//#include <avr/interrupt.h>


void setup()
{
    PORTB = 0;      //Reset values on port B

    // After setting up the timer counter,
    // set the direction of the ports to output
    DDRB |= (1<<PB1) | (1<<PB0); // Set the direction of PB1 to an output

    // PLLCSR - PLL control and status register:
    // PLL is a clock multiplier - multiplies system     8Mhz by 8 to 64Mhz
    // PLL is enabled when:PLLE bit is enabled,
    // CKSEL fuse is programmed to 0001.  This clock is
    //   switched off in sleep modes!
    PLLCSR |= (1<<PLLE);    // PLL enable

    // Wait until the PLOCK bit is enabled
    //  before allowing the PCK to be enabled
    // WaitForPLOCK();
    // unsigned int i = 0;


    while ((PLLCSR & (1<<PLOCK)) == 0x00)
    {
        // Do nothing until plock bit is set
    }

    PLLCSR |= (1<<PCKE); // Enable asynchronous mode, sets PWM clock source


    TCCR1 =
            (1<<CTC1) |  //enable pwm
            (1<<PWM1A) | // set source to pck
            (1<<(CS10)) | // clear the pin when match with ocr1x
            (1<<COM1A1);
    GTCCR =   (1<<PWM1B) | (1<<COM1B1);


    // Set PWM TOP value - counter will count and reset
    //  after reaching this value
    //          OCR1C
    // 400Khz   159     
    // 450khz   141
    // 500khz   127
    OCR1C = 159;


    //enable Timer1 OVF interrupt
    TIMSK = (1<<OCIE1A) | (1<<TOIE1);   

    sei();

    //This should set the duty cycle to about 75%
    OCR1A = 120;
}

void loop() {
}

 

  • Membro VIP
Postado

Nem sabia que tinha arduino com attiny e sim já modulei pwm com variável analógica mas com outro mc.

Há séculos não vejo o datasheet deste mc mas por insight...

1 hora atrás, Claudiocfv disse:

//This should set the duty cycle to about 75%

OCR1A = 120;

... o registro OCR1A é o de controle dele

 

Pior que acabo de pesquisar pra você e num é que tem arduino com ele mesmo? E o pior (ou melhor) já semimastigado algo do pwm

tinydactwox12.gif

 

http://www.technoblogy.com/show?1NGL

 

Agora se sua inquietação for mesmo o lance da frequência, não sei dizer se este mc tem competência pra freq bem alta. Melhor mesmo ver seu d.sheet...

abç

 

Postado
19 horas atrás, Isadora Ferraz disse:

Nem sabia que tinha arduino com attiny e sim já modulei pwm com variável analógica mas com outro mc.

Há séculos não vejo o datasheet deste mc mas por insight...

... o registro OCR1A é o de controle dele

 

Pior que acabo de pesquisar pra você e num é que tem arduino com ele mesmo? E o pior (ou melhor) já semimastigado algo do pwm

tinydactwox12.gif

 

http://www.technoblogy.com/show?1NGL

 

Agora se sua inquietação for mesmo o lance da frequência, não sei dizer se este mc tem competência pra freq bem alta. Melhor mesmo ver seu d.sheet...

abç

 

Então, eu consigo alterar o OCR1A dentro do código e variar a saida normalmente com 400khz, mas não consigo modular ele por outra variável tipo uma int que responde a uma entrada analógica, parece que esse codigo que mexe com os fuses atrapalha alguma outra coisa.

Eu consegui outro código que mexe só nos Timers, e com esse sim o resto tudo funciona, mas ele só chega a 32khz. Segue abaixo para analise.

PS; Tentei desvendar o datasheet, ele explica muita coisa, mas não tem exemplos de códigos, está acima da minha sabedoria em programação.

void setup() 
{
  pinMode(1, OUTPUT);
  TCCR0B = TCCR0B & 0b11111000 | 0b001 ;
  
  
}

void loop()
{
  int val = analogRead(1);
  val = map(val, 0, 1023, 0, 255);
  analogWrite(1, val);
  
  
}

 

  • Membro VIP
Postado
1 hora atrás, Claudiocfv disse:

modular ele por outra variável tipo uma int que corresponde a uma entrada analógica,

Isso é relativamente fácil. Digamos que sua entrada analógica é de 10 bits (1023) e o d.s. te instrui que o registro em questão é 8 bits ou até meesmo sua função mastigada analogWrite() - que provavelmente  altera o OCR1A pra você -  quer parâmetro 8 bits...

analogWrite(1,analogRead(1)/4);

 

não sei pra que serve a map()

Postado
Em 17/03/2020 às 10:59, Isadora Ferraz disse:

map

Uma função que converte um valor de uma escala linear para outra .

 

É uma regra de três para programadores que não sabem matemática kkkkk !

 

Paulo

Postado
Em 17/03/2020 às 10:59, Isadora Ferraz disse:

Isso é relativamente fácil. Digamos que sua entrada analógica é de 10 bits (1023) e o d.s. te instrui que o registro em questão é 8 bits ou até meesmo sua função mastigada analogWrite() - que provavelmente  altera o OCR1A pra você -  quer parâmetro 8 bits...

analogWrite(1,analogRead(1)/4);

 

não sei pra que serve a map()

Aí que tá, quando roda o codigo que mexe no OCR1A, o analogWrite para de funcionar.

 

Postado
11 minutos atrás, Isadora Ferraz disse:

Pois não mexa nele pow. Deixe o analogwrite() se virar...

Escrevi errado, quis dizer quando roda aquele primeiro codigo que define o OCR1C = 159; pra chegar nos 400khz, mesmo se não definir o OCR1A, o analogwrite() não vai, ficaria assim:

//#include <avr/io.h>
//#include <avr/interrupt.h>


void setup()
{
    PORTB = 0;      //Reset values on port B

    // After setting up the timer counter,
    // set the direction of the ports to output
    DDRB |= (1<<PB1) | (1<<PB0); // Set the direction of PB1 to an output

    // PLLCSR - PLL control and status register:
    // PLL is a clock multiplier - multiplies system     8Mhz by 8 to 64Mhz
    // PLL is enabled when:PLLE bit is enabled,
    // CKSEL fuse is programmed to 0001.  This clock is
    //   switched off in sleep modes!
    PLLCSR |= (1<<PLLE);    // PLL enable

    // Wait until the PLOCK bit is enabled
    //  before allowing the PCK to be enabled
    // WaitForPLOCK();
    // unsigned int i = 0;


    while ((PLLCSR & (1<<PLOCK)) == 0x00)
    {
        // Do nothing until plock bit is set
    }

    PLLCSR |= (1<<PCKE); // Enable asynchronous mode, sets PWM clock source


    TCCR1 =
            (1<<CTC1) |  //enable pwm
            (1<<PWM1A) | // set source to pck
            (1<<(CS10)) | // clear the pin when match with ocr1x
            (1<<COM1A1);
    GTCCR =   (1<<PWM1B) | (1<<COM1B1);


    // Set PWM TOP value - counter will count and reset
    //  after reaching this value
    //          OCR1C
    // 400Khz   159     
    // 450khz   141
    // 500khz   127
    OCR1C = 159;


    //enable Timer1 OVF interrupt
    TIMSK = (1<<OCIE1A) | (1<<TOIE1);   

    sei();

    
}

void loop() {

analogWrite(1,analogRead(1)/4);// como você sugeriu
}

 

  • Membro VIP
Postado

Então não mexa com quem tá queto. Deixa os registros em paz e fique somente com o 'alto nível' uai. Geralmente não precisa mexer na frequencia

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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 comunidades 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

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!