USART Interrupt

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, guys

I am trying to use USART interrupt. The idea is to send character through hyperTerminal then show the character on LCD.So far, I believe my sending and receiving function is working fine. And the function writing LCD is fine. So, I guess must be somewhere wrong with the interrupt.
I used WinAVR toolchain.

Thank you all for your time!

Here is part of the code

#include 
#include 
#include 

unsigned char r_char;

void USART_send(unsigned char Tx)
{
    while(!(USARTF0_STATUS&=0x20))
        _delay_us(1);

        USARTF0_DATA = Tx;
}

unsigned char cmd_Rx(void)
{
    unsigned char RxChar = NULL;
    while(!(USARTF0_STATUS&=0x80))
    _delay_us(1);
    RxChar = USARTF0_DATA;

    return RxChar;
}

/* Reception Complete Interrupt */
ISR(USARTF0_RXC_vect) 
{
    r_char = cmd_Rx();
    Wrt_Data(r_char); // Write to LCD
}

void main(void)
{
	 	 SPI_Init(); // SPI initialization
	 _delay_us(5);
	 cli();
	 _delay_us(5);
	 USART_init();

	 _delay_ms(5);
	 sei();   /* enable interrupts */
	 _delay_us(5);
	 PMIC_CTRL |= 0x01; // enable interrupts

	 PORTF_DIRSET |= 0x80; // set PF7 as output
	 //PORTF_OUTSET |= 0x80;
	 SREG |= 0x80;
	 _delay_us(1);
 	 Port_Init();

 	 _delay_us(1);
	 PORTA_OUT = 0x00;
	 PORTC_OUT = 0x00;
	 _delay_us(1);

	 // LCD initialiazion
	 // Clear Display
	 Wrt_Instr(0x01); //Clear Display, set DDRAM address to "00H" into AC

	 _delay_ms(2);
         ................
         ................
         ................
	
	 USART_send('A');

	 while(1)
	 {
	 }
}

/*
* Following is edited on May 3rd
*/
Hi, Guys
Right now, I am sure that the USART interrupt is never been triggered. So, someone please check my USART initialization code, is there any problem. If the initialization is right, what else could cause USART interrupt don't get triggered?
I basically follow the procedure from the menual. I truned off global interrupt before USART initialization.
One more question, is it necessary to set I/O register INTCTRL and INT0MASK too?
Thanks a lot!!!

/*
 * USART.c
 *
 *  Created on: 2011-4-18
 *      Author: Administrator
 *      USART
 *      PORTF USARTF0 PF1~PF3
 *      PF1: XCK0
 *      PF2: RXD0
 *      PF3: TXD0
 */

#include 
#include 
#include 
#include 

char cmd[20];
char temp;
unsigned char r_char;

void USART_init(void)
{
	PORTF_OUTSET |= 0x08; // set PF3(TxD) output high
	PORTF_OUTCLR |= 0x02; // set PF2(RxD), PF1(XCK) output low
	PORTF_DIRSET |= 0x0A; // set PF3(TxD) and PF1(XCK) as output
    PORTF_DIRCLR = 0x04; // set PF2(RxD) as input
    //PORTF_INTCTRL = 0x01; // set interrupt0 low level
    //PORTF_INT0MASK = 0x04; // Set PF3, PF2 as source for port interrupt0
	USARTF0_BAUDCTRLA = 0x0C; // BSEL = 12
	USARTF0_BAUDCTRLB = 0x00; // BSCALE = 0;
	USARTF0_CTRLC = 0x03; // Asynchronous mode; No Parity; 1 StopBit; 8bit data
	USARTF0_CTRLB = 0x18; // Enable Receiver and Transmitter
    /*
     * CTRLA - USART Control Register A
     * bit  7                                                  0
     * -----------------------------------------------------------
     * | - | - | RXCINTLVL[1:0] | TXCINTLVL[1:0] | DREINTLVL[1:0] |
     * -----------------------------------------------------------
     */
    USARTF0_CTRLA = 0x15; // Enable Receive Complete, TransmitComplete, RegisterEmpty Interrupt(Low Level)
}
Last Edited: Wed. May 4, 2011 - 11:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

So, I guess must be somewhere wrong with the interrupt

Guess WHAT must be wrong? You forgot to say.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Change:
while(!(USARTF0_STATUS &= 0x20))
to
while(!(USARTF0_STATUS & 0x20));
and
while(!(USARTF0_STATUS &= 0x80))
to
while(!(USARTF0_STATUS & 0x80));

Edit: the RXCIF will be cleared by reading USARTF0_DATA in interrupt routine. Try to define a variable and check it when waiting for data.

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

So, I guess must be somewhere wrong with the interrupt

Guess WHAT must be wrong? You forgot to say.

I think might be this part.

ISR(USARTF0_RXC_vect)
{
r_char = cmd_Rx();
Wrt_Data(r_char); // Write to LCD
}

But I can't see where is the problem. I can write character on LCD through HyperTerminal. I can receive character from HyperTerminal if I keep checking RXCIF bit.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

electronic.designer wrote:
Change:
while(!(USARTF0_STATUS &= 0x20))
to
while(!(USARTF0_STATUS & 0x20));
and
while(!(USARTF0_STATUS &= 0x80))
to
while(!(USARTF0_STATUS & 0x80));

Edit: the RXCIF will be cleared by reading USARTF0_DATA in interrupt routine. Try to define a variable and check it when waiting for data.

Thank you for your response. I've made the change, still the same thing. And I got another question from your response. The USART interrupt will be triggered every time I try to send any character to MCU right? Then why I still need to define a variable and check it when waiting for data?
Thanks a lot!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

still the same thing.

But you STILL haven't said what that is?!? If you don't say what's wrong how do you expect anyone to help?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

still the same thing.

But you STILL haven't said what that is?!? If you don't say what's wrong how do you expect anyone to help?

I said in my first post. The idea is to send a character from Hyperterminal then show the received character on LCD, but it doesn't show any character on LCD when I entered a character. I can send a character from hyperterminal to LCD by checking RXCIF bit, without using USART interrupt. So, I think the send function is fine, and I suspect it's someting wrong with interrupt code. But what's exactly the problem, I can't tell, otherwise if I have any clue I will keep trying instead of bothering other people.

I hope I made myself clear this time. If not, please be specific what you don't understand, and I will try to explain my question. Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I also read from an old thread that there is interrupt problem with earilier Xmega chip. Has anyone encountered these kind of porblems?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe you got this figured out already, but the xmega interrupt controller is double enabled. You need to set global interrupts and also enable the level you are using. Since you are setting the uart interrupt to level 0, you need to also enable that level like this.

PMIC.CTRL |= LOLVLEN_bm;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

GordonFreeman wrote:
Maybe you got this figured out already, but the xmega interrupt controller is double enabled. You need to set global interrupts and also enable the level you are using. Since you are setting the uart interrupt to level 0, you need to also enable that level like this.

PMIC.CTRL |= LOLVLEN_bm;

Thank you for your response!
I did enable PMIC control register. Sorry, I should have my main function re editted.
I think it should work the same way as yours.

PMIC_CTRL |= 0x01; // enable interrupts
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes that is the same command as mine. Do you have it working yet or are there still problems?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

GordonFreeman wrote:
Yes that is the same command as mine. Do you have it working yet or are there still problems?

No, still dont work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is a code example for sending a character to Hyper terminal and display the received character on lcd:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=104565

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

electronic.designer wrote:
Here is a code example for sending a character to Hyper terminal and display the received character on lcd:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=104565

Thank you, I will study your code. :D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pls post your USART_init(); function code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

rsensan wrote:
pls post your USART_init(); function code.

Who are you referring to?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

rsensan wrote:
pls post your USART_init(); function code.

/*
 * USART.c
 *
 *  Created on: 2011-4-18
 *      Author: Administrator
 *      USART
 *      PORTF USARTF0 PF1~PF3
 *      PF1: XCK0
 *      PF2: RXD0
 *      PF3: TXD0
 */

#include 
#include 
#include 
#include 

char cmd[20];
char temp;
unsigned char r_char;

void USART_init(void)
{
   PORTF_OUTSET |= 0x08; // set PF3(TxD) output high
   PORTF_OUTCLR |= 0x02; // set PF2(RxD), PF1(XCK) output low
   PORTF_DIRSET |= 0x0A; // set PF3(TxD) and PF1(XCK) as output
    PORTF_DIRCLR = 0x04; // set PF2(RxD) as input
    //PORTF_INTCTRL = 0x01; // set interrupt0 low level
    //PORTF_INT0MASK = 0x04; // Set PF3, PF2 as source for port interrupt0
   USARTF0_BAUDCTRLA = 0x0C; // BSEL = 12
   USARTF0_BAUDCTRLB = 0x00; // BSCALE = 0;
   USARTF0_CTRLC = 0x03; // Asynchronous mode; No Parity; 1 StopBit; 8bit data
   USARTF0_CTRLB = 0x18; // Enable Receiver and Transmitter
    /*
     * CTRLA - USART Control Register A
     * bit  7                                                  0
     * -----------------------------------------------------------
     * | - | - | RXCINTLVL[1:0] | TXCINTLVL[1:0] | DREINTLVL[1:0] |
     * -----------------------------------------------------------
     */
    USARTF0_CTRLA = 0x15; // Enable Receive Complete, TransmitComplete, RegisterEmpty Interrupt(Low Level)
} 

:D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

...so did you manage to resolve your problem? I've been struggling with the same for the last day or so... :/