查看: 1688|回复: 0
打印 上一主题 下一主题

已经在UC3C2512上能用的串口,中端方式+环形缓冲区

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-18 22:01:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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);







回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表