Code: Select all
unit irq_usart;
{ @jpc 2009 mp PRO for AVR v 1.30
cpu : ATMEGA1280
provides 4 simple interrupt driven uart-receivers with simple circular buffers
}
procedure init_4_irq_uarts;
function getchar(channel : byte):byte;
function datareceived(channel: byte) : boolean;
implementation
const rx_bufsize = 80;
brate1 = 57600;
brate2 = 57600;
brate3 = 57600;
brate4 = 57600;
type uart_type = record
rxbuffer : array[rx_bufsize] of byte;
head,
tail,
parity_error,
frame_error,
overrun_error : byte;
end;
var uarts : array[4] of uart_type;
procedure uart1_isr; org IVT_ADDR_USART0__RX;
var err,dummy : byte;
begin
with uarts[0] do
begin
err := UCSR0A and %00011100;
if err = 0 then
begin
rxbuffer[head] := UDR0;
if inc(head) = rx_bufsize then head := 0;
end else
begin
dummy := UDR0; // flush the byte
if err and %00010000 then inc(frame_error);
if err and %00001000 then inc(overrun_error);
if err and %00000100 then inc(parity_error);
end;
end;
end;
procedure uart2_isr; org IVT_ADDR_USART1__RX;
var err,dummy : byte;
begin
with uarts[1] do
begin
err := UCSR1A and %00011100;
if err = 0 then
begin
rxbuffer[head] := UDR1;
if inc(head) = rx_bufsize then head := 0;
end else
begin
dummy := UDR1; // flush the byte
if err and %00010000 then inc(frame_error);
if err and %00001000 then inc(overrun_error);
if err and %00000100 then inc(parity_error);
end;
end;
end;
procedure uart3_isr; org IVT_ADDR_USART2__RX;
var err,dummy : byte;
begin
with uarts[2] do
begin
err := UCSR2A and %00011100;
if err = 0 then
begin
rxbuffer[head] := UDR2;
if inc(head) = rx_bufsize then head := 0;
end else
begin
dummy := UDR2; // flush the byte
if err and %00010000 then inc(frame_error);
if err and %00001000 then inc(overrun_error);
if err and %00000100 then inc(parity_error);
end;
end;
end;
procedure uart4_isr; org IVT_ADDR_USART3__RX ;
var err,dummy : byte;
begin
with uarts[3] do
begin
err := UCSR3A and %00011100;
if err = 0 then
begin
rxbuffer[head] := UDR3;
if inc(head) = rx_bufsize then head := 0;
end else
begin
dummy := UDR3; // flush the byte
if err and %00010000 then inc(frame_error);
if err and %00001000 then inc(overrun_error);
if err and %00000100 then inc(parity_error);
end;
end;
end;
function datareceived(channel:byte) : boolean;
begin
with uarts[channel] do
begin
if head <> tail then datareceived := true else datareceived := false;
end;
end;
function getchar(channel : byte):byte;
var tmp : byte;
begin
with uarts[channel] do
begin
if(head <> tail) then
begin
result := rxbuffer[tail];
if inc(tail) = rx_bufsize then tail := 0;
end else getchar := 0;
end;
end;
procedure init_4_irq_uarts;
begin
// initialize uart Interrupt's and buffers
memset(word(@uarts),0,sizeof(uarts)); // clear buffers
UART1_Init(brate1);
UART2_Init(brate2);
UART3_Init(brate3);
UART4_Init(brate4);
UCSR0b := %10011000; // enable RX Interrupt , enable rx and tx uart
UCSR1b := %10011000;
UCSR2b := %10011000;
UCSR3b := %10011000;
end;
end.
Code: Select all
program irq_4uart_test;
{ demo 4 channel Uart ISR for BigAVR with ATMEGA1280
@jpc 2009, mikroPascal PRO for AVR V1.30
this little demo outputs ALL data received by 4 uart-channels to UART1
connect terminal program on RS232-port , jumper the 4 uart_RX lines together on the headers
any character send to the RSS232 will be received simultanously by the 4 ISR's
}
var channel : byte;
procedure init_all;
begin
init_4_irq_uarts;
SREG.7 := 1; // global interrupt enable
uart1_write_text('Demo 4 channel Uart');
uart1_write(10);
uart1_write(13);
end;
begin
init_all;
while true do
begin
for channel :=0 to 3 do
begin
if datareceived(channel) = true then
begin
uart1_write(getchar(channel));
end;
end;
end;
end.