delay 100 microsegundos

Software e Hardware para linha x51

Moderadores: 51, guest2003, Renie, gpenga

delay 100 microsegundos

Mensagempor valdotc » 15 Set 2008 15:05

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
valdotc
Bit
 
Mensagens: 8
Registrado em: 02 Jul 2008 13:33

Mensagempor helton » 15 Set 2008 16:27

Faz um timer de 100 us...(timer 1 auto reload 16 bits )...muito melhor que qualquer delay...
Helton Marques
"Priorize as Prioridades"
helton
Byte
 
Mensagens: 146
Registrado em: 16 Out 2006 09:18
Localização: São José-SC

Mensagempor valdotc » 15 Set 2008 16:43

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
valdotc
Bit
 
Mensagens: 8
Registrado em: 02 Jul 2008 13:33

Mensagempor Djalma Toledo Rodrigues » 15 Set 2008 18:03

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.
Editado pela última vez por Djalma Toledo Rodrigues em 16 Set 2008 01:21, em um total de 1 vez.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor Maurício » 15 Set 2008 20:45

Salve, valdotc.

Bem-vindo!

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

[]'s
"Não leve a vida tão à sério, afinal, nenhum de nós sairá vivo, dela!"
Avatar do usuário
Maurício
Word
 
Mensagens: 678
Registrado em: 14 Out 2006 17:23
Localização: São Paulo - SP

Mensagempor valdotc » 16 Set 2008 08:26

Salve Pessoal,

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

Obrigado,

Valdo
valdotc
Bit
 
Mensagens: 8
Registrado em: 02 Jul 2008 13:33

Mensagempor Meson » 16 Set 2008 12:00

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
 }
Meson
Nibble
 
Mensagens: 54
Registrado em: 13 Out 2006 08:31

Mensagempor valdotc » 16 Set 2008 12:51

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
valdotc
Bit
 
Mensagens: 8
Registrado em: 02 Jul 2008 13:33

Mensagempor chrdcv » 16 Set 2008 16:32

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(); } \
}
Avatar do usuário
chrdcv
Dword
 
Mensagens: 1580
Registrado em: 13 Out 2006 14:13

Mensagempor valdotc » 19 Set 2008 13:32

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]
valdotc
Bit
 
Mensagens: 8
Registrado em: 02 Jul 2008 13:33

Mensagempor Djalma Toledo Rodrigues » 19 Set 2008 13:43

Você deve estar em 8 bits, logo valor máx = 255.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor valdotc » 19 Set 2008 14:36

Djalma,

O que devo fazer??Altero o THO??


Obrigado,

Valdo
valdotc
Bit
 
Mensagens: 8
Registrado em: 02 Jul 2008 13:33

Mensagempor Djalma Toledo Rodrigues » 20 Set 2008 01:21

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
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor tcpipchip » 20 Set 2008 11:56

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
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor helton » 22 Set 2008 07:41

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]
Helton Marques
"Priorize as Prioridades"
helton
Byte
 
Mensagens: 146
Registrado em: 16 Out 2006 09:18
Localização: São José-SC

Próximo

Voltar para 8051

Quem está online

Usuários navegando neste fórum: Bing [Bot] e 1 visitante

x