This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Trying to transmit with interrupt in XC164CS

Hi everybody,
I am learning to program with MCUs and now i have got the SK-XC164 board.I am trying to transmit via ASC0 a message. This message has 6 equal bytes and I must do it with transmit interrupt. Has anyone a simple program to practise??. The message I would like to see the message through Hyperterminal on PC. Thanks to everyone.

Parents Reply Children
  • John,
    I don't know the 164 so I cannot quickly comment about your code. however, please check the following:
    * if your TX interrupt bit enabled?
    * if so, if its priority is 0, no interrupt will be generated.
    * make sure it has a unique group/level setting.

  • also note that Dave generates a report indicating problems related to the peripherals after code generation. it includes warnings about interrupts that will not be invoked!

  • Ok you have a problem to set the interrupt levels.

    Anyway I stripped down some previous code to show a bare minimum if this helps you.

    #include <xc164.h>
    #include <intrins.h>
    
    unsigned int  cnt;
    unsigned int  txSendCount;
    unsigned char *txTailptr;
    unsigned char txBuf[] = {"Hello"};
    
    /*****************************************************/
    void main(void) {
      ASC0_CON =  0x0011;
      ASC0_BG  =  0x0011;
    
      ALTSEL0P3 |= 0x0400;       /* select alternate output function   */
      _bfld_(P3,0x0C00,0x0400);  /* P3.10 (Tx) and P3.11 (Rx) are used */
      _bfld_(DP3,0x0C00,0x0400); /* P3.10 (Tx) and P3.11 (Rx) are used */
    
      ASC0_TXFCON = 0x0100;  /* transmit FIFO is disabled  */
    
      ASC0_TBIC  = 0x0079;
    
      txSendCount = 0;
      txTailptr = &txBuf[0];
    
      ASC0_CON |= 0x8000; /* enable baud rate generator */
    
      PSW_IEN = 1;        /* globally enable interrupts */
    
      txSendCount = 5;    /* set the number of bytes to send */
      ASC0_TBIC_IR = 1;   /* send message */
    
      for(;;) {     /* run forever! */
        cnt++;
      };
    }
    
    /*****************************************************/
    void ASC0_TxBufferIsr (void) interrupt (0x47U) {
    
      if (txSendCount > 0) {
        txSendCount--;
        ASC0_TBUF = *txTailptr++;
      }
    }
    

  • Hello,
    the Dave gives me the following information and I am not sure if this is the mistake:

    ASC0_TIC       =  0x0079;
    
      ///  Use PEC channel 1 for ASC0 Tx INT:
      ///  - normal interrupt
      ///  - pointers are not modified
      ///  - transfer a word
      ///  - service End of PEC interrrupt by a EOP interrupt node is disabled
      ///  - channel link mode is disabled
    

    Do you think wether it may be the problem?

  • Then how in your code did you have...

      ASC0_TIC =  0x0080;
    

  • Ups,this can be the problem. I'm going to try.

  • I've just tested and It doesn't work :(

  • Thanks Chris,
    I have just tested your program example and It only sends me 1 "Hello" and not 5.(txSendCount = 5; /* set the number of bytes to send */). What can I do?

  • Hello Chris. You are right. The example works well.
    Thank you very mutch. :D

  • Hello Chris,
    I would like to get more information about these instructions: ASC0_TBIC_IR, ASC0_TBIC and the rest of code relationed with ASC0.
    I want to know where do you get them from. I saw the XC164CS complet datasheet and I haven't seen them.
    Thanks

  • Hi John,

    You can find the information in the peripheral users manual. Look in the ASC section under interrupts.

    TBIR is activated when data is moved from TBUF to the transmit shift register.

    TIR is activated before the last bit of an asynchronous frame is transmitted, or after the last bit of a synchronous frame has been transmitted

    So if you are sending a stream of data generally you would use the TBIR as this could keep the transmission to appear to be contiguous. It allows the register to be loaded while still sending a value.

    You generally would use the TIR interrupt if you need to perform software handshaking.

    Hope that helps.
    -Chris

  • Hi John,

    Sorry, I didn't read your last post correctly.

    ASC0_TBIC_IR is the interrupt flag in the special function register (SFR) ASC0_TBIC that would get set when the transmit buffer is able to accept another word.

    It is automatically cleared when you vector its interrupt handler. Alternatively you can clear it by software.

    Look at both the system and peripheral users manuals for information about interrupts.

  • I have understood the reply and it's been important.
    One more thing. Could you give me a program that is similar to transmission interrupt, but in this case using reveive interrupt?
    Thank you very much, Chris.

  • I have tried sending a "A" character via HyperTerminal to the XC164CS and when it receives, it blinks a LED. I use this code, but it doesn't run correctly.

    #include <AR166.h>
    #include <XC164.h>
    
    unsigned char   mi_sbuf;
    
    void main(void)
    {
         ASC0_CON       =  0x0011;      // load ASC0 control register
         ASC0_BG        =  0x0011;      // load ASC0 baud rate time reload register
      ALTSEL0P3 |= 0x0400;       /* select alternate output function   */
      _bfld_(P3,0x0C00,0x0400);  /* P3.10 (Tx) and P3.11 (Rx) are used */
      _bfld_(DP3,0x0C00,0x0400); /* P3.10 (Tx) and P3.11 (Rx) are used */
      ASC0_TXFCON = 0x0100;  /* transmit FIFO is disabled  */  ///
      ASC0_TBIC      =  0x0079;
      ASC0_RIC       =  0x007D;
    
      ASC0_CON      |=  0x8000;      // enable baud rate generator
      while (1);
    }
    void ASC0_viRx(void) interrupt ASC0_RINT using RB_LEVEL15
    {
            while (ASC0_RIC_IR);
            mi_sbuf = ASC0_RBUF;
    
            if (mi_sbuf == 'A')
            {
                 if (MY_LED == 0)MY_LED = 1;
                     else MY_LED=0;
                     os_dly_wait (50);
                 if (MY_LED == 0)MY_LED = 1;
                     else MY_LED=0;
                     os_dly_wait (50);
            }
    }