myrs232.h
/*****************************************************************************
*
* \brief RS232 operation head file.
*
* USART3
*
******************************************************************************/
#ifndef _MYRS232_H_
#define _MYRS232_H_
#define MYRS232_RX_BUFFER_SIZE 128
// Receiver buffer
extern char myrs232_rx_buffer[MYRS232_RX_BUFFER_SIZE];
//extern unsigned char myrs232_rx_wr_index,myrs232_rx_rd_index;
extern unsigned char myrs232_rx_counter;
// This flag is set on Receiver buffer overflow
extern unsigned char myrs232_rx_buffer_overflow;
#define MYRS232_TX_BUFFER_SIZE 128
// Transmitter buffer
extern char myrs232_tx_buffer[MYRS232_TX_BUFFER_SIZE];
//extern unsigned char myrs232_tx_wr_index,myrs232_tx_rd_index,myrs232_tx_counter;
extern char myrs232_getchar(void);
extern void myrs232_putchar(char);
extern void myrs232_putstr(char *);
extern void myrs232_init(void);
#endif
// end of file
rs232.c
/*****************************************************************************
*
* \file
*
* \brief RS232 fuctions
*
* Receiving a byte in RX interrupt and push it into RX FIFO circular buffer
* buffer size is 128 bytes
*
*
* Transmit a byte directly if THR is empty otherwise push it into TX FIFO circular buffer and transmit it in TX interrupt
* buffer size is 128 bytes
*
* Copyright
*
*
******************************************************************************/
#include "compiler.h"
#include "myboard.h"
#include "usart.h"
#include "myrs232.h"
#include "gpio.h"
// Receiver buffer
char myrs232_rx_buffer[MYRS232_RX_BUFFER_SIZE];
unsigned char myrs232_rx_wr_index=0,myrs232_rx_rd_index=0,myrs232_rx_counter=0;
// This flag is set on Receiver buffer overflow
unsigned char myrs232_rx_buffer_overflow=0;
// Receive a character from RS232
char myrs232_getchar(void)
{
char data;
while (myrs232_rx_counter==0);
data=myrs232_rx_buffer[myrs232_rx_rd_index++];
if (myrs232_rx_rd_index == MYRS232_RX_BUFFER_SIZE) myrs232_rx_rd_index=0;
Disable_global_interrupt();
--myrs232_rx_counter;
Enable_global_interrupt();
return data;
}
char myrs232_tx_buffer[MYRS232_TX_BUFFER_SIZE];
unsigned char myrs232_tx_wr_index=0,myrs232_tx_rd_index=0,myrs232_tx_counter=0;
// Write a character to the RS232 Transmitter buffer
void myrs232_putchar(char c)
{
while (myrs232_tx_counter == MYRS232_TX_BUFFER_SIZE);
Disable_global_interrupt();
if (myrs232_tx_counter || (usart_tx_ready(RS232_USART)==0))
{
myrs232_tx_buffer[myrs232_tx_wr_index++]=c;
if (myrs232_tx_wr_index == MYRS232_TX_BUFFER_SIZE) myrs232_tx_wr_index=0;
++myrs232_tx_counter;
}
else
{
RS232_USART->thr = c;
RS232_USART->ier = AVR32_USART_IER_TXRDY_MASK; //Enable Tx IRQ
}
Enable_global_interrupt();
}
// Write a string by myrs232_putchar
void myrs232_putstr(char *str)
{
char *c;
c=str;
for(;*c!=NULL;)
{
myrs232_putchar(*c++);
}
}
// MYRS232 interrupt service routine
__attribute__((__interrupt__)) static void myrs232_irq(void)
{
if (RS232_USART->csr & AVR32_USART_CSR_RXRDY_MASK) // RX interrupt
{
if ((RS232_USART->csr & (AVR32_USART_CSR_OVRE_MASK | AVR32_USART_CSR_FRAME_MASK)) == 0)
{ // No overrun and frame error
myrs232_rx_buffer[myrs232_rx_wr_index++]= (char)(RS232_USART->rhr);
if (myrs232_rx_wr_index == MYRS232_RX_BUFFER_SIZE) myrs232_rx_wr_index=0;
if (++myrs232_rx_counter == MYRS232_RX_BUFFER_SIZE)
{
myrs232_rx_counter=0;
myrs232_rx_buffer_overflow++;
}
}
else
{ // RX error
usart_reset_status(RS232_USART);
}
}
else
{ // TX interrupt
if (myrs232_tx_counter) // still have data to TX
{
--myrs232_tx_counter;
RS232_USART->thr = myrs232_tx_buffer[myrs232_tx_rd_index++]; // TX a byte in buffer
if (myrs232_tx_rd_index == MYRS232_TX_BUFFER_SIZE) myrs232_tx_rd_index=0; // buffer index roll back
}
else
{ // Buffer is empty
RS232_USART->idr = AVR32_USART_IDR_TXRDY_MASK;
}
}
}
// myrs232 init
void myrs232_init()
{
static const gpio_map_t USART_GPIO_MAP =
{
{RS232_USART_RX_PIN, RS232_USART_RX_FUNCTION},
{RS232_USART_TX_PIN, RS232_USART_TX_FUNCTION}
};
// USART options.
static const usart_options_t USART_OPTIONS =
{
.baudrate = 57600,
.charlength = 8,
.paritytype = USART_NO_PARITY,
.stopbits = USART_1_STOPBIT,
.channelmode = USART_NORMAL_CHMODE,
};
// Assign GPIO pins
gpio_enable_module(USART_GPIO_MAP, sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0]));
// Initialize the USART in RS232 mode.
usart_init_rs232(RS232_USART, &USART_OPTIONS, RS232_TARGET_PBACLK_FREQ_HZ);
// Enable USART Rx interrupt.
RS232_USART->ier = AVR32_USART_IER_RXRDY_MASK;
// Register the USART interrupt handler to the interrupt controller.
// myrs232_irq is the interrupt handler to register.
// RS232_IRQ is the IRQ of the interrupt handler to register.
// RS232_IRQ_PRIORITY is the interrupt priority level to assign to the group of this IRQ.
// void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_lev);
INTC_register_interrupt(&myrs232_irq, RS232_IRQ, RS232_IRQ_PRIORITY);
}
// end of file
使用
读取
if(myrs232_rx_counter)
{
c=myrs232_getchar();
....
}
发送
myrs232_putchar('c');
myrs232_putstr("Hello world");
myrs232_putstr(string_in_ram);
|
|
|
|