AT90CAN32 16MHz uart at 500Kbps?

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

I got a bee in my bonnet to build a can gateway by connecting two of our can bds with the ttl level uart1 rx and tx crosscoupled. I can see the rx coming in, but it doesn't look like its interrupting. I figger 500kbits is 16us per byte, and my interrupt handler is about 40 cycles, so it should be working? Does the rx int needs a falling edge on the start bit? Cuz that aint there straight from the tx pin is it? I'll really be disappointed if someone tells me their gcc hex file runs just great at 16MHz and 500 Kbps.

 

Dont let the can mess things up. Just 2 16MHz avrs with the ttl level rx and tx cross coupled, and baud divisor of 1 (500Kbps). It should work, and I cant see why it isnt working. Thanks.

 

 

 

Imagecraft compiler user

Last Edited: Tue. Aug 16, 2016 - 03:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The usart will interrupt then it has rxd a full byte, and yes the start bit is a low from a high idle.

Try a bit slower speed just to see if it works, say 4 instead of 1,  also try adding another stop bit to the transmitter and see what happens.

 

Jim

 

edit: with 10 bits/byte, at 500kbs, you would have 20us / byte, so you have lots of time! q:-)

 

 

 

 

 

 

Last Edited: Thu. Aug 18, 2016 - 05:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
I can see the rx coming in, but it doesn't look like its interrupting.

Does it receive anything ?

Interrups enabled ?

RXEN, RXCIE enabled ?

 

bobgardner wrote:

I figger 500kbits is 16us per byte, and my interrupt handler is about 40 cycles, so it should be working?

Show us the code.

If this is a typical FIFO in C, then it should be a little longer. (not as long as Arduino, which stops transmitting at ~250kbps, but longer than this 43 cycle rx handler)

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

Here is some code that runs on ATmega329PB Xmini.  The driving board was an Mega 2560 clone.  Just sending ascii. But shows receive interrupt.

 

/*
 * usart1pb.c
 *
 * Created: 8/19/2016 09:17:58
 * Author : J.Stampfl
 */ 

#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include <string.h>

static volatile int pos;
static volatile char buf0[80], buf1[80], outbuf1[80],outbuf0[80];
static volatile char* Bp0;
static volatile char* Bp1;
static volatile char* Bp2;
static volatile int rxflag1;
int main ( void )
{

	int i;
	rxflag1 = 0;

	pos = 0;

	for (i = 0; i < 80; i++) {
		buf0[i] = (char) 0;
		buf1[i] = (char) 0;
	}
	Bp0 = (char *) buf0;	//set the buffer pointers
	Bp1 = (char *) buf1;
	Bp2 = (char *) buf0;

	UCSR1B = (1 << RXEN1 );   // Turn on the rx for USART1
	UCSR0B = (1 << TXEN0 );   // Turn on the tx for USART0

	UBRR1H = 0;                              //Load upper 8-bits of baud rate to zero
	UBRR1L = 1;								// 500 baud 
	
	UBRR0H = 0;                               //Load upper 8-bits of baud rate to zero
	UBRR0L = 0;								 // 1M baud
	
	UCSR1B |= (1 << RXCIE1 ); // Enable the USART1 Recieve Complete interrupt ( USART_RXC )
	sei ();                                   // Enable the Global Interrupt Enable flag so that interrupts can be processed
	rxflag1 = 0;
	_delay_ms(200);

	for (;;) // Loop forever
	{
		//rxflag1 is set when buffer is full or '\n' is received
		//just send 1st character to USART0
		if (rxflag1 == 1)
		{
			rxflag1 = 0;
			UDR0 = Bp1[0];
		}
	}
}
ISR ( USART1_RX_vect )
{
	// next 4 lines are for debugging, send each character to USART0
	/*
	char ReceivedByte ;
	ReceivedByte = UDR1 ; // Fetch the received byte value into the variable "ReceivedByte "
	UDR0 = ReceivedByte ; // Echo the received byte to the computer
	Bp0[pos] = ReceivedByte;
	*/
	// if you uncomment the preceding 4 lines, comment out the following line.
	Bp0[pos] = UDR1;      //into the buffer
	
	if (Bp0[pos] == '\n') 
	{
							//dealing with ascii line should end with '\n'
		Bp0[pos+1] = 0;	 
		pos = 0;			// reset buffer location
		Bp2 = Bp1;			// swap buffers, by changing pointers.
		Bp1 = Bp0;
		Bp0 = Bp2;
		rxflag1 = 1;
	} else
	{
		pos++;
		
							
		if ( pos == 78 )	//buffer full
		{
			Bp0[pos+1] = 0;	//dealing with ascii end with "\n0"
			Bp0 [pos] = '\n';
			pos = 0;
			Bp2 = Bp1;
			Bp1 = Bp0;
			Bp0 = Bp2;
			rxflag1 = 1;
		}
	}
}