• AT91SAM7SE应用 UART 数据块的发送方式


    最近一直在调试代码,在短短的时间内产生了大量的代码,还没有来得及总结。

    现在就总结一下用 UART 发送数据块的方式,为什么采用数据块发送呢?

    一、块数据发送的方式可以提高发送效率;

    二、在需要发送一个数据帧的格式时,数据块的发送更实用。

    这里采用的是中断的方式,因此,缓冲区是必须的,笔者为这个通信方式设计了一个环形缓冲区,

    可以检测空信号,但不检测满信号。

    缓冲区的代码如下:

    View Code
     1 #define BUFF_SIZE 16000
     2 
     3 typedef struct
     4 {
     5     char data[BUFF_SIZE];
     6     volatile int read_pt, write_pt;
     7 } FIFO;
     8 
     9 
    10 //求队列的长度
    11 int fifo_len(FIFO *p_fifo)
    12 {
    13     return p_fifo->write_pt - p_fifo->read_pt;
    14 }
    15 
    16 void fifo_init(FIFO *p_fifo)
    17 {
    18     p_fifo->read_pt = 0;
    19     p_fifo->write_pt = 0;
    20     memset(p_fifo->data, 0, BUFF_SIZE);
    21 }
    22 
    23 //判断队列是否为空
    24 int fifo_empty(FIFO *p_fifo)
    25 {
    26     return (p_fifo->write_pt == p_fifo->read_pt);
    27 }
    28 
    29 //元素入队列
    30 int fifo_push(FIFO *p_fifo, char e)
    31 {
    32     p_fifo->data[p_fifo->write_pt] = e;
    33     p_fifo->write_pt++;
    34     if (p_fifo->write_pt == BUFF_SIZE)
    35     {
    36         p_fifo->write_pt = 0;
    37     }
    38     return 1;
    39 }

    UART初始化程序:

    View Code
     1 /******************************************************************************
     2  * Function Name       : Usart_init
     3  * Object              : USART initialization
     4  * Input Parameters    : none
     5  * Output Parameters   : TRUE
     6  ******************************************************************************/
     7 void uart_init(void)
     8 //* Begin
     9 {
    10 
    11     COM0 = AT91C_BASE_US0;
    12 
    13     //* Define RXD and TXD as peripheral
    14     //AT91F_US0_CfgPIO();
    15     AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,  // PIO controller base address
    16     ((unsigned int)AT91C_PA5_RXD0) | ((unsigned int)AT91C_PA6_TXD0) | ((unsigned int)AT91C_PA7_RTS0) | ((unsigned int)AT91C_PA8_CTS0), 0);
    17 
    18     // First, enable the clock of the PIOB
    19     AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_US0);
    20 
    21     // Usart Configure
    22     //AT91F_US_Configure(COM0, MCK, AT91C_US_ASYNC_MODE, USART_BAUD_RATE, 0);
    23     AT91F_US_Configure(COM0, MCK, AT91C_US_ASYNC_MODE, 115200, 0);
    24 
    25     // Enable usart
    26     COM0->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
    27 
    28     //* Set the PDC Interrupt mode
    29     BlockMode = false;
    30 
    31     AT91F_US_EnableIt(COM0, AT91C_US_RXRDY);
    32 
    33     //* open Usart 1 interrupt
    34     AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_US0, USART_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, Usart_c_irq_handler);
    35     AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_US0);
    36 
    37     fifo_init(p_uart_buffer);
    38 
    39 }

    例化一个串口缓冲区,全局变量:

    FIFO uart_buffer;
    FIFO *p_uart_buffer = &uart_buffer;
    

    数据块发送程序:

    View Code
     1 static int first_send_flag = 0;
     2 void uart_send_buffer(FIFO *p, char *data, int n)
     3 {
     4     int i;
     5     BlockSize = n;
     6 
     7     for (i = 0; i < n; i++)
     8     {
     9         fifo_push(p, data[i]);
    10     }
    11     if (first_send_flag == 0)
    12     {
    13         first_send_flag = 1;
    14 
    15         //* clean all param
    16         AT91F_US_DisableIt(COM0, AT91C_US_ENDTX | AT91C_US_TXBUFE);
    17         COM0->US_TCR = 0;
    18         COM0->US_TNCR = 0;
    19         BlockMode = (char)true;
    20 
    21         //* Start PDC
    22         //* ---- Set the first Block
    23         COM0->US_TPR = (unsigned int) &(p->data[p->read_pt]);
    24         COM0->US_TCR = n;
    25         p_uart_buffer->read_pt = (p_uart_buffer->read_pt + BlockSize) % BUFF_SIZE;
    26         AT91F_US_EnableIt(COM0, AT91C_US_TXBUFE);
    27 
    28     }
    29     else
    30     {
    31         AT91F_US_EnableIt(COM0, AT91C_US_TXBUFE);
    32     }
    33 
    34 }

    当发送完一个数据块(8字节)后,会进入中断,中断处理函数如下:

    View Code
     1 __irq void Usart_c_irq_handler(void)
     2 {
     3     unsigned int status;
     4     char rx_dat;
     5     //* get Usart status register
     6     status = COM0->US_CSR;
     7     // check if interrupt is present and available
     8     if ((status &AT91C_US_TXBUFE) &(COM0->US_IMR &AT91C_US_TXBUFE))
     9     {
    10         //AT91F_US_DisableIt(COM0, AT91C_US_TXBUFE);
    11         //p_uart_buffer->read_pt = (p_uart_buffer->read_pt + BlockSize ) % BUFF_SIZE;
    12         if (p_uart_buffer->read_pt == p_uart_buffer->write_pt)
    13         {
    14             AT91F_US_DisableIt(COM0, AT91C_US_TXBUFE);
    15             send_buffer_done = 1;
    16         }
    17         else
    18         {
    19             COM0->US_TPR = (unsigned int) &(p_uart_buffer->data[p_uart_buffer->read_pt]);
    20             COM0->US_TCR = BlockSize;
    21             p_uart_buffer->read_pt = (p_uart_buffer->read_pt + BlockSize) % BUFF_SIZE;
    22             AT91F_US_EnableIt(COM0, AT91C_US_TXBUFE);
    23         }
    24     }
    25 
    26     //* Reset the satus bit
    27     COM0->US_CR = AT91C_US_RSTSTA;
    28     AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
    29 }
  • 相关阅读:
    翻译:Razor剖析之第4部分:Razor页面
    学习第二十二天
    jQuery:选择器和事件
    学习第二十天@简单json+上传文件+Ado存储过程
    统计指定时间段内的周未(非周未)天数
    c#动态创建内存模型(笔记)
    cmd命令 任务计划 详解
    BAT教程:第四节(批处理中的变量)
    103个Windows XP运行命令
    BAT教程 :第二节(for命令详解 )
  • 原文地址:https://www.cnblogs.com/xiangtailiang/p/2693950.html
Copyright © 2020-2023  润新知