Utilizando o TIMER0 do PIC
O TIMER0 normalmente é utilizado em projetos para fazer a base de tempo, ou seja, o relógio do projeto, como contar tempo para repetir ou considerar um evento.O TIMER0 utiliza normalmente três registros especiais (SFR), dependendo do PIC a ser utilizado. Mostrarei como utilizar o TIMER0 do PIC16F877A.
PIC16F877A
O temporizador/Contador TIMER0 possui as seguintes características:• temporizador/contador de 8 bits;
• leitura e gravação;
• software prescaler de 8 bits programável;
• Relógio interno ou externo selecionavel;
• Interrupção no estouro de FFh para 00h;
• Borda de seleção para relógio externo;
Registros associados ao TIMER0:
MODO CONTADOR:
O TIMER0 funciona como contador, quando você usa como oscilador os pulsos externos aplicado no pino RA4/T0CKIN.
Você deve configurar o seguinte registro:
T0CS - Define a fonte de clock do TIMER0:
1 - Externa (PINO RA4/T0CKIN) - Modo contador;
0 - Interna (Cristal de quartzo) - Modo temporizador;
T0SE - Seleção da borda de transição do pino RA4/T0CKIN
1 - transição nivel alto-baixo (transição negativa);
0 - transição nivel baixo-alto (transição positiva);
PSA - Habilitação do prescaler (no modo CONTADOR é comum desabilitar);
1 - Desabilitado;
0 - Habilitado;
0 - Habilitado;
PS2, PS1, PS0 - Seleção do prescaler( somente no modo temporizador);
bits / TMR0 rate
000 1:2
001 1:4
010 1:8
011 1:16
100 1:32
101 1:64
110 1:128
111 1:256
void main() { TRISB=0; OPTION_REG=0b10111000; //modo contador TMR0=0; //Inicializa o registro TMR0 com o valor 0. while(1) { if(INTCON.TMR0IF) { INTCON.TMR0IF=0; //limpa a flag TMR0 = 0; portb=~portb; //quando acontecer o overflow(a cada 256 pulsos) interver as saidas } delay_ms(10); } }
O registro TMR0 é o registro que armazena o estado inicial da contagem. Possui 8 bits, por isso conta de 0 a 255. Quando acontece o overflow ele retorna a contagem inicial 0. O bit do overflow é o INTCON.TMR0IF e deve ser limpo por software.
MODO TEMPORIZADOR:
O temporizador do TIMER0 funciona quando você usa o oscilador interno do PIC ou o cristal de quartzo externo.
Você deve configurar os seguintes bits do registro OPTION_REG:
T0CS - Define a fonte de clock do TIMER0:
1 - Externa (PINO RA4/T0CKIN) - Modo contador;
0 - Interna (Cristal de quartzo) - Modo temporizador;
PSA - Habilitação do prescaler (no modo CONTADOR é comum desabilitar);
1 - Desabilitado;
0 - Habilitado;
0 - Habilitado;
PS2, PS1, PS0 - Seleção do prescaler;
bits / TMR0 rate
000 1:2
001 1:4
010 1:8
011 1:16
100 1:32
101 1:64
110 1:128
111 1:256
Você deve estar perguntando: O que é prescaler?
Prescaler é o divisor de frequência do clock do TIMER0. É usado no modo temporizador para poder obter tempos maiores.
A fórmula do tempo para o overflow é a seguinte:
t = ciclo de máquina * prescaler * contagem ( 256 - TMR0 );
ciclo de máquina = 4 / Fosc;
Fosc é a freqência do clock do cristal oscilador.
EXEMPLO:
O clock de um PIC é de 4MHz, utlizado o prescaler de 1:256 e contagem de 0 a 256, qual será o tempo?
ciclo de máquina = 4/4 = 1us.
t = 1 * 256 * 256;
t = 65536us ou 65,536ms
para ter tempos ainda maiores, como alguns segundos,um dos meios de se conseguir é utilizando a interrupção.
Veja um exemplo: utilizando clock 4Mhz e prescaler de 1:4.
unsigned contagem; void interrupt() { contagem++; //para cada interrpção do TMR0 incrementa a variável contagem TMR0 = 0; INTCON.TMR0IF = 0; //limpa o overflow. } void main() { INTCON.GIE = 1; //habilita interrupção global; INTCON.PEIE = 1; //habilita interrupção dos perifericos; INTCON.TMR0IE = 1; //habilita interrupção do TMR0; TMR0 = 0; // TIMER0 inicia com o valor 0; OPTION_REG = 0b10000001; // Modo Temporizador, prescaler 1:4; //tempo =1us * 4 * 256 = 1ms ... while (1) { if(contagem == 1000) //quando o contagem = 1000, tempo = 1000 * 1ms = 1s; { portb.RB0 = ~portb.RB0; //inverte o estado do pino rb0 contagem = 0; //reseta a variavel contagem } } }
Boa tarde.
ResponderExcluirNo texto você coloca t=65,536ms e no código 4,096ms
É uma divisão por 16 que eu não consegui entender.
Outra coisa, preciso contar um segundo com um cristal de 20MHz, pode me ajudar na conta mais precisa /
Muito obrigado pelo seu comentário! É o primeiro do blog!!!
ExcluirVocê tem razão,acabei utilizando o prescaler de 1:256 sendo que na verdade é de 1:16, me desculpe pelo erro e já corrigi.
No seu caso:
ciclo de máquina = 4 / 20MHZ = 0,2 us.
tempo = 0,2 * 4 * 125 = 100us.
utilizando prescaler de 1:4 e TMR0=131(256 - 125) => irá contar de 131 a 256.
Para cada interrupção gerada, você pode incrementar uma variável (x) e quando essa variável chegar no valor de 10000 executar alguma coisa.
No final de tudo: 10000 * 100us = 1segundo.
Espero que possa ter entendido! Muito obrigado pelo seu comentário!!
Utilizando O Timer0 Do Pic - Microcontrolandos >>>>> Download Now
Excluir>>>>> Download Full
Utilizando O Timer0 Do Pic - Microcontrolandos >>>>> Download LINK
>>>>> Download Now
Utilizando O Timer0 Do Pic - Microcontrolandos >>>>> Download Full
>>>>> Download LINK ij
Boa tarde,
ResponderExcluirPrimeiramente gostaria de lhe dar os parabéns pela explicação, pesquisando, não encontrei nada nem mesmo similar. Muito bom!!!
Infelizmente não estou entendendo muito bem a configuração do "optionreg" já li e reli o datasheet do pic16f877a mas ainda tenho duvidas sobre como delarar as variáveis do pre escale.
Estou tentando fazer um led piscar com a funçar timer0, você poderia me auxiliar?
Obrigado :)
ResponderExcluirCada bit do registro OPTION_REG tem uma função. os bits 2, 1 e 0 possui a função de configurar o prescaler. Então, caso OPTION_REG = 0B10000111, como os ultimos bits são 111, o prescaler será 1:256.
para poder fazer um led piscar, você deve configurar TIMER0 no modo temporizador(bit 5). Atraves da formula dito acima, você calcula o tempo.
Faz de conta que utilize um cristal de 4Mhz(ciclo maquina = 1us),precaler 1:128, e carregue o TMR0 como o valor 100; O perido será: 1 * 128 * (256 - 100) = 19968us = 20ms. O led piscara num intervalo de 20ms.
O codigo ficaria assim:
void main(){
TMR0 = 100;
OPTION_REG = 0B10000110;//como os ultimos bits sao 110, prescaler e 1:128.
TRISB.F0 = 0;
while(1){
if(INTCON.TMR0IF==1){//flag de sinalizacao quando TMR0 e maior q 255
PORTB.F0 = ~PORTB.F0;//pisca o led
TMR0 = 100;//necessita carregar o TMR0, senao volta pra 0
INTCON.TMR0IF=0;//limpa a flag
}
}
}
Nossa, que ágil a resposta hehehe...^^
ExcluirCom um exemplo tudo começa ficar mais claro, agora consegui associar a função de cada bit do "OPTION_REG". Li o Cap. 2 e 5 do datasheet mas faltava uma dica para unir a teoria com a pratica.
A atividade que estou desenvolvendo pede que eu configure a fonte de clock com configuração do pre escaler 1:256 e que siga o seguinte algoritmo:
configurar fonte de clock
conf. pre escaler 1:256
enquanto timer<15625 espere
timer = 0
acended lad
enquando timer<15625, espere
timer = 0
apaga led
O meu código encontra-se assim:
void main() {
TRISA=0b11111110; //Porta A têm o pino A0 configurado como "saída"
OPTION_REG=0b10000111;
for(;;)
{
while (TMR0<255) {
TMR0=0;
PORTA=0b00000000;} //Pino A0 libera "saída alta" (5V)
while (TMR0<255) {
TMR0=0;
PORTA=0b00000001;} //Pino A0 libera "saída alta" (5V)
}
}
Mas não funciona por nada hehehe.... alguma luz?
Eu faria assim:
Excluirvoid main() {
TRISA = 0b11111110;
OPTION_REG = 0b10000111;
for(;;)
{
while (TMR0<255);
TMR0 = 0;
PORTA = 1;
while (TMR0<255);
TMR0 = 0;
PORTA = 0;
}
}
No seu codigo, dentro do while, vc carregou TMR0=0, como o TMR0=0 sera sempre menor q 255, nunca iria sair do loop.
Entendi, eu havia criado uma função que nunca sairia do loop T_T... Farei apenas mais um questionamento, o que o algoritmo do problema que estou tentando resolver quer dizer com "... timer<15625...", pois, qualquer valor que entro, se maior do que 255, o programa não funciona como esperado.
ExcluirO módulo timer0 na verdade conta ate 255, pois possui um registro contador(TMR0) de 8 bits. Para o timer1, possui um registro de 16 bits(TMR1H/TMR1L) e pode contar até 65536.
ExcluirMuito obrigado pelas explicações, apesar de conceitos básicos, foram essenciais para clarear minha vida =)...
ExcluirEstou com uma duvida
ResponderExcluirEstou tentando acender 4 leds um de cada vez com intervalo de 2segundos utilizando o pic 18f4520, porem ele só acende o primeiro?
Oque estaria errado?
void main() {
int segundos = 0;
trisb=0;
portb=0;
T0CON=0b10000110;
TMR0L=0XEE;
TMR0H=0X85;
INTCON.TMR0IF = 0;
while(1){
if(segundos == 0 && INTCON.TMR0IF == 1){
//porta = 0;
portb.f0 = 1;
TMR0L=0XEE;
TMR0H=0X85;
INTCON.TMR0IF = 0;
segundos++;
}else if(segundos == 1 && INTCON.TMR0IF == 1){
portb.f0 = 0;
portb.f1 = 1;
TMR0L=0XEE;
TMR0H=0X85;
INTCON.TMR0IF = 0;
segundos++;
}else if(segundos == 2 && INTCON.TMR0IF == 1){
portb = 0;
portb.f2 = 1;
TMR0L=0XEE;
TMR0H=0X85;
INTCON.TMR0IF = 0;
segundos++;
}else if(segundos == 3 && INTCON.TMR0IF == 1){
portb = 0;
portb.f3 = 1;
TMR0L=0XEE;
TMR0H=0X85;
INTCON.TMR0IF = 0;
segundos++;
}else if(segundos == 4 && INTCON.TMR0IF == 1){
segundos = 0;
}else{
portb = 0;
TMR0L=0XEE;
TMR0H=0X85;
INTCON.TMR0IF = 0;
segundos++;
}
}
}
Na linha:
ExcluirINTCON.TMR0IF = 0;
adicione:
INTCON.TMR0IE = 0;
Olá!
ResponderExcluirVeja que no ultimo "else" voce incrementa a variavel segundos. como o intervalo do timer é de 2 segundos(eu acho) durante esse tempo, o pic ira executar esse "else" milhares de vezes, ou seja, a variavel incrementara milhares de vezes, e nunca sera 1,2,3 ou 4.
simplifiquei seu codigo:
void main() {
int segundos = 0;
trisb=0;
portb=0;
T0CON=0b10000110;
TMR0L=0XEE;
TMR0H=0X85;
INTCON.TMR0IF = 0;
while(1){
if(INTCON.TMR0IF==1)
{
PORTB = (1 << segundos++);
if(segundos==4) segundos=0;
TMR0L=0XEE;
TMR0H=0X85;
INTCON.TMR0IF = 0;
}
}
}
Olá, minha dúvida a seguinte:
ResponderExcluirPreciso de uma contagem de 0 a 20ms, ou seja, 0 a 20000us.
Meu cristal é de 4MHz. Minha aplicação é com USB, então preciso de 48MHz. Consigo isso modificando o prescaler do clock. Mas esse prescaler é o mesmo do timer0?
Outra coisa, o ciclo de máquina nesse caso seria:
4/48=0.08333us
O tempo de overflow é:
T=ciclo de maq*prescaler*contagem
20000=0.08333us*128*contagem
Ta certo isso?
Olá!
ExcluirO prescaler do PLL e do timer0 NAO é o mesmo.
Vc teria q configurar o prescaler PLL para 1:1 e ativar o PLL.
Depois vc configura o prescaler do timer0.
A conta esta certinho!
Olá Tiago, obrigado pela rápida resposta!
ExcluirExiste algum comando no MikroC (sou novato) para que eu possa pegar o valor atual de um timer? Quero dizer, eu quero fazer uma interrupção no timer e pegar o valor da contagem na hora dessa interrupção. No CCS existe o "get_timer0()", existe algo parecido no MikroC?
Recomendo que você leia o datasheet do PIC q vc está utilizando.
ExcluirNa verdade não existe nenhum comando, você tem q pegar o valor de registro.
Provavelmente, vc esta utilizando um timer de 16bits, entao voce tera q pegar o valor do registro TMR0H(8bits) e TMR0L(8bits);
Exemplo:
int valorDoTimer; //declara uma varivel do tipo int(16 bits)
valorDoTimer = (TMR0H<<8) + TMR0L;//desloca 8 bits do TMR0H para esquerda e soma com TMR0L
cara para fazer um programa que tenha um botão com duas funções por exemplo: se eu só o aperto ele faz alguma coisa tipo acende um led mas se eu o aperto e segura por meio segundo ele faz outra coisa. Como eu faço isso?? é com timer??
ResponderExcluirNesse caso, voce pode utilizar delay. Veja um exemplo:
Excluirchar funcao = 0;
void main()
{
TRISB = 255;
TRISC = 0;
while(1)
{
funcao = 0;
if(PORTB.F0==1)//botao pressionado
{
funcao = 1;
delay_ms(500);
while(PORTB.F0)// a cada 500ms, uma nova funcao ao botao
{
funcao++;
delay_ms(500);
}
switch(funcao)//define uma acao para a funcao
{
case 1: PORTC = 1; break;
case 2: PORTC = 2; break;
case 3: PORTC = 4; break;
default: PORTC = 0; break;
}
}
}
}
vlw cara
Excluirobrigado, me ajudou bastante, gosto muito do seu blog
Olá Boa tarde!
ResponderExcluirEncontrei este blog e achei-o muito bom, sendo em C e eu que estou a dar os passos em Mikrobasic.
Estou a tentar fazer um contador de eventos para contar nº de voltas de uma base de uma paletelizadora e depois desenvolver todo o programa.
parabéns.
cump.
Jorge
Muito obrigado! Você me ajudou em um antigo problema!
ResponderExcluirPrimeiro queria dizer que essa página do seu blog é muito legal, li todos os posts e vc explica muito bem.
ResponderExcluirMinha duvida com timer é a seguinte.
Vejo que todo mundo faz um timer que faz alguma coisa alternada, ou seja, com uma base de tempo só. Ex: No seu programa a cada estouro do timer muda o estado de uma saida =~, ou seja, se o timer tiver estouro de 20ms, a cada 20ms a saida estará em nivel 1 e passados 20ms ela vai para nivel 0, assim se visualizarmos essa saida em um osciloscópio teremos um formato de onda quadrada e simétrica. Isso eu consegui, o meu problema é que eu quero uma interrupção assimetrica.
Por exemplo, quero fazer um programa que fique 2ms em nivel 1 e 18ms em nivel 0, mas queria fazer isso através de uma variável e proporcional, quando um subir o outro desce, assim se o nivel alto se manter por 5ms o baixo se mantém por 15ms.
Existe uma maneira de fazer isso?
Outra coisa que percebi é que quando uso timer o delay_ms não funciona.
Voce pode faz o seguinte:
ResponderExcluirDefine o estouro do timer para 1ms e...
char i = 0, state = 0, var = 3;
//1ms
void interrupt()
{
if (TMR0IF_bit)
{
TMR0IF_bit = 0;
TMR0L = 0x05;
i++;
if(i == (2 + var) && state == 0) //Depois de 2ms + var
{
PORTB.B0 = 0;
i = 0;
state = 1;
}
else if(i == (18 - var) && state == 1) //Depois de 18ms + var
{
PORTB.B0 = 1;
i = 0;
state = 0;
}
}
}
Obrigado por responder, testei esse código mas não funcionou.
ResponderExcluirVocê consegue fazer um timer que conte um estou a cada 2us com um oscilador de 8Mhz, no resto eu me viro, a minha maior dificuldade é o timer pois nunca trabalhei com timer antes.
Obrigado.
void Interrupt()
Excluir{
if (TMR0IF_bit)
{
TMR0IF_bit = 0;
TMR0 = 251;
//Seu código
}
void InitTimer0()
{
OPTION_REG = 0x88; //Prescaler 1:1
TMR0 = 251;
INTCON = 0xA0;
}
Obrigado mais uma vez por responder, mas está dando erro no TMR0 q eu depois declarei como variavel int, depois fica dando erro no InitTimer0.
ResponderExcluirEste código devo colocar acima do void main() ?
Estou usando o 18F4520
ResponderExcluirvoid Interrupt()
Excluir{
if (TMR0IF_bit)
{
TMR0IF_bit = 0;
TMR0L = 0xFB;
//Seu código
}
}
void InitTimer0()
{
T0CON = 0xC8;
TMR0L = 0xFB;
GIE_bit = 1;
TMR0IE_bit = 1;
}
void main()
{
InitTimer0();
//Seu código
}
Opa Tiago, pode me dar uma força?
ResponderExcluirEstou usando um Pic 12F675
O programa que estou tentando criar funciona assim:
Estou usando GP0 como entrada e GP2 como saida.
Funciona assim:
A saida GP2 fica em nivel 1.
No momento que eu mudo o estado da entrada "GP0" atraves de um botão, depois de 5 minutos a saida vai a 0 e permanece assim por 5s e volta para "1".
Até ai tudo bem, funciona, porém se eu antes dos 5 minutos deixar de pressionar o botão, não era mais pra acionar a saída, mas não é isso que acontece, mesmo assim a saída vai para "0".
Pode me ajudar?
vc tem o programa q vc esta fazendo.
ExcluirEu nao entendi muito, se puder passar mais detalhes.
Bom dia Tiago, obrigado pela atenção.
ExcluirSegue o programa.
void main() {
ansel = 0;
cmcon = 7;
trisio = 0x01;
gpio = 0;
while(1){
if (GP0_bit == 0){
GP2_bit = 0;
}
else{
delay_ms (300000);
GP2_bit = 1;
delay_ms (5000);
GP2_bit = 0;
}
}
}
Como sou novo no assunto, ainda não sei trabalhar com os timers e interrupções, meus programas são todos do nível acima, mas tô praticando, e te agradeço por perder tempo comigo. A lógica do programa tá invertida em relação ao que eu escrevi ontem, mas é só isso.
Ah, esqueci,
ExcluirO problema que não consigo resolver é: se eu pressiono o botão(GP0_bit) e solto ele não deveria acionar a saída (GP2_bit), mas ele entra no looping de tempo, ai já era. Porque se eu solto o botão, antes dos 5 minutos, ele teria que interromper a contagem do tempo e zerar a contagem.
void main()
Excluir{
unsigned i=0;
ansel = 0;
cmcon = 7;
trisio = 0x01;
gpio = 0;
Label1:
while(1)
{
if (GP0_bit == 0)
{
GP2_bit = 0;
}
else
{
while(GP0_bit && i < 30000)
{
delay_ms(10);
i++;
}
if(!GP0_Bit)
{
i=0;
GP2_Bit = 0;
goto Label1;
}
GP2_bit = 1;
delay_ms(5000);
GP2_Bit = 0;
i=0;
}
}
}
Thiago o que significa este Label 1 e o Goto Label?
ExcluirMuito obrigado.
A instruçao goto significa “ir para“. ela direciona o contador de programa do mcu para um endereço, no caso, para o label1, que é o inicio do “while“.
ExcluirObrigado pela resposta!
ExcluirAnderson, você quer que a saida permaneça em nivel 1 durante o tempo que o botão está pressionado ou vc dá um toque no botão e ele fica em nivel 1 por 5s e depois volta pra 0?
ResponderExcluirVi no seu programa que vc colocou um delay de 300.000ms, isso é igual a 300s. Assim qdo entrar no o programa vai manter o ultimo estado, que no caso é 0, por 300 segundos.
Me diga o que extamente vc quer fazer que acredito que posso te ajudar.
Se vc quiser mudar o status do que vc está fazendo, antes do tempo que vc está querendo programar, vc não deve usar delay, vc deve usar uma variável que vai contar um numero X e ela será o seu flag, assim vc pode interromper e alterar o status de alguma saída antes do tempo do delay.
Acontece que o delay em alguns casos não é interessante pois ele trava o programa o resto do código até que o tempo daquela linha onde está o delay estoure.
Ex.
while(1){
PORTB.RB1 = 1; //A saida RB1 irá pra nivel lógico 1
delay_ms(1000); //RB1 permanecerá assim por 1s até que o microcontrolador leia a próxima linha
PORTB.RB1 = 0; //Esta linha altera o estado para nivel 0
delay_ms(20000); //A leitura do código ficará parada aqui até que os 20s desse delay estoure, só depois ele passará pra linha abaixo.
PORTB.RB2 = 1;
}
Na verdade se a entrada for pra 1(botão pressionado), começa a contar 300s pra acionar a saida, porem se eu soltar o botão a saida deveria permanecer no mesmo estado.
ResponderExcluirOlá! parabéns pelo tutorial. Só tenho uma dúvida. Se eu quiser usar um tempo de overflow de 1000us e um cristal de 4Mhz, qual o prescaler indicado? Pois estou tentando fazer aqui e sempre dá um tempo enorme de contagem.
ResponderExcluirOlá! Obrigado!
ExcluirVocê pode utilizar um prescaler 1:4 e TMR0 = 6;
4 / 4MHz = 1us
1us * 4 * (256 - 6) = 1000us
Obrigado. O problema que estou tendo é que quando mudo o prescaler fica errado. Por exemplo, 4mhz, prescaler 1:8 e overflow de 1000us. 1us*8*(256 - 131) = 1000us com TMR0 = 131, mas quando coloco pra rodar o tempo não bate.
ExcluirVoce está fazendo assim? Lembre-se de recarregar o TMR0 sempre que houver um overflow. Se o TMR0 for recarregado com 0, não há necessidade de inseri-lo no código.
Excluirvoid Interrupt()
{
//seu código
TMR0 = 131;
TMR0IF_Bit = 0;
}
void Main()
{
OPTION_REG = 0b10000010;
TMR0 = 131;
INTCON.GIE = 1;
INTCON.PEIE = 1;
INTCON.TMR0IE = 1;
}
valew Tiago!! Eu estava carregando o tmr0 fora da rotina de interrupção. Agora tá rodando redondo aqui.
ExcluirOlá Thiago, muito bacana sua explicação sobre o TMR0 mas li as respostas que você deu aos outros colegas e não encontrei uma solução para mim. Estou tentnado implementar um temporizador com o PIC16F628 de pelo menos duas horas, isso acionado por um LDR numa determinada porta. Pois bem, a questão do LDR até posso resolver depois mas já li muitos materiais sobre a manipulação do TMR0 do PIC mas todos acabam falando em acionamento por um segundo de um led, etc. Assim, gostaria de alguma ajuda com esse cálculo para um período maior, caso possa fazê-lo. Obs.: uso CCS e minha pequena base de programação é C ANSI. Grande abraço e tudo de bom. Sandro
ResponderExcluir#include <16F628A.h>
Excluir#device adc=8
#FUSES NOWDT,XT
#use delay(clock=4000000)
int32 time=0;
#int_RTCC
void RTCC_isr(void) //1000us
{
time++;
if(time == 7200000)
{
output_toggle(pin_b0);
time = 0;
}
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
set_timer0(6);
set_tris_b(0x00);
time =0;
while (TRUE)
{
}
}
Calculo:
Excluir1us * 4 * (256 - 6) = 1000us
2horas = 120min = 7200 seg == 7200000ms
Salve Tiago!! Estudo completo, hein? (pelo menos com o setor #### eu devia me virar sozinho (rss..).
ExcluirValeu mesmo, seu algoritmo vou guardar prá sempre porque a explicação é perfeita e servirá de base para outros pequenos projetos de final de semana por aqui (ou de um ano inteiro, kkk). Grande abraço e tudo de bom. Sandro.
pq foi usada uma variavel time do tipo inteira de 32 bits? Poderia ser do timpo inteira de 8 bits?
ExcluirTiago, preciso de ajuda com o timer0, mas é para o pic12F675. Preciso fazer um temporizador que fique ligado por 168 horas seguidos, e após este tempo desligar. O programa é inicialmente simples, o problema está na precisão, pois como o tempo é longo, o acumulo de pequenos erros na temporização acaba atrapalhando o resultado final. Você pode me ajudar na questão de precisão desse temporizador ? Agradeço se me der uma ajuda.
ResponderExcluirNo seu caso poderia utilizar um cristal de 32768Hz.
ExcluirIrei fazer um post sobre este assunto!!
Até mais!!
Valeu Tiago. A resposta veio rápido vai me ajuda muito. Obrigado e parabéns pelo material disponível no blog.
ExcluirTiago Você conhece mesmo o pic e o mickroc.
ResponderExcluirvocê poderia me ajudar a sincronizar com a rede eletrica.
assim um pino fica gerando onda quadrada a 60Hz atraves de um temporizador.
uma chave fica aberta e conecta um pino contador um sinal externo que varia de 57Hz a 63Hz, quando isso acontece o pino que gera os 60Hz tem que ir de 60Hz suavemente para a frequencia que está entrando nesse pino contador, caso abra a chave o pino que gera o clock deve voltar suavemente para 60Hz, olha já quebrei a cabeça mas é complicado. eu programo com o CCS
Por favor, preciso fazer um temporizador com o PIC 18F4520, porém não estou conseguindo. Preciso selecionar no display LCD, por meio de um botão, a função TEMPO, que faz a contagem, em segundos, para o acionamento de um motor. Quando a função TEMPO é selecionada será necessário informar o tempo que o motor irá ser acionado. Por exemplo: Preciso que o motor entre em funcionamento após 5 segundos, assim eu selecionaria a função TEMPO no display LCD e incrementaria por meio de um botão, até aparecer o número 5, dessa forma após 5 segundos o motor seria acionado.
ResponderExcluirMuito obrigado
Thiago
Olá Thiago, gostei muito da sua explicação sobre o TMR0, uso o ccs e estou tentando fazer um temporizador com o PIC16F628a que fique um Led ligado por 6segundos e desligado por 2 horas por uma determinada porta, sempre assim com loop, mas não encontro nada sobre esse tipo de temporizador infinito por horas, apenas segundos preciso de ajuda com esse cálculo para um período maior, pode me ajudar? fico grato por sua ajuda e parabéns pelo blog.
ResponderExcluirOlá Thiago,
ResponderExcluirCara, estou com um projeto que que seria mais ou menos assim:
Tenho um dispositivo que faz um movimento e fica parado "x" segundos (regulado em um temporizador ). Após isso um segundo temporizador faz o mesmo durante "xx" segundos .
Esses dois movimentos desse dispositivo, gerariam "X" + "XX" segundos , que automaticamente me dariam "Z" quantidades por hora.
Ex: 1segundo + 2 segundos = 60 minutos / 3 segundos = "Z" quantidades por minuto * 60 minutos= 1200 por hora.
Não estou conseguindo resolver isso.
Se por possível me ajudar !!!
Abraço !
Olá Thiago,
ResponderExcluirCara, estou com um projeto com PIC 16f877a que seria mais ou menos assim:
Tenho um dispositivo que faz um movimento e fica parado "x" segundos (regulado em um temporizador ). Após isso um segundo temporizador faz o mesmo durante "xx" segundos .
Esses dois movimentos desse dispositivo, gerariam "X" + "XX" segundos , que automaticamente me dariam "Z" quantidades por hora.
Ex: 1segundo + 2 segundos = 60 minutos / 3 segundos = "Z" quantidades por minuto * 60 minutos= 1200 por hora.
Não estou conseguindo resolver isso.
Se por possível me ajudar !!!
Abraço !
Ola, Thiago
ResponderExcluirEstou com um projeto que vai ter varias rotinas no lcd, estou usando um pic 18F452, so que eu acho que ele nao vai suportar a memoria. o que vc me diz uso uma externa ou tem alguma rotina pra minizar a memoria.
Olá,Thiago.
ResponderExcluirMuito boa a sua explicação sobre os timers,mas preciso de sua ajuda.Preciso fazer um contador de pulsos que conte um determinado numero de pulsos que eu determinarei,por exemplo 10 pulso, sendo que isso só pode acontecer depois de acionado um botão,isto feito deverá acionar duas porta: uma com 200 ms e outra acionada direta.
Como saber o prescaler e como configurar para estourar a cada 1ms
ResponderExcluirOlá!
ResponderExcluirNão poderia passar por aqui sem deixar o meu agradecimento e os parabéns pelos responsáveis por esse blog, que foi uma ajuda incrível para minhas dúvidas. Infelizmente materiais assim ainda são escassos na internet.
Ótima Iniciativa, continuem!
Olá Thiago blz, preciso de uma pequena ajuda com botões, 16 botões que tem a seguinte função:
ResponderExcluircada botão seleciona 1 de cada 3 caracteres do alfabeto e imprime em um lcd 16x2, porem se crio condições de tempo ou por clicks para cada função de um botão o ciclo do while() faz com o lcd fique imprimindo varios dos caracteres e preenchendo todo o lcd sem parar.
exemplo:
Se botão 1 pressionado durante 500ms e solto imprime caracter "A" se 1000ms e solto imprime caracter "B"
isso por condição de tempo
por clicks seria se botão 1, um click caracter "A" e se dois carater "B"
Poderia me dizer se e possivel eu criar uma rotina em que se o botão pressionado durante um tempo,
ex: 1000ms ele fica selecionando os três caracteres e assim quando aparecer o caracter que quero solto o botão e imprime no lcd.
Estou usando o compilador mikroc e o pic16f877, segue 1 ex do código que estou usando para esta função.
Ja tentei de varias outras formas mas o lcd imprime sem parar, o objetivo e criar uma interface para entrada de senhas em um circuito para armar um alarme ou desarmar, o codigo para o alarme ja tenho
em mente mas a dificuldade e no menu, ums dos códigos que criei faz a função de selecionar por meio de condição de tempo um dos caracteres e imprimir no lcd mas não da para calcular o tempo certo que o botão deve ser pressionado imprimir o caractere escolhido, segue o código do mesmo no 2 ex.
Ex 1:
ResponderExcluir// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
bit oldstate; // Old state flag
char txt1[] = "A";
char txt2[] = "C";
char txt3[] = "D";
char txt4[] = "E";
char txt5[] = "F";
char txt6[] = "G";
char txt7[] = "H";
char txt8[] = "I";
char txt9[] = "J";
char txt10[] = "K";
char txt11[] = "L";
char txt12[] = "M";
char txt13[] = "N";
char txt14[] = "O";
char txt15[] = "P";
char txt16[] = "Q";
char txt17[] = "R";
char txt18[] = "S";
char txt19[] = "T";
char txt20[] = "U";
char txt21[] = "V";
char txt22[] = "W";
char txt23[] = "X";
char txt24[] = "Y";
char txt25[] = "Z";
char txt26[] = "0";
char txt27[] = "1";
char txt28[] = "2";
char txt29[] = "3";
char txt30[] = "4";
char txt31[] = "5";
char txt32[] = "7";
char txt33[] = "8";
char txt34[] = "9";
char txt35[] = "entre com senha";
char txt36[] = "senha correta";
char read [] = "RISEHANDS";
//------------------//
void main(){
ADCON1=0x0F; //Configura analógios
ADCON1=0x0F;
CMCON|=0x07; //Desliga comparadores
trisa=0;
trisb=0;
trisc=1;
trisd=1;
trise=0;
porta=0;
portb=0;
portc=0;
portd=0;
porte=0;
oldstate = 0;
Lcd_Init();
Lcd_out(1,1,txt35);
delay_ms(3000);
Lcd_Cmd(_LCD_BLINK_CURSOR_ON);
delay_ms(500);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_RETURN_HOME);
oldstate = 0;
while(1){
if (portd.RD0 == 1, // Detect logical one
delay_ms(500),
oldstate == 0){
Lcd_out_CP("A");
}
if (portd.RD0 == 1, // Detect logical one
delay_ms(1000),
oldstate == 0){
Lcd_out_CP("B");
}
Delay_ms(10);
}
}
Ex 2:
ResponderExcluirwhile(1){
if (portd.RD0 == (1, 0, 1)){
delay_ms(500); // Detect logical one
Lcd_out_CP("A");
}
if (portd.RD0 == (1, 0, 1)){
delay_ms(1000); // Detect logical one
Lcd_out_CP("B");
}
Delay_ms(10);
}
}
O circuito a seguir:
1 * 128 * (256 - 100) = 19968us = 20ms. como que o 19968 é igual a 20ms
ResponderExcluirNao tem como obter um tempo exatamente igual a 20ms. Único jeito é aproximando...
ExcluirBoa noite, teria como me ajudar nessa questão ?
ResponderExcluirExemplo: Quero fazer um led piscar permanecendo aceso durante um segundo e apagado durante um segundo. No meu sistema embarcado tenho cristal que gera um clock de 1Mhz. Meu timer é de 16 bits. Escolha um valor de pescaler e ache até quanto o timer deve contar para que eu possa criar uma rotina que o led possa picar da maneira que eu desejo.
Olá Thiago muito bom seu blog, é grande ajuda, parabéns pela iniciativa.
ResponderExcluirSe puder me ajudar?
Tenho um sensor de umidade (grove), e tenho que fazer uma programação em um PIC18F4520, que quando o solo estiver umido mande um sinal ao pic que o faça ligar uma bomba de água, quando o solo estiver em níveis normais fique parado e quando o solo estiver bem molhado desligue a bomba.
Desde já agradeço, e novamente parabéns pelo blog.
Tbm estava preciasndo, se tiver conseguido, manda.
ExcluirBoa tarde, será que me podiam ajudar nesta questão?
ResponderExcluirQual o valor com que se deve inicial o TIMER0 do pic18 para obter um overflow em 175ms. Suponha que utiliza um cristal de 20MHZ e um prescaler de 1/64.
a) 54688
b) 13672
c) 51863
d) Nenhuma das anteriores
Sei que a resposta certa é a "c", mas gostava de perceber como chegar ao valor.
Desde já, obrigado.
Boa tarde.
ExcluirComo o TIMER0 do PIC18F é de 16 bits entao vai contar até 65535 e estourar no proximo tick. Utlizando a formula lá no post, T = ciclo * prescaler * ( 65536 - valor inicial ), vamos isolar a incognita 'valor inicial', entao vai ficar assim: valor inicial = 65536 - ( T / ( ciclo * prescaler ) ). Jogando os valores, valor inicial = 65536 - ( 175000us / 0.2us * 64 ) = 51864.
Muito muito obrigado! Excelente blog, parabéns!
ExcluirObrigado.
ExcluirPra nao ficar preso as formulas, voce poderia pensar no seguinte: Dentro de um intervalo de tempo (T1), neste caso, 175ms, há varios subintervalos (T2), que é o tempo de cada tick, ou seja, ( ciclo * prescaler = 0.2 * 64 = 12,8us ), pra saber quantos T2 são necessarios, é so fazer T1 / T2 = 175000us / 12.8us = 13672 subitervalos. Agora e só subtrair 13762 de 65536, que vai dar 51864.
Mais uma vez, muito obrigado! Sem querer "abusar" nem sobrecarregar, apenas se tiver tempo e disponibilidade. Será que me podia dar umas luzes neste problema?
ExcluirImagine que ocupa o cargo de engenheiro de sistemas numa empresa que se
dedica ao desenvolvimento de hardware. Um cliente pretende desenvolver um sistema
para monitorização do nível de água existente num depósito, baseado num microcontrolador.
O sensor utilizado apresenta como saída um sinal analógico com tensões
que podem variar entre os 2 e 3V estando esta gama de tensões associada linearmente
à capacidade do depósito (i.e. 0 a 100%). Desenhe um diagrama de blocos
correspondente ao sistema que sugere implementar e descreva-o detalhadamente.
Quais os módulos existentes num microcontrolador que sugere utilizar? Que técnicas
de programação recomenda, e porquê? Justifique.
E se eu configurasse o timer0 com 8 bits?? como ficaria?
ExcluirOlá Thiago, sera que vc pode ajudar em uma questão?
ResponderExcluirEstou fazendo um TCC onde haverá um alarme por ldr no jardim pegando 4 pontos, e pontos de luz no jardim quando escurecer, isso usando o pic16F628, o alarme tem que tocar por 2min com intervalo de30 seg.
Parabéns pelo excelente material e obrigado por compartilhar esse conhecimento!
ResponderExcluirOlá,
ResponderExcluiré possivel gerar uma interrupçao por timer, passando 1 hora?
Olá Thiago, excelente consulta esse seu blog. Gostaria que por gentileza você me ajudasse com uma dica.
ResponderExcluirEstou querendo calcular o fator de potência da rede. Para isso é necessário os sinais analógicos de tensão e corrente. Entretanto para que eu possa amostrar o sinal eu devo fazer meus cálculos de forma discreta para que eu possa pegar cada pedaço do sinal analógico. Pois bem, para que eu possa determinar o time de amostragem do meu sinal discretizado no pic, você pela sua experiência acha melhor eu utilizar o timer0 ou simplesmente aplicar o delay? a frequencia de rede é 60Hz e o meu sinal amostrado será de 960Hz, ou seja, ele irá me informar uma amostra do sinal a cada (1/960) = 1.04 ms.. como eu poderia aplicar o timer0 nesse caso?
Não estou conseguindo fazer calculo de tempo:
ResponderExcluirestou usando cristal 4Mhz, Pic 16f628A, precisava de um tempo de 5 segundos
Bom dia, eu preciso controlar uma sinaleira simples com PIC PIC16F877A, utilizando o TIMER 0, fazendo o seguinte: sendo que o verde deverá permanecer aceso durante 3 segundos, o amarelo durante 1 segundo e o vermelho durante 3 segundos, lembrando que o processo se repetirá indefinidamente. Pode me ajudar?
ResponderExcluirExcelente blog.
ResponderExcluirUm microcontrolador PIC está utilizando um clock externo de 4 MHz. O temporizador TIMER0 foi configurado para um prescaler de 256. Qual o intervalo de interrupção do TIMER0?
ResponderExcluir0,256 milissegundos.
65,536 milissegundos.
16,384 milissegundos.
Impossível calcular.
1,024 milissegundos.
mas qual é o tempo da interrupcao??
ExcluirEstou achando 16,67 segundos e não tem nenhuma alternativa com esse valor !
ResponderExcluirPoderia me ajudar
Olá, eu li o post inteiro porem n vi uma solucao de como criar uma base de tempo usando o timer0 do CCS para que gere um sinal de 50hz na saída. Obs: O pic usado é o 18f4550 topado, ou seja clock do cpu em 48MHz. Por favor me ajudem!!
ResponderExcluirboa tarde , alguem pode me ajudar, tenho que montar um circuito com pic, com uma entrada de bot aonde acione os dois reles com tempo programavel por mim ,tipo um micro chave possa aumentar ou diminuir o tempo de atracado,sendo que o tempo de um rele fique o dobro do outro.EX: Isto é assim que presionar o botão BOT se colocar 10 minutos no tempo um rele ficara atracada por esse tempo e o outro automaticamente ficara atracado por 20 minutos ,ou tb que eu programe o tempo individual ( o mais facil)meu email marcosj_soares@hotmail.com, obrigado pela atenção marcos soares
ResponderExcluirOla! pessoal estou precisando de uma ajudinha ai com o tmr0 do pic16f877a
ResponderExcluirestou montando um projecto e preciso que uma variavel guarda o tempo porque irei usar mais tarde este tempo para calcular a energia e preciso mostrar o tempo contando no LCD...
Olá,
ResponderExcluirCopiei o código e adaptei para testar no MPLAB com PIC16F628A e o LED apenas acende e não apaga, não estou conseguindo entender o porque, na contagem ele respeita o tempo para acender, mas uma vez ligado não desliga mais. Alguma ideia do que pode ser?
Ola pessoal!! Preciso fazer um temporizador com timer0 que começe em 0hz e vá até 20000hz, como faço para controlar as interrupções para incrementar e decrementar essa frequência ? Qual o preescaler mais indicado para esse caso ?
ResponderExcluirSobre o temporizador de 0 a 20000 Hz que citei, quero acrescentar mais algumas informações para que alguém possa me ajudar, estou usando a linguagem ccs e o pic que estou utilizando é o 16f628A com um clock interno de 4MHZ para o timer0. Um dos problemas que estou tendo é que não consigo iniciar a frequência de 0HZ.
ResponderExcluirOlá, parabéns pelo blog!
ResponderExcluirEstou tendo um problema, estou usando o MPLAB linguagem C.
Quando eu coloco OPTION_REG ele gera um erro na compilação, comecei a incrementar o timer0 e no início deu esse erro:
*** Error 48 "codigo.c" Line 47(12,22): Expecting a (
*** Error 43 "codigo.c" Line 47(14,25): Expecting a declaration
*** Error 43 "codigo.c" Line 47(25,26): Expecting a declaration
Se alguém ou o moderador poder me ajudar eu agradeço.
Segue o código.
#include <16F877a.h> //Define o modelo do microcontrolador
// Fusíveis de configuração do microcontrolador
#FUSES NOWDT //Sem Watch dog, evitando reset
#FUSES BROWNOUT //Resetar quando detectar brownout (Quando a tensão cair abaixo do previsto no datasheet)
//#FUSES HS //Crystal de oscilação > QUE 4mhz
#FUSES XT //Crystal de oscilação de 4mhz
#FUSES PUT //Tempo de início do PIC
#FUSES NOPROTECT //Codigo sem proteção de leitura, software livre!
#FUSES NODEBUG //Verifica se tem erros bo código (desabilitado)
#FUSES NOLVP //No low voltage prgming (prog. baixa voltagem desabilitado), B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection (Sem travar o chip)
#use delay(clock=4000000) //Define o cristal utilizado
//***************************************** LCD *****************************************
//Definição de entradas e saídas
//Cada bit representa um pino físico de I/O
// 0 significa que o pino será uma saída
// 1 significa que o pino será uma entrada
#define trisa 0b11111111
#define trisb 0b00000000
// Estas são as definições dos pinos que o LCD utiliza.
// Definem quais pinos do PIC controlarão os pinos do LCD
#define lcd_enable pin_a1 // pino enable do LCD (E)
#define lcd_rs pin_a0 // pino rs (register select)do LCD (RS)
// (0) para comandos (1) para dados
//O pino RW vai no negativo.
#define lcd_db4 pin_b4 // pino de dados d4 do LCD
#define lcd_db5 pin_b5 // pino de dados d5 do LCD
#define lcd_db6 pin_b6 // pino de dados d6 do LCD
#define lcd_db7 pin_b7 // pino de dados d7 do LCD
#include //declaração da biblioteca do LCD
//***************************************** LCD *****************************************
//***************************************** TIMER0 *****************************************
OPTION_REG = 0b100000001; //Pag. 23 - Explicação em 11:34 link: https://www.youtube.com/watch?v=K81eMwKZYYw&t=938s
//Conversor: http://www.calculadoraonline.com.br/conversao-bases
//Em binário: 0b10000001 = 0x81
//Configura o prescale em 1:4
//***************************************** TIMER0 *****************************************
//Programa principal
void main(){
inicializa_lcd(); //Inicializa o LCD
while(1){
//delay_ms(10);
limpa_lcd(); //Limpa o display do LCD
output_high(pin_b3); //Liga o Led testando a saída do pino
caracter_inicio(1,1); //Define o caracter de inicio da escrita
printf(escreve_lcd,"TESTE LCD"); //Escreve no LCD
caracter_inicio(2,1); //Define o caracter de inicio da escrita
printf(escreve_lcd,"Linha 2"); //Escreve no LCD
//output_low(pin_b3); //Desliga o Led
//delay_ms(5000);
}
} //fecha void main
Best Online Training From India Instittue
ResponderExcluirAbinitio Online Training From India
Application Packaging Online Training From India
ORACLE Apps Technical Online Training From India
App-v Online Training From India
AWS Online Training From India
Azure Online Training From India
Business Analysis Online Training From India
Cognos Online Training From India
DataScience Online Training From India
Utilizando O Timer0 Do Pic - Microcontrolandos >>>>> Download Now
ResponderExcluir>>>>> Download Full
Utilizando O Timer0 Do Pic - Microcontrolandos >>>>> Download LINK
>>>>> Download Now
Utilizando O Timer0 Do Pic - Microcontrolandos >>>>> Download Full
>>>>> Download LINK
düzce
ResponderExcluirsakarya
tunceli
van
bayburt
NT4UX
0C38B
ResponderExcluirAğrı Parça Eşya Taşıma
Çorum Evden Eve Nakliyat
Bayburt Evden Eve Nakliyat
Tunceli Parça Eşya Taşıma
Batman Evden Eve Nakliyat
23A4C
ResponderExcluirSakarya Evden Eve Nakliyat
steroid cycles for sale
fat burner for sale
sustanon
Muş Evden Eve Nakliyat
Tekirdağ Fayans Ustası
masteron for sale
Binance Referans Kodu
order trenbolone enanthate
68B55
ResponderExcluirordu sohbet odaları
kırşehir görüntülü sohbet uygulamaları ücretsiz
antep en iyi rastgele görüntülü sohbet
ısparta canlı sohbet
çorum canli goruntulu sohbet siteleri
antep sesli sohbet siteler
mardin canli goruntulu sohbet siteleri
ığdır canlı sohbet
en iyi rastgele görüntülü sohbet