Página 1 de 2

delay 100 microsegundos

MensagemEnviado: 15 Set 2008 15:05
por valdotc
Pessoal,
Estou precisando de uma rotina de delay de 100 microsegundos.
Estou precisando para ter um que me da mais precisão para um passo do motor de passo.
Por exemplo se eu quiser um tempo de 1.2 milisegundos, uso o valor de 12X100 microsendos = 1.2milisegundos.
Estou programando em C mas estou usando uma estrura que o SDCC permite usar e mesclando o assembler e C, conforme abaixo:
//*****DELAY*****//
void delayms(char c) // Rotina de Delay com tempo de minimo de 1ms
{
c;
_asm
mov r0,dpl
0100$:
mov R2,#8
0200$:
mov R1,#55
0300$:
djnz R1,0300$
djnz R2,0200$
djnz R0,0100$
ret
_endasm;
}

Se alguém tiver uma dica agradeço,
Valdotc

MensagemEnviado: 15 Set 2008 16:27
por helton
Faz um timer de 100 us...(timer 1 auto reload 16 bits )...muito melhor que qualquer delay...

MensagemEnviado: 15 Set 2008 16:43
por valdotc
Helton,

Desculpe, mas eu entendo muito pouco de programação.
Não sei como fazer um timer ( timer 1 auto reload 16 bits ).
tem algum documento que eu poderia pesquisar???

Obrigado,

Valdotc

MensagemEnviado: 15 Set 2008 18:03
por Djalma Toledo Rodrigues
Valdotc Melhor documento é o Datasheet do uC
Timer são contadores internos do uC , como você insere Assembler no C creio que não será difícil.

Mas você não informou qual uC esta a usar.

MensagemEnviado: 15 Set 2008 20:45
por Maurício
Salve, valdotc.

Bem-vindo!

Qual a frequência do cristal que vc está usando?
Tem um timer sobrando aí?

[]'s

MensagemEnviado: 16 Set 2008 08:26
por valdotc
Salve Pessoal,

Estou usando o uC AT89C52 e o Cristal é 11.0592Mhz e tenho timer sobrando.

Obrigado,

Valdo

MensagemEnviado: 16 Set 2008 12:00
por Meson
Valdotc eu uso este recurso quando to com todos os timers ocupados e tem dado certo, acho que com vc pode dar tbm, pois é muito simples.
A instrução nop com o cristal q vc esta usando gasta 1us para ser executada, como vc tem que esperar cem ciclos deste pode ser que de uma diferença,mas ajuste até dar certo, diminui o número de ciclos da função!

Este é o jeito rápido e utiliza o principio de Namarra! :D

Caso queira algo muito preciso, vai ter que usar o timer mesmo.

Espero ter te ajudado.

Código: Selecionar todos
while(f<=100)
 { f++; _asm             // inicio da declaracao em assembly
         nop              // no operation
       _endasm;          // fim da declaracao em assembly
 }

MensagemEnviado: 16 Set 2008 12:51
por valdotc
Meson obrigado,


Acho que serve, não preciso muita precisão, é apenas para definir o passo de um motor de passo.
Vou testar .

Obrigado a todos.

Valdo

MensagemEnviado: 16 Set 2008 16:32
por chrdcv
Saudações!

Cuidado com a implementação de rotinas assembly declaradas no corpo do código em C. Em alguns compiladores, há alguns efeitos indesejáveis; principalmente caso haja manipulação do stack.

Sugiro que utilze uma macro, ao invés de função, pois devido ao compromisso de tempo e sendo o mesmo utilizado como base para a geração de outros, uma macro faria a substituição "em linha" e não sacrificaria muito em relação ao compromisso de tempo.

typedef u8_t unsigned char;

#define sysucNOP() { _asm nop _endasm }
#define sysucDelay10Us(xUs) { volatile u8_t _xUsDcnt; \
_xUsDcnt = (u8_t)(xUs); \
while(--_xUsDcnt) { \
sysucNOP(); } \
}

MensagemEnviado: 19 Set 2008 13:32
por valdotc
Salve galera<

Testei a rotina que alguém me passou mas que não estou encontrando a mensagem.
Ajustei os tempos e esta funcionando, só estou com um problema ainda . O valor digitado acima de 250, parece que que fica travado no valor de 250, parece que acima deste valor ele se perde.
Medi os tempos do osciloscópio e fecha muito bem até 250.
Por exemplo se eu digitar 200 o resultado= 200 x 100 us=20 ms.
Peciso chegar até >1000 x 100 us = 0,1 ms.
Estou achando que pode ser a declaração da variavel char .
Não sei se consegui passar a minha dúvida, até eu estou achando confuso.Abaixo segue a rotina que estou tentando trabalhar.
Mais uma coisa, estou usando float para a variavies que são usadas junto, por exemplo: o tempo_passo_motor é float.
delay_100micros(tempo_passo_motor);

[void delay_100micros(unsigned char micro_segundos) //Função de geração de tempo - base 1us
{
// A variável micro_segundos é a entrada do parâmetro de quantos microsegundos serão gerados

unsigned int carga_inicial=(65535-500); // Variável de carga inicial do Timer

while(micro_segundos)
{
TL0=carga_inicial; // Carregamento do parte baixa do valor inicial de contagem
TH0=carga_inicial>>8; // Carregamento do parte baixa do valor inicial de contagem
TR0=1; // Ligação do Timer
while(!TF0); // Verificação do fim da contagem a partir do estouro do flag, necessário apenas quando não usamos a interrupção do Timer
TR0=0; // Desligao o timer
TF0=0; // Zera o flag
micro_segundos--; // Decrementa a variável
}

} ]

Valeu galera,
Valdo[/code][/quote]

MensagemEnviado: 19 Set 2008 13:43
por Djalma Toledo Rodrigues
Você deve estar em 8 bits, logo valor máx = 255.

MensagemEnviado: 19 Set 2008 14:36
por valdotc
Djalma,

O que devo fazer??Altero o THO??


Obrigado,

Valdo

MensagemEnviado: 20 Set 2008 01:21
por Djalma Toledo Rodrigues
Se o Timer0 estiver no Modozero você terá TH 8 bits (Div 256D) e TL 5 bits (Div 32D)

Atenção ao valor de recarga.

Se modo1: TH 8 bits TL 8 bits

MensagemEnviado: 20 Set 2008 11:56
por tcpipchip
Se teu processador MCS51 nao for DALLAS e estiver a 12Mhz,
NOP leva 1us para executar...

Entao, faz

98 NOPS (sem while, jnb, for, etc,etc,tc) e RET no final...

98 NOPS = 98us + RET (2us) = 100us...

NOP
NOP
NOP
.
.
.
RETURN

T+

TPCIPCHIP

MensagemEnviado: 22 Set 2008 07:41
por helton
dica de tempo:
http://www.asm51.eng.br/phpbb/viewtopic.php?t=6115

[code]
#include "at89c52.h"

#define DEF_TH0 0xDB
#define DEF_TL0 0xFF

/*
deltaT = 12 / ( 11.0592 * 10^6 )

T0(TH0/TL0) = 65535 - (IntTempo / deltaT);
Para um IntTempo = 10ms
T0 = 0xDBFF
*/

void init_hardware(void)
{
SCON = 0x50;
TMOD = 0x21;
TCON = 0x11;
}

void init_timer( void )
{
TR0 = 0;
TH0 = DEF_TH0;
TL0 = DEF_TL0;
TR0 = 1;
ET0 = 1;
}

void timer0_isr( void ) interrupt 1
{
TR0 = 0; /* timer 0 stop timer */

/* update time counter 0 (th0, tl0 ) */
TH0 = DEF_TH0;
TL0 = DEF_TL0;

TR0 = 1; /* timer 0 run */
/* Decrease Variables and Setting Flags */
}

void main( void )
{
init_hardware();
init_timer();

while(1)
{
}
}
[\code]