Boas,

com a interrupção do timer2 estou chamando a função  tx_trame() e  nessa funçao necessitava de usar um delay de 10ms mas nao estou conseguindo ate ja usei __asm__("nop\n\t")  

quando activo o digitalWrite(etx, LOW); queria fazer antes uma pausa de 10ms

**************************************************************************************************

unsigned int toggle = 0; //used to keep the state of the LED
unsigned int count = 0; //used to keep count of how many interrupts were fired

//Timer2 Overflow Interrupt Vector, called every 1ms
ISR(TIMER2_OVF_vect)
{
count++; //Increments the interrupt counter


if(count > 499) // 500ms
{
toggle = !toggle; //toggles the LED state

tx_trame(trame);
count = 0; //Resets the interrupt counter

}

digitalWrite(13,toggle); //LED

TCNT2 = 130; //Reset Timer to 130 out of 255
TIFR2 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup(void)
{

 Serial.begin(19200);
 pinMode(etx, OUTPUT);
 pinMode(13,OUTPUT);
 Serial.println("DEBUG ok ok ");

  //Setup Timer2 to fire every 1ms
  TCCR2B = 0x00; //Disbale Timer2 while we set it up
  TCNT2 = 130; //Reset Timer Count to 130 out of 255
  TIFR2 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
  TIMSK2 = 0x01; //Timer2 INT Reg: Timer2 Overflow Interrupt Enable
  TCCR2A = 0x00; //Timer2 Control Reg A: Wave Gen Mode normal
  TCCR2B = 0x05; //Timer2 Control Reg B: Timer Prescaler set to 128
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop()
{
  // tx_trame(trame);
  // delay(500);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void tx_trame (byte *data)
{
  byte i =0;
  byte checksum =0;
  static unsigned long ii=0;

   //delay(10);
    __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); //delay
   digitalWrite(etx, HIGH); // escreve  MAX485

     Serial.write(0xF4); 
     Serial.write(0x4F); 

         for (i=0; i<13; i++)
           {
             Serial.write(data[i]);
             checksum ^= trame[i];
           }

  Serial.write(checksum);

// delay(10);  // problema com este delay

/*
for (ii=0; ii<2999999; ii++)
{
__asm__("nop\n\t"); //delay

}
*/

   digitalWrite(etx, LOW);

}

Exibições: 636

Responder esta

Respostas a este tópico

Evite fazer delay em interrupção.. As interrupções devem ser o mais rápido possível. Senão vc está dentro da interrupção e ela pode ser chamada novamente. Como existe um bit que indica se já está em uma interrupção ela não "reentra", mas não fica bom..

Evite também chamar funções dentro de interrupções. Elas consomem mta pilha e isso é critico.

A solução seria vc usar a interrupção só pra setar um bit qualquer, um flag. No programa principal vc fica testando esse bit e aih sim executa toda a função necessária.

Boas,

o meu problema e que esse código serve para gerir uma carta de entradas/saída via bus rs485, e tenho que enviar todos os 500ms uma trama a carta para que funcione bem ... no max todos 800ms se não a carta reseta e deixa de comandar todas as saídas ...

Como posso resolver o problema ...

Pois sem o delay de 10ms não consigo comunicar ...

E quero usar a interrupção pois tenho que tratar toda a informação para gerir o programa 

Cpts

Eh... Não ta facil, então.

Vc vai ter que usar criatividade...

Por ex:

E se vc criar uma interrupção de tempo com um intervalo pouco maior que um byte transmitido da serial, e usar essa interrupção para medir tempos e enviar bytes pela serial???

Ficaria algo assim:

Vc cria um buffer de transmissão com quantos bytes puder. por ex 200.

Cria um byte para apontar para onde vc deve ler no buffer e outro para onde vc deve escrever.

No lugar de transmitir de forma convencional para a serial vc usa essa rotina.

Ela acumula mto rapidamente os bytes a transmitir no buffer, mas a interrupção de timer é que efetivamente faz a transmissão.

Vc poderia verificar se existem bytes que vc não normalmente e adotar como delay.

Por ex o caracter 254 poderia ser um delay equivalente a 200 caracteres. Quando ele for encontrado na string em vez de vc transmitir vc dispara um contator que fará a interrupção de timer voltar sem fazer nada por 200 vezes.

Deu pra entender a ideia ????

Parece complicado, mas temo que seja isso ou algo como isso sua resposta... Senão ou vc vai ter que fazer isso no programa principal ou não consegue pq se vc ficar demorando dentro da rotina de interrupção outras não acontecem...

Boas,

resumindo e concluindo ...... não percebi nada ...

Cpts

Paulo

Pois é... Não conheço jeito mais fácil.

Alguem conhece ???

Na verdade o que acontece é que em alguns protocolos a pausa é como um caracter... 

Minha proposta seria a criação do caracter pausa.

Aih vc teria que substituir a rotina de escrita na serial por outra que verifica se é esse caracter, Se for dispara uma pausa, senão simplesmente transmite.

Um fator complicador é que vc está querendo escrever na serial pela interrupção. Para poder fazer isso sugeri usar a interrupção de timer e um buffer (array de caracteres) para acumular a mensagem.

Se vc tentar mandar por ex 2 caracteres pela serial o primeiro vai imediatamente mas o segundo espera o primeiro completar a transmissão. Isso é ruim.

Com o buffer vc escreveria tudo nele e outra interrupção faria a leitura do buffer e efetiva transmissão... Um caracter  de cada vez..

Piorou ?????????

Boas,

Poderia dar um bocado de código ... se não esta difícil perceber ...

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço