Ir ao conteúdo
  • Cadastre-se

Gerar frequência de 24khz com 12f629 sem delay


Posts recomendados

Pessoal, preciso gerar uma frequência de 24khz de saída em um pino do 12f629, não quero usar delay, pois vou usar botão para mudar funções, nesse caso o delay mata o desempenho do código. Precisa ser esse pic pelo tamanho, pensei na possibilidade de fazer isso usando tirmer, mas não consegui, preciso da juda dos amigos do fórum.

 

Eu uso o compilador CCS Compiler.

 

Ronildo.

Link para o comentário
Compartilhar em outros sites

O Código que eu fiz é esse abaixo. Ele funciona legal, o "x" é incrementado a cada estouro do timer 0, porém como estou usando o oscilador interno por causa de espaço da minha pci. A variável "Y" é somente para ajuste de precisão da frequência.

    A frequência máxima que ele gera  1953HZ, creio que não posso colocar o osc interno maior que 4MHZ.

 

 

 

 

#include <12F629.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOCPD                    //No EE protection
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BANDGAP_HIGH          
#use delay(clock=4000000)
int x, y;

#int_RTCC
void  RTCC_isr(void)
{
x++;
}



void main()
{

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   setup_comparator(NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   // TODO: USER CODE!!

while (true)
{

if (x>=1)
{
y++;
x=0;
}

if(y>=1)
{
output_toggle(pin_a1);
y=0;
}
}
}

Link para o comentário
Compartilhar em outros sites

 Acho que usando um Timer,ja que usando Looping ele não quer,não da.

Me corrijam.

 

A sim cara, realmente você tem razão =D ... com o looping também acho que não da... mas eu perguntei exatamente porque estava pensando no timer hehe.... não tinha imaginado que você falava que não da por que ele tentava fazer com o loping...

 

então @Cristiano Tadeu ..... você sabe como usar o timer?

 

abrçs....

Link para o comentário
Compartilhar em outros sites

Então pessoal, sobre a última pergunta, eu estou usando o timer(timer 0), e se não me engano. eu não posso usar o oscilador interno com uma frequência maior que 4mhz, eu fiz um programa parecido com o pic 16f628 usando o pwm dele, mas nesse caso preciso usar esse pic, que não tem essa função, se alguém tiver uma ideia.

Link para o comentário
Compartilhar em outros sites

Então cara, o oscilador interno é de 4MHz e não da pra alterar, a precisão dele não é a melhor mas se não for crítica sua utilização não fara diferença pra você.

 

A frequência do clock sendo de 4MHz, a frequência de máquina sera 1MHz, e o preescaler mínimo é 1:2, então seu tmr0 sera incrementado a uma frequência de 500KHz, mais que suficiente pra você fazer o que for necessário, basta apenas fazer a lógica correta que da pra fazer sossegado seu gerador de frequência.....

 

floww

Link para o comentário
Compartilhar em outros sites

Vai ficar possível, mas muito restrito.

Usando o timer0 para gerar uma onda quadrada de 24kHz. Significa que vai precisar que o TIMER0 transborde a cada meio período (meio em '1' e meio em '0'). O tempo de meio período será:

Ton = Toff = 1 / (24.000 x 2) = 20us (u = micro e s é a unidade de segundo).

A frequência interna do PIC é de 4MHz, que divididos por 4 dá um clock de 1MHz. Então o seu TIMER0 TEM que gerar uma interrupção a cada 20us para que você faça o tratamento da interrupção.

Seu tratamento seria:

Reseta o registro T0IF

Atualiza o valor do TIMER0

Inverte o pino de saída

Sai da interrupção.

Isso teria que ser feito a cada 20us, ou com no máximo 20 instruções, o que deveria ser com instruções em assembler. Além disso, não sobraria muito tempo para as outras coisas que você precisaria fazer.

 

Parece que o pic que você usa não tem o TIMER2 para fazer um PWM. Nem sei se daria.

Mas talvez dê para usar o comparador interno do pic no modo 1 (CM2 = CM1 = 0 e CM0 = 1). Figura 6.2 do manual.

Com o comparador, três resistores e um capacitor você faz um oscilador com histerese, que fica oscilando SEM GASTAR MAIS NENHUMA INSTRUÇÃO PARA ISSO. Você fica com o pic livre para fazer as outras coisas.

Estude o comparador do pic e pesquise sobre comparador com histerese.

MOR_AL

Link para o comentário
Compartilhar em outros sites

No caso do comparador amigo, dei uma olhada, e esse pic pelo que vi não me dá essa opção, quanto à sua explicação caro mister, entendi o que quer dizer, porém, se com clock de 4mhz, a frequência fica de 1mhz,até aí beleza, só que nessas condições o overflow do timer fica em 256us, me corrija se estiver errado. Se eu estiver errado, por favor me dá uma linha de raciocínio que eu sigo, obrigado

Link para o comentário
Compartilhar em outros sites

Você acha isso porque deve pensar que não pra alterar o timer0, mas ele é um REGISTRADOR, logo da pra ler, escrever, fazer qualquer coisa nele, então você pode escrever o valor 236 nele para inicializar e toda vez que ele estourar escrever 236 também, ai como ele estoura na transição de 255 pra 0 ele vai demorar 20 us pra estourar.....

 

mas você percebe que o que o amigo @MOR disse é verdade, é uma operação bem crítica, você tem que fazer o código mais enxuto possível na rotina de interrupção, se não você não vai conseguir realizar nenhuma outra coisa mais, pois a todo momento ele vai ficar na rotina de interrupção

 

terá que ser mais ou menos assim

void interrupt(){ pino_da_frequência=!pino_da_frequência; intcon.T0IF=0; tmr0=236;}

teria que ser apenas isso, e já vai ficar muito apertado pras outras coisas, pois você vai ter 20 instruções pra realizar entre cada estouro, e só na rotina de interrupção vai umas 10 instruções, ou seja, vai ser bem apertado mesmo, você vai ter que dominar muito nesse código hahaha

 

abrçs

Link para o comentário
Compartilhar em outros sites

No caso do comparador amigo, dei uma olhada, e esse pic pelo que vi não me dá essa opção,

 

Porque não te dá essa opção? Você viu a figura que lhe informei? As duas entradas e a saída do comparador ficam disponíveis nos pinos. Me explique com mais detalhes, pois não acompanhei o seu raciocínio.

 

quanto à sua explicação caro mister, entendi o que quer dizer, porém, se com clock de 4mhz, a frequência fica de 1mhz,até aí beleza, só que nessas condições o overflow do timer fica em 256us, me corrija se estiver errado. Se eu estiver errado, por favor me dá uma linha de raciocínio que eu sigo, obrigado

 

A cada estouro do TIMER0, você programa o TIMER0 para 236, aí, depois de 20us, ele estoura a contagem em 256 outra vez e o ciclo se repete.

Mas mesmo assim não vai dar para fazer mais nada, pois você terá um estouro do TIMER0 a cada 20 instruções EM ASSEMBLY. Isso sem contar com o procedimento que o pic faz para salvar o PC (program counter - contador de programa que aponta para a última instrução antes de ter desviado para o endereço da interrupção) e desviar para o endereço da interrupção. Depois ainda tem o procedimento que o pic faz para recuperar o valor do PC e desviar para a instrução seguinte, quando foi gerada a interrupção.

Ainda tem o detalhe que o compilador pode estar salvando o stack e o registro W. Aliás esqueci de colocar na sequência do tratamento da interrupção. Tem que salvar em registro e depois recuperar. Mesmo em assembly não acho que vai dar tempo.

Acho que a solução, sem ter que colocar mais CI no projeto seria usar o comparador mesmo.

Bons projetos.

MOR_AL

Link para o comentário
Compartilhar em outros sites

 Mas mesmo assim não vai dar para fazer mais nada, pois você terá um estouro do TIMER0 a cada 20 instruções EM ASSEMBLY. Isso sem contar com o procedimento que o pic faz para salvar o PC (program counter - contador de programa que aponta para a última instrução antes de ter desviado para o endereço da interrupção) e desviar para o endereço da interrupção. Depois ainda tem o procedimento que o pic faz para recuperar o valor do PC e desviar para a instrução seguinte, quando foi gerada a interrupção.

Ainda tem o detalhe que o compilador pode estar salvando o stack e o registro W. Aliás esqueci de colocar na sequência do tratamento da interrupção. Tem que salvar em registro e depois recuperar. Mesmo em assembly não acho que vai dar tempo.

Acho que a solução, sem ter que colocar mais CI no projeto seria usar o comparador mesmo.

Bons projetos.

MOR_AL

 

 

 

ÉÉhhhhh cara.... o buraco é mais em baixo mesmo hahahahaha, parece que é mesmo inviável fazer isso por interrupção =S

 

flow

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!