Combining streams and interupts on 8+1 USART

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

I've got my USART1 and 0 set up and transmitting. I'm usings streaming to send strings to USART 0 and have streaming setup to receive strings on Usart1. (I did this because I can't see how to differentiate which port I am printf'ing to if I set streaming up fully on both)

This is what I've written so far - I'm not going to include all 10 pages of code, only the important parts.

volatile unsigned char Receivechar0; //char for USART0 Intterupt to write to. 
volatile unsigned char Receivechar1; //char for USART1 Intterupt to write to. 







/*---------------------------------------------------
Setup Rs232 serial port
USART0
---------------------------------------------------*/
void RS232_Init(void)
{

   //PRR |= (1<<PRUSART0);
   /* Set baud rate */
   UBRR0L = (uint8_t) (F_CPU / (16UL * USART0_BAUD)) - 1;
   UBRR0H = (uint8_t) ((F_CPU / (16UL * USART0_BAUD)) - 1) >>8;


   /* Enable receiver and transmitter */
   UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0);
   /* Set frame format: 8data, 2stop bit */
   UCSR0C = (1<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01)|(0<<UMSEL00)|(0<<UMSEL01);
}

/*---------------------------------------------------
USART0 Transmit
---------------------------------------------------*/
void RS232_Transmit_Char( unsigned char data )
{
	
/* Wait for empty transmit buffer */

	while (!(UCSR0A&(1<<UDRE0)))
	{
	}
/* Put data into buffer, sends the data */
	UDR0 = data;
		
}

/*---------------------------------------------------
USART0 Receive
---------------------------------------------------*/
unsigned char RS232_Receive_Char(void)
{
   /* Wait for data to be received */
   while ( !(UCSR0A & (1<<RXC0)) )

   /* Get and return received data from buffer */
   return UDR0;
}

/*---------------------------------------------------
USART0 REceive interrupt
---------------------------------------------------*/


ISR(USART0_RX_vect) //RS232 Receive interrupt
{
	
	
	//Store data to volatile Receivechar
	Receivechar0 =UDR0;
	
}

static int cput(char c, FILE *f)
{
	loop_until_bit_is_set(UCSR0A, UDRE0);
	UDR0 = c;
	return 0;
}
/*--------------------------------------
Receive strings from usart 1
--------------------------------------*/
static int cget(FILE *f)
{
	loop_until_bit_is_set(UCSR1A, RXC1);
	return UDR1;
}



/*---------------------------------------------------
Setup LIN serial port
USART1
---------------------------------------------------*/
void LINBUS_Init (void)
{
   //PRR |= (1<<PRUSART0);
   /* Set baud rate */
   UBRR1L = (uint8_t) (F_CPU / (16UL * USART1_BAUD)) - 1;
   UBRR1H = (uint8_t) ((F_CPU / (16UL * USART1_BAUD)) - 1) >>8;


   // Enable receiver and transmitter 
   //	Enable interrupt
   UCSR1B |= (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1);
  // Set frame format: 8+1data, 2stop bit 
  UCSR1C = (1<<USBS1)|(1<<UCSZ12)|(1<<UCSZ10)|(1<<UCSZ11)|(0<<UMSEL10)|(0<<UMSEL11);
}

/*---------------------------------------------------
LIN Transmit
---------------------------------------------------*/
void LIN_Transmit( unsigned char data, int startflag )
{
   /* Wait for empty transmit buffer */
   while ( !( UCSR1A & (1<<UDRE1)));

   /* Copy 9th bit to TXB8 */
   UCSR1B &= ~(1<<TXB81); //Clear startbit
   if ( startflag == 1 )
   {
	UCSR1B |= (1<<TXB81); //Set start flag
   }	
   /* Put data into buffer, sends the data */
   UDR1 = data;

}

/*--------------------------------------------------
LIN Recieve
--------------------------------------------------*/
unsigned char LIN_Receive(void)
{


   unsigned char resh, resl;
   /* Wait for data to be received */
   while ( !(UCSR1A & (1<<RXC1)) );
   // Get 9th bit, then data 
   // from buffer 

  resh = UCSR1B;
  resl = UDR1;
  /* Filter the 9th bit, then return */
  resh = (resh >> 1) & 0x01;
  return ((resh << 8) | resl);

}

ISR(USART1_RX_vect) //LIN Receive interrupt
{
	unsigned char resh;
	
	//Store data to volatile Receivechar
	resh = UCSR1B;
	/*if( resh >0)
	{
		scanf(Receivechar1);
		
	}
	
	else */
	
	Receivechar1 = UDR1;
	
	_FDEV_EOF;
	
}

How do I set it to receive strings on intterupt. I can get it to receive a char. If I use scanf(), it will freeze my program until it gets an input and if one of the MPPT's I'm interfacing with over the LINbus breaks, I'll have to reboot the whole system, so can someone please point me in the right direction?

Thanks

edit: indented code

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

The uart hardware sets the receive interrupt when it gets a char. You have one char time to service the interrupt. Reading the char from the data register resets the interrupt flag, so that part is automatic. You just need to store the received char in a big array. Keep two array indexes. Add chars to the array at the inputindex, and in the main program pull them out from the outputindex. If you reset the index back to the beginning when it gets to the end, you can call this simple old array like everyone used in fortran and basic a 'circular buffer' and impress your computer science buddies.

Imagecraft compiler user