SCI TX Interrupt Problem

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

SCI TX Interrupt Problem

3,221 次查看
longliveboy
Contributor I

Hi everybody;

 

I'm in trouble with tx interrupt.

although i wrote codes below it's not working

 

 

__interrupt void isrVscitx(void){  if(SCIS1_TC){// wait to Transmission Complete flag   txCount++;   if(txCount>10){        //to transmit 10 bytes   txCount=0;  txON=0;        //TX hardware enable pin low  SCIC2_TCIE=0;  //TX interrupt disable } else{  SCID = sendBuffer[rxCount]; }  }}

 

 The problem is:

  Even TXInterrupt is off it branches to interrupt again and again.

  If i use debugger step by step code enters txCount control block but if i set a breakpotint to

txCount=0;

line it never enters to breakpoint.

 

It's so meaningles.


标签 (1)
0 项奖励
回复
8 回复数

1,053 次查看
erooll
Contributor II

Hi.
First of all, if you want to send the first 10 bytes in your array, your code starts on element 1 instead of element 0 of array.
Use Transmition complete like event generator of interrupt doesn't take advantage of SCI module, because we could use the TDRE flag in order to queue new data on SCI module.
So you could use two posibles flags as interruption generators
1.Transmission Complete flag
2. Transmit Data register empty flag

Example to first option:
SCIC2_TCIE = 1; //Call this to start transmission

__interrupt void isrVscitx(void)
{
   if(SCIS1_TC)
   {     
      SCID = sendBuffer[txCount];
      if(++txCount>=10)
      {
         SCIC2_TCIE = 0;   //Disable interrupt
     txCount=0;
     //txON=0;        //TX hardware enable pin low        
      }     
   }
}

Example to second option:

SCIC2_TIE = 1; //Call this to start transmission

__interrupt void isrVscitx(void)
{
   if(SCIS1_TDRE)
   {     
      SCID = sendBuffer[txCount];
      if(++txCount>=10)
      {
         SCIC2_TIE = 0;   //Disable interrupt
     txCount=0;
     txON=0;        //TX hardware enable pin low        
      }     
   }
}

The above examples assumes that you starts correctly the SCI module.

Greetings @420

0 项奖励
回复

1,053 次查看
peg
Senior Contributor IV

Hello,

 

The first example here also suffers from the fact that it needs to be "kick started" by loading the SCID from outside the interrupt, otherwise TC will never be set to generate the interrupt.

 

IMHO, it is misleading to satisfy the flag resetting requirements by doing an "if" test of the generating flag inside the ISR. To a reader it looks like the if needs to be there and looks like you could tack an "else" condition on the end (which you can't). dummy= SCIS1 even uncommented, will cause the ignorant reader to find out why, rather than lull them into a false reason.

 

0 项奖励
回复

1,053 次查看
bigmac
Specialist III

Hello,

 

I presume that the first character is sent from outside the ISR.  Then each time the ISR is entered the TC flag will always be clear since a new character is sent each time.  I also notice that your are using the index value rxcount, rather than the perhaps expected txcount, and that you do not increment this index value. So it is possibly the same character sent each time.

 

If you require to limit each transmission to ten characters, you will need to keep track of this within the else part of your if statement, and then use the TC flag to determine only when the interrupt should be disabled.

 

Regards,

Mac

 

0 项奖励
回复

1,053 次查看
longliveboy
Contributor I

Bigmac;

 

rxCount is just a misspelling. In the project it is txCount.

Also i tried every kind of controls to limit transmit count by 10 but code never falls to coltrol block in run time

 

0 项奖励
回复

1,053 次查看
bigmac
Specialist III

Hello,

 

The following untested code snippet is what I was alluding to in my previous post.

 

volatile byte sendBuffer[11];
volatile byte txCount;

void SCI_send_string( void)
{
   txON = 1;                     // Enable Tx hardware
   txCount = 0;
   while (!SCIS1_TDRE);
   SCID = sendBuffer[txCount++]; // Send first character
   SCIC2_TIE = 1;                // Enable TDRE interrupts
}


__interrupt void isrVscitx(void)
{
   if (SCIS1_TC) {       // Test for transmission complete  
      SCIC2_TCIE = 0;    // Disable TC interrupts
      txON = 0;          // Disable Tx hardware
   }
   else {
      if (txCount < 10)    
         SCID = sendBuffer[txCount++];
      else {
         SCIC2_TIE = 0;   // Disable TDRE interrupts
         SCIC2_TCIE = 1;  // Enable TC interrupts

      }
   }
}

 

Regards,

Mac

0 项奖励
回复

1,053 次查看
peg
Senior Contributor IV

Hello longliveboy,

 

You have not told us what flag you have setup to trigger the tx interrupt!

 

I'm guessing you have set it up for TDRE. Now when the interrupt is triggered TC is not set yet so nothing is done and you have failed to properly clear the TDRE flag.

 

Perhaps a review of the datasheet is in order for you....

 

Perhaps you could also indicate what you are trying to do, because it is not clear from your supplied code.

Message Edited by peg on 2009-07-29 04:53 PM
0 项奖励
回复

1,053 次查看
longliveboy
Contributor I

Peg;

 

I have tried both Transmit Interrupt(TDRE flag) and Transmit Complete Interrupt(TC flag) separately but result is same.

First tx interrupt is triggered in main function by "SCIC_TCIE=1;"

 

I read datasheet carefully but i dont know what is the point that i miss?

 

I'm trying to implement MODBUS protocol

i recieve some requests from server and start to control frame compability for modbus. If all frame is ok i start to transmit requested datas but tx interrupt never stops.

Message Edited by longliveboy on 2009-07-29 08:19 AM
0 项奖励
回复

1,053 次查看
peg
Senior Contributor IV

Hi again,

 

Try setting the interrupt to trigger on TDRE and remove the TC test from within the ISR. Put in a read of SCIS1 at begining of ISR to allow the flag to clear. That should get you started.

 

0 项奖励
回复